Maker.io main logo

microbit Games-Controlling Movement on the LED Matrix

2022-03-10 | By Kitronik Maker

License: See Original Project

Courtesy of Kitronik

Guide by Kitronik Maker

Do you have an urge to write some microbit games but don't know how to start, ‎maybe we can help? Learning how to code some basic gaming functions could be ‎all you need to overcome coders block. Today we are going to take it back to ‎basics and learn a couple of key concepts. Processing user input and also taking ‎control of the LED matrix, both required knowledge if you want to create engaging ‎games.‎

create_1

Although we referred to Today's topics as basics, they can become quite tricky if ‎your game is quite complex. We will illustrate three ways of processing user input ‎and also three ways of moving a LED around the matrix. ‎

You Will Need:‎

You Will Learn:‎

  • Processing user input on the microbit
  • How to process user input from an external device
  • Controlling movement on the LED matrix
  • That there is always more than one way to get the desired result

microbit Games - Controlling Movement on the ‎LED Matrix:‎

We've got four code examples to go through, starting with the most ‎difficult/unwieldy first. The first two make use of the Input buttons of the microbit, ‎the third utilises an external analogue device and the fourth makes use of ‎the :GAME Controller for BBC micro:bit. All of the examples are coded using the ‎Microsoft MakeCode editor and we chose to use blocks. The four sections are;

‎• ‎1 - Using the 'LED blocks' in the MakeCode editor to light up an LED, then ‎move it with button presses. Jump

• ‎2 - Use the MakeCode 'Game blocks' to create a sprite on the screen, then ‎move it with button presses. Jump

• ‎3 - Use the 'Map block' to gather user input from a joystick via the microbit ‎gpio pins. Jump

• ‎4 - Using a dedicated gaming platform such as the :GAME Controller. Jump‎

‎‎1 - Take the Scenic Route:‎

route1_2

Disclaimer: Firstly, don't be put off by this method, there are easier and more ‎efficient ones to follow!‎‎ ‎

What Does the Code Do:‎

The code accepts input from the user via the microbits A and B buttons and also ‎when the microbit is shaken. The lit LED is given a starting position and the user ‎input takes over from there. A moves the LED left, B moves the LED ‎right, A+B moves the LED up and shake brings it to the bottom of the ‎column. Additionally, there is code that ensures the lit LED can't disappear off the ‎edge of the LED matrix. ‎

How Does the Code Work:‎

There are five distinct chunks of code, four that handle each type of user input and ‎one that sets the starting position for the LED. The code relies heavily on the use ‎of variables, in this case, X-Pos and Y-Pos. The contents of the variables are ‎updated by user input and the results are plotted to the screen in real time. Let's ‎take a closer look. ‎

The On Start Block:‎

start_2

The above image shows how the LED matrix is arranged in terms of x and y and ‎also where our starting LED is plotted. In the variables menu, we create two ‎variables; X-Pos and Y-Pos. We use these throughout the program to keep track of ‎the LEDs position. In this block, we just need to input a starting point and then plot ‎it to screen. The 'plot' block can be found in the LED menu and the 'set' blocks and ‎the X-Pos/Y-Pos lozenges can be found in the 'Variables' menu. Now we have an ‎LED lit up we need to figure out how to move it.‎

The on Button Press Input Blocks:‎

button_3

The code above allows for three different types of button press; A button pressed, ‎B button pressed, and A and B pressed together. You will notice that the code for ‎each is almost identical as they all move the LED one place; left, right, and up ‎respectively. Each code block also has code to make sure the LED can't disappear ‎off the edge of the display.‎‎ ‎

On Button A Pressed:‎

When the A button is pressed the variable X-Pos is changed by minus 1. If you ‎refer to the grid further up, you will see that this will result in the X-Pos variable ‎being updated with a number that will move it one space to the left. The code then ‎clears the screen of its last location and replots it with the updated value now held ‎in the X-Pos variable. The LED moves one space left.‎

On Button B Pressed:‎

When the B button is pressed the variable X-Pos is changed by plus 1. If you refer ‎to the grid further up, you will see that this will result in the X-Pos variable being ‎updated with a number that will move it one space to the right. The code then ‎clears the screen of its last location and replots it with the updated value now held ‎in the X-Pos variable. The LED moves one space right.‎

