Maze Runner Micro:bit Game
Can you make it through all the levels?
We’re going to create a maze game where you must navigate a series of mazes without running into the walls. You’ll learn how to…
- use a Buzzer and ADKeypad with the micro:bit.
- use if statements to evaluate conditions.
- use variables to track game states such as player location.
- customise your game and add your own levels!
- Plug in your Buzzer to Pin0, making sure the positive lead is connected to the yellow signal pin and the negative lead is connected to the black ground pin on the breakout board.
- Plug in the ADKeypad to Pin1, match the colours of the wires to the ones on the breakout board!
- How are we going to create a maze game on the micro:bit? A blinking red LED will represent the player’s position on the micro:bit screen. Solid red LEDs will represent walls. And LEDs that aren’t turned on will represent the maze paths.
- How are we going to keep track of the player’s location on the screen? The micro:bit LEDs can be controlled using coordinates! The x coordinates start from 0 on the left to 4 on the right. The y coordinates start from 0 on top to 4 on the bottom. This means that the upper left LED is x=0, y=0. Likewise, the bottom right LED is x=4, y=4.
- To do this, we need to create a few variables. Remember, variables are like buckets that store pieces of information for us – and whenever we want that stored information we can just look at the variable. We need two variables to keep track of the player’s location. Why two variables? One will keep track of the player’s x position and the other will keep track of the player’s y position.
- We also need a variable to keep track of the maze level (yes, we can have multiple levels!) and also another variable to keep track of whether the game is active (as opposed to a game over).
- So let’s set these up. Inside the ‘on start’ event handler, we (optionally) play a melody and display the name of the game on the micro:bit (MAZE RUNNER!). We also set up the 4 variables mentioned above. I use the names level, playerx, playery, and gameOn
- What do we set these variables to? We start at level 1 (of course), and we set gameOn to True because when we power on the micro:bit, we want to start the game right away. We can choose any starting point for our player location, but we’ll need to remember this location later on when we set up our maze level (we don’t want the player to start inside a wall!). In this example, I choose to start the player at x=0 and y=3.
- Now that we’ve set up our starting variables, let’s get our player to display on the micro:bit screen!
- We want the player LED to blink on and off so that it’s easily identifiable. To do this, we’ll use the ‘plot x y’ block alternating with the ‘pause’ block inside a forever loop. Remember, we want the player to forever blink on and off! However, this won’t work immediately. In step 6 when we add in the maze walls, the micro:bit will overwrite the player every time it draws the maze walls. By adding a pause block here, we make it so that the player won’t immediately be re-plotted, creating a blinking effect.
- We use the playerx and playery variables that we created above. Why? If we typed in numbers here, we wouldn’t be able to easily make our player move! Using variables allows us to change the values of playerx and playery so that the forever loop will plot the new location of the player.
- Remember the pause block is in milliseconds (so 300 ms = .3 seconds)! You can customise the speed at which it flashes by modifying the length of the pause.
- We’ve got the player displaying on the micro:bit, but we can’t move yet! Let’s add in player movement next. We’re going to sense for button presses on the ADKeypad, but to do so, we need to import a special package into MakeCode.
- Expand the ‘Advanced’ section and scroll to the bottom and click on ‘Add Packages’
- In the search box, type in ‘Tinkercademy’. Click on the box labelled ‘tinkercademy-misc’
- Now you’ll see something new in MakeCode – a bright green Tinkercademy category has been added!
- Inside this category you’ll find blocks to sense button presses on the ADKeypad. Note that importing this package only happens for the current project. So if you start a new project and want to use the category, you’ll need to re-import it.
- Now that we have our Tinkercademy category added, we can use the ADKeypad to move up, down, left, and right. In this example, we’ll set the A button to move up, the C button to move down, the D button to move left, and the E button to move right.
- To do this, we use if statments. If statements test to see if a condition is true; if it is true, then they run any blocks inside the if block. When we place an if statement inside a forever loop, we forever test to see if the condition is true.
- To move the player, we simply change the player x or player y variables. Remember, decreasing or increasing playerx causes the player to move left or right respectively, and decreasing or increasing playery causes the player to move up or down respectively. We’re constantly plotting the location of the player using these variables, so when we change them, it automatically changes the player’s location!
- Note that we add a short 300ms pause after each button press. Otherwise the micro:bit would move you many spaces every time you pressed a button because it runs the code so fast.
- Now that we can move our player around, let’s start creating our maze levels! Every time we start a level we need to do a few things: First we need to display the maze walls on the LED display. Second, we need to forever check if the player runs into a wall (if they do, it’s gameover!). And third, we need to forever check if the player makes it to the end of the maze level (if they do, let them know they succeeded and move onto the next level!).
- For each level, we’re going to use a forever loop. Inside the loop, we use an ‘if’ statement to check if the level variable equals 1. This means this code will only ever run if the level variable equals 1.
- Inside the if statement, we first display the maze walls. We light up LEDs to serve as maze walls, and leave them turned off to represent the maze path. This can be done using the ‘show leds’ block. One thing to be careful about though: remember above we set the starting position of the player? Make sure your player starting position is not inside a maze wall! In this example, the starting position of the player is x=0, y=3.
- Next, we need to check if the player ever runs into a wall. How to do this? Once again we’ll use if statments to check if our playerx and playery variables are ever in the same place as a wall. We do this using the coordinate system of the 5x5 LED grid. In this example, there are two sections of walls.
- The first wall exists where playerx is less than or equal to 2 AND playery is less than or equal to 2. We create an if statement with these conditions, and inside we set gameOn to ‘false’ (since if it’s ever ‘true’, it means the player ran into a wall and should get a Game Over).
- The second wall exists where playerx equals 4 OR playery equals 4. We create another if statement with these conditions, and inside we set gameOn to ‘false’ (because once again if it’s ever True, it means the player ran into a wall and should get a Game Over).
- Finally, the last test we need to add is to see if the player makes it successfully through the maze! In this example level, the end of the maze is at x=3, y=0. We create another if statment to check if x=3 AND y=0, and inside we do a few things: First, we play a success melody in the background. Second, we set the starting position of the player for the next level (in this example, we use the same starting position, but it can be different!). Third, we show a smily face to tell the player they succceeded! And fourth, we change the level variable by 1 (this will cause the next level to display).
- Whew, setting up a level was a lot of work! Now that we have a single level, let’s make something happen when a player gets a game over. This will happen whenever they run into a wall, and it’s tracked by the ‘gameOn’ variable.
- Inside a forever loop, we use an if statment to check the value of the ‘gameOn’ variable. If it equals ‘false’, then we want our game over code to run!
- In this example, we play a sad melody in the background, reset the ‘level’, unplot the player LED, show an angry face, and finally display a string telling the player they can press B to restart the game.
- Speaking of pressing B to restart the game, we haven’t yet created the code to do that!
- Inside a forever loop, we test to see if button B on the ADKeypad is pressed. If it is, we want to set ‘level’ to 1, reset the player’s starting location by setting the ‘playerx’ and ‘playery’ variables to 0 and 3 respectively, and set the ‘gameOn’ variable back to ‘true’.
- Now our game should be working as intended! The only thing missing is more levels!
- It’s quite easy to add more levels by duplicating our level 1 code from above. The only things that will change are the maze walls and the coordinates for our if statments (for testing if the player moves into a wall or completes the level.
- Tip: sometimes it can be complicated to create if statements to test for every wall. In these cases, try to break down your walls into separate rectangles and create an if statement for each rectangle.
- One thing to watch out for: after the player completes the level and you reset their playerx and playery variables, make sure the position matches your next level. Otherwise they could start inside a wall!
- Once you’re done adding in levels, you can optionally create a victory section. In this example, once the player successfully completes the first 3 levels and level equals 4, we: unplot the player, play a victory melofy in the background, and show a victory message!
- Now that you’ve learned how to use the ADKeypad, you can try using it to control LEDs, servos, and other components! You also learned about if statements which are useful in many micro:bit projects! Try customising your maze runner game by adding more levels!