MakeCode Arcade
If you're not already familiar with the basics of MakeCode Arcade, check out this guide on creating a character sprite and moving it with controls.
To start, open a new Chrome browser window (Chrome works best) and go to MakeCode Arcade beta.
These MakeCode Arcade guides are designed to take you through the fundamentals before tackling more complex games, such as Arkanoid:
Arkanoid
We'll begin by loading a completed version of the MakeCode Arcade Arkanoid game and then take a look at each section of the program to understand how it all works!
Start by launching MakeCode Arcade beta using the Google Chrome web browser. Then, download the Re-MakeCode-Arkanoid.png file by right-clicking on the image below and saving it to your computer.
Load the Code
This is a special .png file that contains not only an image, but the entire game is embedded in it as well!
Simply drag it from the location to which you saved the image on your computer (such as the desktop as shown here) onto the Chrome browser window that is already running MakeCode Arcade (MCA). Note that the image in this graphic is of a different game, but you'll be dragging the Arkanoid png file.
This will open the code into the MCA editor.
Give the game a test play -- it's fun! Press the A button to start the game and launch the ball. Then, use the controller d-pad/thumbstick to move the paddle left and right and bounce the ball into the bricks!
Now, we'll have a look at the blocks that make it all work.
Background and Tile Map/Tiles
We'll begin by creating the background image. You can use a solid color for this, or create a pattern. I made a black and blue checkerboard pattern that will read like a dark blue, especially on the PyGamer or PyBadge screen.
The tile map will define the position of the walls for bouncing the ball as well as determining when the ball has been missed by the panel. Also, to create a graphical border frame similar to the original Arkanoid style, we need to make six tiles that will be placed on each of their associated color indexed spots on the tile map.
Note that the tile for the red tile map positions is just a sliver of the same background pattern so that it doesn't show up -- if you leave a color on the tile map without an associated tile the palette color of the tile map itself will show up, in this case it would be a big red line across the bottom.
Make a Splash
Once the field is in place we'll us the splash blocks to write text on screen. First "Re-MakeCode:" and "ARKANOID" will be displayed, and require the player to press the A button to advance. Then we'll use a second splash block to give instructions "Press 'A' button" and "to launch ball"
Music, Maestro
Next, we'll play the Arkanoid theme music. This is done with a separate function, named BGM
, for "background music". This function contains the notes that we'll play, and it's triggered with the call BGM
function block.
You'll see that many parts of the game are created with functions so that they can be called discreetly when necessary, as well as too keep things organized -- otherwise this on start loop, for example, would be getting really big!
Brick Work
We'll create the rows of bricks as functions as well, one function per row of eight bricks.
Each brick is made with the set mySprite to <sprite art> of kind Food block (Food is selected from the dropdown menu.) Rename this first one to brickA01
Here's an example of some simple sprite art for the beige and red bricks, but you can get as fancy as you like here, just keep the dimensions the same.
In a future guide, we'll explore creating this type of repetitive sprite set using iterative loops and arrays, but for now, each is made by copying and pasting the set brickA01 of type Food block and set brickA01 position block pairs multiple times.
Note how the position y value is the same for each brick per row, while the position x value increases by 16 pixels for each brick.
We'll create five rows of bricks, each with its own function. This allows us to only use some rows but not others to leave a fun gap between rows for bonus bounces of the ball!
You can see here the rows called in our on start loop being displayed.
Paddle Setup
After the bricks are set, we call the paddleSetup function to, well, set up the paddle!
This consists of first creating the sprite paddle of type Player.
We then set it to move with the thumbstick/d-pad buttons. By setting the velocity to vx = 150 and vy = 0, we are constraining it to move horizontally only, but quite quickly.
We'll prevent the paddle from leaving by turning on stay in screen, and finally, set it to the center, bottom of the screen.
Lives and Variables
The last things we'll do in the on start loop are set the life counter to 3 and create these two variables we'll use later:
- brickCount variable will be used to determine when the player has hit the final brick for the level,
- ballInPlay variable is a sort of toggle for keeping track of the state of the ball so we know when to allow the player to send a new ball into the level after they've lost a paddle life.
Press A
The next thing we set up is what to do when the player presses the A button.
The if statement checks to see if the ball is currently in play, based on the ballInPlay variable's value. Since we set it at 0 in the startup, the condition is true and it'll proceed to call the ballUpdate function, essentially launching the ball into play.
We also immediately flip the ballInPlay variable to 1 so that pressing the A button again won't do anything until the ball goes out of bounds.
Ball Update
When the ballUpdate function is called, here's what happens:
First, the if else block checks to see that there are still lives left, since this function will be called both when the player starts a level and when the ball goes out of bounds (the player missed it with the paddle). If the life counter is at 0 it will run the game over lose with melt effect block.
If there are more lives than 0, the ballSetup and paddleReset functions will be called.
ballSetup does a number of things! First:
- Create the sprite named ball with a ball graphic of the type Projectile
- Set the ball to bounce on walls and stay in screen
- Set the ball's velocity down and left with vx = -60 and vy = 60
Then, we will create a few variables to help set ball speed and figure out the bounce angles:
ballInitSpeed is the initial speed of the ball
ballChangeSpeed can be used to adjust speed between levels
ballMaxVxFactor can be used as a factor to mulitply the ballInitSpeed and derive the ballMaxVx maximum velocity on the x axis
ball position is then set to the lower near-center of the screen
The ballVx variable is set to 0, this will be used to calculate the bounce angle.
The the ballVy variable is set to the ballInitSpeed speed minus the ball's vx value.
Ball Hits Paddle
Here we'll get to bouncing the ball off of the paddle. This isn't as simple as the wall bounce we've used before, as it's not a canned function, and we want the player to be able to angle the ball depending on where on the paddle they hit it.
The on sprite of kind Projectile overlaps otherSprite of kind Player block will run any time the ball (a Projectile) hits the paddle (a Player).
Next, we set the xDiff variable to the differential between the ball's horizontal position (ball x) and the paddle's horizontal position (paddle x).
We'll use this xDiff to help us determine where on the paddle the ball has hit.
Note: this method comes from AlexK's excellent breakout game posted on the MakeCode forums!
If the xDiff is equal to zero, this means the ball has hit dead center on the paddle. We actually don't want to allow this to cause the ball to bounce off straight up and down, so we'll nudge it just a couple of pixels and re-set the xDiff value to 2 before proceeding.
Next, we'll set the ballVx variable to the absolute of xDiff multiplied by the ballMaxVx divided by the paddle width plus 2. This give us the velocity x value we'll need to send the ball off the paddle.
Then, we'll set the ballVy variable to the ballVx variable's value we just determined, minus the ball's initial speed.
Now, if the differential between the ball and paddle's x positions is negative, the if xDiff < 0 block will invert the ballVx value by mulitplying it by -1.
Now that the variables have been calculated, those values are actually applied to the ball with the set ball velocity to vc ballVx vy BallVy block.
Ball Misses Paddle
When the player misses the ball, it will hit the red wall as set in the tile map -- using the on sprite of kind Projectile hits wall (red) allows us to take action.
First, we'll shake the camera a bit, then destroy ball with ashes effect for 20 ms.
We'll reduce the player life count by one, play a four tone sound effect, and then flip the ballInPlay variable to zero.
Paddle Misses Ball
When the player misses the ball, it will hit the red wall as set in the tile map -- using the on sprite of kind Projectile hits wall (red) allows us to take action.
First, we'll shake the camera a bit, then destroy ball with ashes effect for 20 ms.
We'll reduce the player life count by one, play a four tone sound effect, and then flip the ballInPlay variable to zero.
Ball Hits Bricks
Similarly to the ball hitting the paddle, we use the overlap test to see when the ball (sprite of kind Projectile) overlaps a brick (otherSprite of kind Food).
If the ball is traveling upward (vy > 0) we invert the velocity on y and send it back down. The opposite is true if the ball is traveling downward when it hits a brick, which happens on rebounds off the top of the board or higher rows of bricks.
Next, we'll destroy otherSprite to get rid of the brick.
The score goes up by 200 points. Yay!
The brickCount variable is reduced by one, so we'll know when the last brick is hit.
A satisfying tone is played for a 1/4 beat.
If the final brick is hit (brickCount < or = 0) then we destroy the ball and paddle, pause a brief moment, and then reset everything for the next level.
This includes calling the brick setup functions for the rows you want, setting the associated brickCount value, setting ballInPlay to 0 and finally, playing the BGM music!
Ball Hits Bricks
Similarly to the ball hitting the paddle, we use the overlap test to see when the ball (sprite of kind Projectile) overlaps a brick (otherSprite of kind Food).
If the ball is traveling upward (vy > 0) we invert the velocity on y and send it back down. The opposite is true if the ball is traveling downward when it hits a brick, which happens on rebounds off the top of the board or higher rows of bricks.
Next, we'll destroy otherSprite to get rid of the brick.
The score goes up by 200 points. Yay!
The brickCount variable is reduced by one, so we'll know when the last brick is hit.
A satisfying tone is played for a 1/4 beat.
If the final brick is hit (brickCount < or = 0) then we destroy the ball and paddle, pause a brief moment, and then reset everything for the next level.
This includes calling the brick setup functions for the rows you want, setting the associated brickCount value, setting ballInPlay to 0 and finally, playing the BGM music!
And now, the player can start up the next level by pressing A!
Page last edited March 08, 2024
Text editor powered by tinymce.