On Button A+B Pressed:‎

When the A and B buttons are pressed at the same time the variable Y-Pos is ‎changed by minus 1. If you refer to the grid further up, you will see that this will ‎result in the Y-Pos variable being updated with a number that will move it one ‎space upwards. The code then clears the screen of its last location and replots it ‎with the updated value now held in the Y-Pos variable. The LED moves one space ‎up.‎

The Code that Keeps the LED On Screen:‎

Each of the button press options has code contained within an 'if' block (found in ‎the logic menu). This ensures that the LED cannot go any further, in the current ‎direction of movement, than the edge of the display. In the grid further up, you can ‎see the values for the edge of the screen. In the case of the B button press; if the ‎X-Pos value is greater than 4 it will be reset to 4 and replotted. No matter how ‎many times you try to move further than the edge, the position will just be reset to ‎the edge.‎

The On Shake Input Block:‎

shake_4

This block is much more straightforward than the on button pressed blocks. When ‎the microbit is shaken, the Y-Pos variable is overwritten with a value that will move ‎the LED down to the bottom. The screen is cleared of the last known location and ‎replotted with the new value of Y-Pos. Because we have updated the Y-Pos ‎variable with an absolute value we don't have to worry about code to stop the LED ‎dropping off the screen. ‎‎ ‎

Grab the Code:‎

grab_5

Microsoft MakeCode | Terms of Use | Privacy | Download‎ ‎‎

Copy Code
input.onButtonPressed(Button.A, function () {
XPos += -1
basic.clearScreen()
led.plot(XPos, YPos)
if (XPos < 0) {
XPos = 0
basic.clearScreen()
led.plot(XPos, YPos)
}
})
input.onButtonPressed(Button.AB, function () {
YPos += -1
basic.clearScreen()
led.plot(XPos, YPos)
if (YPos < 0) {
YPos = 0
basic.clearScreen()
led.plot(XPos, YPos)
}
})
input.onButtonPressed(Button.B, function () {
XPos += 1
basic.clearScreen()
led.plot(XPos, YPos)
if (XPos > 4) {
XPos = 4
basic.clearScreen()
led.plot(XPos, YPos)
}
})
input.onGesture(Gesture.Shake, function () {
YPos = 4
basic.clearScreen()
led.plot(XPos, YPos)
})
let YPos = 0
let XPos = 0
XPos = 2
YPos = 4
led.plot(XPos, YPos)

2 - Obey Your Thirst for Simplicity with Sprites:‎

sprites_6

What Does the Code Do:‎

The code accepts input from the user via the microbits A and B buttons and also ‎when the microbit is shaken. The lit Sprite is given a starting position and the user ‎input takes over from there. A moves the Sprite left, B moves the Sprite ‎right, A+B moves the Sprite up and shake brings it to the bottom of the ‎column. Additionally, there is code that ensures the Sprite can't disappear off the ‎edge of the LED matrix. ‎

A Word About Sprites:‎

Many of our Kitronik microbit boards can be coded using custom blocks that we've ‎added to the MakeCode editor. These blocks simplify the job of coding by ‎containing a number of functions within a single block. Sprites are much the same, ‎as each Sprite block hides a number of coded instructions within it. This means ‎you can do some pretty complicated things with relatively few blocks. This is great ‎when you are starting out as it is less likely you will convince yourself that it's too ‎difficult to learn. A host of Variables can look quite scary to the novice, Sprite ‎commands much less so.‎

How Does the Code Work:‎

There are five distinct chunks of code, four that handle each type of user input and ‎one that sets the starting position for the Sprite. The code is simplified greatly by ‎the use of Sprites. Essentially it works in the same way as the more complicated ‎version above but requires much fewer blocks. Each button press moves the Sprite ‎in the desired direction and the 'if on edge bounce' block ensures the sprite stays ‎on the screen. Let's have a closer look. ‎

The On Start Block:‎

on_7

