Building a Snake game in Scratch is one of the best intermediate projects you can tackle, and it only requires one sprite, a few lists, and about 30 minutes. The core idea is simple: a square moves constantly in one direction, you steer it with arrow keys, it eats food to grow longer, and the game ends if the snake hits itself or a wall. Here’s how to build it step by step.
Set Up the Project
Open a new Scratch project at scratch.mit.edu. Delete the default cat sprite and create a new one: a small filled square, roughly 10 by 10 pixels, using the costume editor. This square represents one segment of the snake. Choose a bright color like green so it stands out against the backdrop.
Next, create a second sprite for the food. Draw another small square (same size) in a different color, like red. That’s all you need for sprites. For the backdrop, a plain black or dark background works best and gives the game a classic arcade feel.
Create the Variables and Lists
Before writing any scripts, set up the data your game needs. Go to the Variables category and create these:
- direction: stores which way the snake is currently heading
- score: tracks how many food items the snake has eaten
- length: the current number of body segments
Now create two lists (click “Make a List” in the same category):
- snake X: stores the X position of every segment
- snake Y: stores the Y position of every segment
These two lists are the backbone of the entire game. Every time the snake moves, you record its new head position at the front of each list and delete the oldest position from the end. This creates the illusion of a snake slithering across the screen. When the snake eats food, you skip the deletion step, so the list grows by one entry and the snake gets longer.
Program Constant Movement
The snake never stops moving on its own. You control only the direction, not the speed. Inside the snake sprite, start with a “when green flag clicked” block, then set up your starting conditions: go to x: 0 y: 0, point in direction 90 (facing right), set length to 3, set score to 0, and delete all items from both the snake X and snake Y lists.
Below that, add a “forever” loop. Inside the forever loop, the snake moves a fixed number of steps on each cycle. A step size of 10 works well if your sprite is 10 pixels wide, because it keeps the snake aligned to a neat grid. After each move, insert the snake’s current x position at position 1 of the snake X list, and insert the y position at position 1 of the snake Y list. This places the new head position at the top of both lists every single frame.
Still inside the forever loop, add a check: if the length of the snake X list is greater than the “length” variable, delete the last item of snake X and the last item of snake Y. This trims the tail so the snake stays at the correct length. When the snake eats food and you increase the length variable, the list is allowed to grow by one before trimming kicks in again.
Add a short “wait 0.1 seconds” block inside the loop to control game speed. A smaller wait makes the game faster and harder. Start with 0.1 and adjust to your taste.
Add Arrow Key Controls
Because the snake is always moving, the player only needs to tap a key to change direction. Use four separate “when [key] pressed” hat blocks, one for each arrow key:
- Up arrow: point in direction 0
- Down arrow: point in direction 180
- Left arrow: point in direction -90
- Right arrow: point in direction 90
Using “when key pressed” blocks instead of “if key pressed” sensing blocks is important here. The “when key pressed” approach fires once per tap, which feels right for a grid-based snake game. It also prevents the snake from reversing into itself if you accidentally double-tap.
To add an extra layer of protection, you can wrap each direction change in a condition. For example, only allow “point in direction 0” if the snake is not currently pointing at 180. This stops the snake from doing a 180-degree turn directly into its own body.
Draw the Snake Body
Moving the sprite draws the head, but you need to see the full body. The simplest approach uses the pen extension. Click “Add Extension” in the bottom left corner of Scratch and choose “Pen.” At the start of the game, add “erase all” and “pen down” blocks. Set the pen color to match your sprite and the pen size to match the sprite width (10, for example).
The pen draws a trail everywhere the snake goes, but you also need to erase old segments as the tail moves. Inside your forever loop, after you delete the last items from your lists, use a “stamp and erase” approach: erase all pen marks, then loop through every item in the snake X list, moving the sprite to each stored coordinate and stamping or drawing a dot. This redraws the entire snake from scratch on each frame.
Here’s what that inner drawing loop looks like in blocks: add a “set pen color” block, then a “repeat (length of snake X)” loop. Inside it, set x to the current item of snake X, set y to the matching item of snake Y, and use “pen down” then “pen up” to place a dot. Use a counter variable to step through the list items.
An alternative to the pen is using the “stamp” block on the sprite itself. Erase all stamps at the start of each frame, loop through your coordinate lists, move the sprite to each position, and stamp. Both methods work. The pen approach tends to run a little smoother with longer snakes.
Place and Detect Food
Switch to your food sprite. When the green flag is clicked, have it go to a random position on the screen. Use “go to x: (pick random -220 to 220) y: (pick random -160 to 160)” but round these to the nearest multiple of 10 so the food aligns with your grid. A quick way to do this in Scratch: pick a random number from -22 to 22 and multiply by 10 for x, and random -16 to 16 multiplied by 10 for y.
Add a forever loop that checks “if touching [snake sprite]?” When the condition is true, increase the score by 1, increase the length variable by 1, and send the food to a new random grid-aligned position. That single “change length by 1” is all it takes to grow the snake, because your movement loop already uses the length variable to decide when to trim the tail.
Detect Game Over Conditions
The game should end when the snake hits a wall or runs into its own body. For wall detection, add a check inside the snake’s forever loop: if the x position is greater than 230 or less than -230, or the y position is greater than 170 or less than -170, stop all scripts and display a “Game Over” message. You can use a “say” block or switch to a game-over backdrop.
Self-collision is a bit trickier. After the snake moves and before you update the lists, loop through items 2 through the end of snake X and snake Y. If any stored coordinate pair matches the snake’s current x and y position, the head has collided with the body. Trigger the same game-over sequence. A small helper: only start checking for self-collision once the snake is longer than 4 segments, since shorter snakes can’t physically collide with themselves.
Fine-Tune the Gameplay
Once the basic game works, small tweaks make a big difference. Lowering the wait time inside the forever loop from 0.1 to 0.05 seconds speeds things up noticeably. You could also decrease the wait time each time the player scores, so the game gets progressively harder.
Display the score on screen by checking the box next to your score variable in the Variables palette, or use a “say (score)” block on a separate sprite for a cleaner look. Adding a short sound effect when the snake eats food (use the “play sound” block with one of Scratch’s built-in sounds like “chomp”) makes the game feel more polished.
If the snake feels too slow at the start, you can increase the initial length to 5 or 6 so the game looks more interesting right away. And if you want a bordered play area, draw a rectangle on the backdrop that marks the boundaries, so players can see exactly where the walls are instead of guessing at the screen edges.

