Elvis eats peanut butter and banana sandwiches. He dresses in pink and black and, of course, wears blue-suede shoes. In search of sandwiches, Elvis moves 8 pixels every 1/2 second in the direction chosen by the player using the arrow keys. Elvis eats as many sandwiches as he can before he bumps into a wall or his head collides with his body.
The game score is the number of sandwiches eaten by the time a game ends. Each time a sandwich is eaten, Elvis grows longer and more sandwiches are generated at random locations on the field. As the score increases, Elvis gets longer and longer making it increasingly difficult to navigate the field without bumping into himself (e.g., turning his head backward).
For a greater challenge, a player can make e Elvis go faster by selecting the option on the first screen of the game as shown on the left below.
Elvis is similar to Apple-Eating Snake except that Elvis moves automatically and the controller buttons are used only to change directions. In Apple-Eating Snake, pressing and/or holding the controller buttons is required to move the snake.
In this post, “the snake” is called “Elvis” and these terms are used interchangeably.
Big Picture of Game Flow
The code blocks in the screenshot below define the game flow. Notice that these main blocks are all on blocks, which run when something happens, such as, the game starts, the player presses a key, a time elapses or a game object collides with another. These types of blocks should be the first blocks defined by a developer because they define the overall game flow. The on blocks call supporting functions, which will be described later.
The code above uses four types of MakeCode Arcade blocks including:
- The green on-start block that runs when the game starts.
- The purple on-game-update block that runs every so many milliseconds,
- The orange on-button-pressed blocks that run when a player presses a controller button, and
- The blue on-overlap blocks that run when two kinds of sprites overlap (collide) with each other.
The green on-start block below initializes variables, lays out the game board and creates the sprites of the game. It uses the variable b_go to prevent the on-game-update running before initialization is complete. The on-start block sets the background, builds the snake, scatters sandwiches, sets volume, initialized the score, creates borders and asks for player input to set the snake speed
The purple on-game-update block moves Elvis every so-many milliseconds, but only if the variable b_go is true. The variable move_frequency is set according to the option selected by the player in the first game screen. The function move_snake causes the snake to move 8-pixels in the direction of the most-recently pressed arrow button.
The variable b_go is false while the on-start block runs and while the snake head overlap sandwich block runs. In these cases, the snake should not move because (1) the snake is just being built or (2) the snake is being lengthened, respectively, and these actions would interfere with snake movement.
The orange on-button-pressed blocks define the game reaction when the player presses a controller button.
A-Button and B-Button Uses
The B-button has the following three uses:
- At the beginning of the game, a player is presented with an option to make Elvis go faster by pressing the A-Button. The B-button cancels so that Elvis moves at the default speed.
- At other times in the game, the B-button is used to pause and un-pause the game. Pressing the B-button causes the variable b_go
- to be set to true if it was previously false and
- to be set to false if it was previously true.
Arrow Keys Change Snake Direction
The up, right, down and left buttons cause the variable snake_direction to be set to 0, 1, 2 and 3, respectively. Later in the snake_move function, this variable is used to determine in which direction to move Elvis.
The blue on-overlap blocks run when two sprites of specified kinds overlap. Sprite collisions are used in this game to change game score and to end the game.
Snake Head Overlap Food Increases Score
When Elvis’s head overlaps a sandwich (food), the score is increased by 1, a tone is played, the sandwich is destroyed and the snake is lengthened by 8 pixels.
Snake Head Overlaps Snake Body and Snake Head Overlaps Border Ends Game
The first on-overlap block below is triggered if the snake head sprite overlaps any of the snake body sprites. It causes the game to end with a dissolve effect.
The second on-overlap block below is triggered if the snake head sprite overlaps any of the four border sprites, which were built by the make_borders function called from the on-start block. In this case, the game also ends with a dissolve effect.
Using border sprites was not the best way to code this functionality. A better way is to use the sprite auto-destroy feature along with the on-destroyed block . Unfortunately, when I implemented this, I was caught in the middle of Arcade’s transition from SpriteKindLegacy to SpriteKind, which caused these blocks to not operate properly at this time. When this Arcade problem is fixed, I will release Elvis with the new code.
The on blocks described in the preceding section call functions that define the detail of their actions. These functions can be grouped as follows:
- Those functions called by the on-start block as part of the game initialization. These include a function (and their supporting functions) for each of the following actions, which are shown in the screenshot below):
- In code column 1
- get the snake speed from the player
- make field borders
- scatter sandwiches
- In code column 2
- make snake
- In code column 1
- Those functions called during game play:
- In code column 3
- move snake
- lengthen snake
- In code column 3
Each supporting functions is discussed in the following sections.
Get Snake Speed from Player
The function get_snake_speed_from_player (left) generates the screen shown below (right). If the player presses Button-A, a faster speed (lower-move frequency) is set. If the player presses Button B, the default speed is set.
Makes Field Borders
This function places 1-pixel wide border sprites on each of the four sides of the screen. These are used (see above) to detect when Elvis hits the border.
As described above following the snake-head-overlap-food block, using borders is not the best way to implement the needed actions.
The function make_sandwiches places 2 or 3 sandwiches at random locations on the screen, but only if there are fewer than 4 sandwiches on the screen when the function is called.
The function make_snake calls functions to make the snake head and the snake body. The snake movement direction is set to up. The variable cell_side specifies the number of pixels in the head and body sprites from which the snake is constructed. Do not change this variable because other sections of the code assume 8 pixels.
Make Snake Head
This function builds Elvis’ head sprite along with four images that are employed for the four directions in which the snake might move.
Make Snake Body
The snake-body function builds the snake body as a series of body sprites placed vertically followed by a series of body sprites extending left. These sprites are placed in a list used in snake movement.
Make Snake Body Cell Image
This function creates an image, which is used in all snake-body sprites. It has a black background with two pink diagonal lines.
Add One Body Sprite to End of Snake
This function creates a new body sprite placing it at the position specified by the function arguments. The new sprite is placed at the end of the body-sprite list.
This function moves the snake 8 pixels in the direction last picked by the player using the arrow controller keys. This takes place in the following four steps:
- remember the current head position
- move the snake head
- move the last body sprite to the position where the head was before it was moved
- put blue shoes on the new last body sprite
Move Snake Head
The two actions that move the snake head depend on the direction in which the snake is to be moved thus the 4-way if block. In each of the four cases, the two actions are:
- re-position the snake head sprite and
- change the snake-head image so that it points in the new direction.
Move Last Body Sprite to Where Head Was
The fist statement in the function removes the last sprite in the snake-body list and inserts it in the first list position. It then positions the sprite to where the snake head was before it was moved. Because this sprite was at the snake end, its image is shoes; therefore, the sprite image is changed to the snake-body image.
Put Shoes on Last Snake Body Sprite
This function changes the last snake-body sprite to the blue suede shoes image.
Lengthening the snake one sprite (8 pixels) sounds easy; however, where the new sprite is placed on the field depends on the direction of snake tail. This direction is determined by the last two sprites. For example, if the next-to-last sprite is above the last sprite, the new sprite should be placed below the last sprite. In general, the new sprite is placed in line with the prior two sprites.
Play the Game and Get the Code
To play Elvis, click on the following link:
Elvis will open in a new browser tab. To restart the program, click on the Restart button below the game window. To view, edit and download the code, click on the Show Code button towards the top of browser to the right of the game name.