The above image shows how the LED matrix is arranged in terms of x and y and ‎also where our starting Sprite is plotted. In the Game menu, we get the create ‎sprite block and place it into a 'set variable' block from the variables menu. In this ‎block, we just need to input a starting point. Now we have a Sprite lit up we need to ‎figure out how to move it.‎

The on Button press Input Blocks:‎

button_8

The code above allows for three different types of button press; A button pressed, ‎B button pressed, and A and B pressed together. You will notice that the code for ‎each is almost identical as they all move the Sprite one place; left, right, and up ‎respectively. Each code block also has code to make sure the LED can't disappear ‎off the edge of the display. As you can see, this code is much less complicated ‎than in the first example. One block that both changes the x/y value and replots the ‎sprite and another block that stops the Sprite from disappearing off the display.‎

On Button A Pressed:‎

When the A button is pressed the Sprites x value is changed by minus 1. If you ‎refer to the grid further up, you will see that this will result in Sprites x value being ‎updated with a number that will move it one space to the left.‎

On Button B Pressed:

When the B button is pressed the Sprites x value is changed by plus 1. If you refer ‎to the grid further up, you will see that this will result in Sprites x value being ‎updated with a number that will move it one space to the right.‎

On Button A+B Pressed:‎

When the A and B buttons are pressed at the same time the Sprites y value is ‎changed by minus 1. If you refer to the grid further up, you will see that this will ‎result in the Sprites y value being updated with a number that will move it one ‎space upwards.‎

The Code that Keeps the LED On Screen:‎

Each of the button press options has a code block for 'if on edge bounce'. This ‎ensures that the Sprite cannot go any further, in the direction of movement, than ‎the edge of the display. No matter how many times you press the button, the Sprite ‎cannot move any further than the edge of the screen.‎

The On Shake Input Block:‎

input_9

When the microbit is shaken, the Sprites x value is overwritten with a value that ‎will move the LED down to the bottom of the column it is in. Regardless of where ‎the Sprite is, the code will move it down to the bottom. Additionally, the if on edge ‎block ensures it stays on the screen.‎

Grab the Code:‎‎ ‎

codeimage_10

Microsoft MakeCode | Terms of Use | Privacy | Download

Copy Code
input.onButtonPressed(Button.A, function () {
Sprite.change(LedSpriteProperty.X, -1)
Sprite.ifOnEdgeBounce()
})
input.onButtonPressed(Button.AB, function () {
Sprite.change(LedSpriteProperty.Y, -1)
Sprite.ifOnEdgeBounce()
})
input.onButtonPressed(Button.B, function () {
Sprite.change(LedSpriteProperty.X, 1)
Sprite.ifOnEdgeBounce()
})
input.onGesture(Gesture.Shake, function () {
Sprite.change(LedSpriteProperty.Y, 4)
Sprite.ifOnEdgeBounce()
})
let Sprite: game.LedSprite = null
Sprite = game.createSprite(2, 4)

3 - Let's Take It Outside (of the micro:bit with a ‎joystick):‎

outside_11

The animation of the simulation is a little different for this one. Although there is no ‎animation of a joystick, we can manually change the value on the pins in use. Pins ‎‎0 and 2 are reading x and y values from the joystick respectively. You can see this ‎in action above, as I pick a value for these pins the LED moves.‎

The Thumbslide Joystick:‎

The X & Y axis pads on the underside of the joystick output an analog voltage, you ‎can code the microbit to monitor and read these voltages and translate that into an ‎action. In this example we used the Microsoft Block Editor and made use of the ‎‎'map' block to read the output voltages from the X & Y Axis and convert them into a ‎value from 0 to 4 so that the position of the joystick can be tracked using the LED ‎matrix on the micro bit. An edge connector and breadboard is a great way of ‎prototyping this setup. You can expect a range of about 128 to 775 on each axis. ‎You will need to experiment, as the range may vary from joystick to ‎joystick. Note: For wiring this part; if you look at the device from the bottom, the ‎pin out goes:‎

pins_12

We wired the X axis output on the Joystick to P0 on the microbit and the Y axis ‎output to P2 on the microbit. If you choose to use different pins you will need to ‎adjust the code accordingly.‎

What Does the Code Do:‎

The code accepts user input via Pins 0 and 2, these pins are connected to our ‎joystick. Pin 0 is reading movement in the x axis and Pin 2 the y axis. We then use ‎the map block, found in the Pins menu, to convert the pin readings to values that ‎can be stored in our x and y variables. The map block collects readings between ‎two values that we specify. We checked the specs of the joystick as a starting ‎point and tweaked them with a bit of trial and error. Once the microbit is ‎interpreting these values adequately we can then plot the x and y values to the ‎screen. The LEDs position will update in real time. So, any change in the joystick ‎position will instantly be reflected in the LED matrix. All of the 'if' statements ‎contain code to stop the LED disappearing off the edge of the screen in all four ‎directions. Let's take a closer look. ‎

The On start Block:‎

block_13

In the Variables menu we create two variables, one for x and one for y. The on ‎start block only contains the code to set the contents of the variables to zero. As ‎both variables will receive real time updates from the map function, explained ‎below, they will be immediately updated with the joysticks position. Unless you are ‎touching the joystick the LED should show up in the middle of the LED matrix if the ‎map block has the correct values entered into it. ‎

The Map Blocks:‎

map_14

When the joystick is moved this creates a change in voltage on the microbits GPIO ‎pins. In this case the P0 and P2 pins. The mapping block, found in the pins menu, ‎reads the changes within a range that we set. It then converts them to meaningful ‎numbers that are stored within the respective variables. As both LED matrix axis ‎go from 0 to 4, we also input this into the map blocks. The map blocks for each ‎axis have read the voltage, converted it to a number between 0 and 4 and stored it ‎in the respective variable. You can expect a range of about 128 to 775 on each axis. ‎It will take a little experimentation, as the range may vary from joystick to joystick. ‎You can see in the image above the values we determined through trial and error; ‎‎175 to 750 for both.‎

Plotting the LED On the Matrix:‎

plot_15

At the foot of the code in the forever block we use the same method used in the ‎very first example. We clear the screen of the last position and use the plot led ‎block from the led menu to place the LED using the current x and y values. This is ‎done in real time and any changes will be immediately reflected on the LED matrix.‎

Edge Detection:‎

edge_16

Each of the 4 edges of the LED matrix has an 'if' block associated with it. The ‎values represent the x and y axis of the microbits LED matrix. We have highlighted ‎this on an image of a microbit in examples 1 and 2 above. If the LED is moved ‎beyond the limits of the matrix, there is an 'if' statement that sets it back to the ‎edge. We use the 'set variable to' block ensure that the variable holds this ‎corrected position.‎

Grab the Code:‎

Code_17

Microsoft MakeCode | Terms of Use | Privacy | Download‎

Copy Code
let x = 0
let y = 0
basic.forever(function () {
x = pins.map(
pins.analogReadPin(AnalogPin.P0),
175,
750,
0,
4
)
y = pins.map(
pins.analogReadPin(AnalogPin.P2),
175,
750,
0,
4
)
if (x > 4) {
x = 4
}
if (x < 0) {
x = 0
}
if (y > 4) {
y = 4
}
if (y < 0) {
y = 0
}
basic.clearScreen()
led.plot(x, y)
})

‎‎4 - Let's Take It Outside 2 (This time it's personal, ‎to Kitronik):‎

lets_18

For our final example, we turn to our very own :GAME Controller for the BBC ‎micro:bit. It not only offers a more comfortable gaming experience, but it also has 6 ‎programmable buttons. The buttons can be coded easily using our custom ‎MakeCode blocks.‎

final_19

To add them to your menu, click on the cog icon in the top right of the editor, then ‎select Extensions. In the search bar type Kitronik and then press enter. Scroll to ‎and select the Kitronik-game-controller tile and it will be added to your menu. For ‎this example, we will be using our custom blocks in conjunction with Sprite blocks ‎found in the Game menu.‎

What Does the Code Do:‎

The code accepts user input via pins; 12, 13, 15 and 16. These are the pins that ‎relate to the codable buttons on the :GAME controller that we've chosen to use. ‎Once a button press occurs it moves the Sprite either, left, right, up, or down. ‎There is also code that ensures that the Sprite can't disappear off the screen. Let's ‎take a closer look. ‎

The On Start Block:‎

start_20

The above image shows how the LED matrix is arranged in terms of x and y and ‎also where our starting Sprite is plotted. In the Game menu, we get the create ‎sprite block and place it into a 'set variable' block from the variables menu. In this ‎block, we just need to input a starting point. Now we have a Sprite lit up we need to ‎figure out how to move it. ‎

The on button joypad/fire button press blocks:‎

joypad_21

The above four blocks represent the four possible directions of movement, left, ‎right, up, and down. On the :GAME Controller we utilised Joypad right and Left ‎buttons and both fire 1 and 2 for up and down. ‎

on button Joypad Left press:‎

When the left joypad button is pressed the Sprites position on the x axis changes ‎by minus one. If you refer to the grid you will see that this will move the Sprite one ‎place left on the LED matrix.‎

on button Joypad Right press:‎

When the right joypad button is pressed the Sprites position on the x axis changes ‎by plus one. If you refer to the grid you will see that this will move the Sprite one ‎place Right on the LED matrix.‎

on button Fire 1 press:‎

When fire 1 is pressed the Sprites position on the y axis changes by minus one. If ‎you refer to the grid you will see that this will move the Sprite one place Up on the ‎LED matrix.‎

on button Fire 2 press:‎

When fire 2 is pressed the Sprites position on the y axis changes by plus one. If ‎you refer to the grid you will see that this will move the Sprite one place Down on ‎the LED matrix.‎

The Code that Keeps the Sprite on the screen:‎

Each of the button press options has a code block for 'if on edge bounce'. This ‎ensures that the Sprite cannot go any further, in the direction of movement, than ‎the edge of the display. No matter how many times you press the button, the Sprite ‎cannot move any further than the edge of the screen.‎

Grab the code:

grab_22

Microsoft MakeCode | Terms of Use | Privacy | Download‎

Copy Code
Kitronik_Game_Controller.onButtonPress(Kitronik_Game_Controller.ControllerButtonPins.Right, Kitronik_Game_Controller.ControllerButtonEvents.Click, function () {
sprite.change(LedSpriteProperty.X, 1)
sprite.ifOnEdgeBounce()
})
Kitronik_Game_Controller.onButtonPress(Kitronik_Game_Controller.ControllerButtonPins.Fire2, Kitronik_Game_Controller.ControllerButtonEvents.Click, function () {
sprite.change(LedSpriteProperty.Y, 1)
sprite.ifOnEdgeBounce()
})
Kitronik_Game_Controller.onButtonPress(Kitronik_Game_Controller.ControllerButtonPins.Left, Kitronik_Game_Controller.ControllerButtonEvents.Click, function () {
sprite.change(LedSpriteProperty.X, -1)
sprite.ifOnEdgeBounce()
})
Kitronik_Game_Controller.onButtonPress(Kitronik_Game_Controller.ControllerButtonPins.Fire1, Kitronik_Game_Controller.ControllerButtonEvents.Click, function () {
sprite.change(LedSpriteProperty.Y, -1)
sprite.ifOnEdgeBounce()
})
let sprite: game.LedSprite = null
sprite = game.createSprite(2, 4)

That's all folks, for now...‎

all_23

We hope you got something useful from this microbit games writing resource. We ‎intend to build on this with further, and possibly shorter, resources in the future that ‎cover other aspects of writing games for the microbit. Please feel to comment ‎below with any requests as to which topics you would like us to cover.‎

©Kitronik Ltd – You may print this page & link to it but must not copy the page or part thereof ‎without Kitronik's prior written consent.‎

制造商零件编号 2012414
MICRO:BIT V2 SBC-BOARD ONLY
OKdo
制造商零件编号 5644
:GAME CONTROLLER FOR MICRO:BIT
Kitronik Ltd.
制造商零件编号 4154
CBL USB2.0 A PLG-MCR B PLG 3.28'
Kitronik Ltd.
Add all DigiKey Parts to Cart
TechForum

Have questions or comments? Continue the conversation on TechForum, DigiKey's online community and technical resource.

Visit TechForum