Table of Contents
Recreate the game with Java

Do you know the basics of Java or Processing and want to start developing your own games or maybe just recreate one of the classics? This article describes the process of building the classic Snake game using Processing.
Wikipedia (2022) describes Processing as a graphical library and integrated development environment (IDE). The library is built on Java and provides additional classes and simplifications (Wikipedia, 2022). To download and install Processing, go to processing.org/download and download the installable matching the preferred platform.
1.1 Application Flow
Processing provides many methods to control the flow of an application, for example, to control key events, initialization, or continuous behavior. Two important methods to know to get started with Processing are the methods setup()
and draw()
. Another built-in method, the article is introducing later is keyPressed()
. The behavior of the three methods is:
setup()
is called one time when the application starts (Processing, 2022a).draw()
executes forever and is called a number of times matching the framerate (Processing, 2022b).keyPressed()
executes when a key is pressed, and the key is stored in a variable namedkey
(Processing, 2022c).
1.2 Graphical Interface
Processing also provides a graphical interface where the point (x, y) = (0, 0) is at the left top corner (see figure 1). Drawing shapes within Processing is very simple because the library provides the 2D primitive methods such as rect(x, y, w, h)
, circle(x, y, r)
or line(x1, y1, x2, y2)
. Find more 2D primitive methods at processing.org/reference.

As with every project, it can be a great idea to establish a couple of requirements to set the direction and outline an overview of necessary features. Section 2.1, therefore, describes the requirements of the game which is followed by a section describing the code.
2.1 Requirements
The requirements for the game are:
- The snake and objective are drawn using rectangles.
- The first rectangle of the snake represents the head of the snake and it is only the head that can trigger collision events with the objective and tail.
- When the snake reaches the screen’s border, it is teleported to the opposite position.
- The objective gets a new random position when it collides with the snake’s head.
- The game ends if the snake’s head collides with its tail.
- The score increases whenever the snake collides with the objective.
2.2 Coding the game
To keep the article simple, the following section is divided into different steps of coding the game.
2.2.1 Adding properties
The first step is to add global properties that can store information about size, positions, etc. The first two properties to add is gameover
and s
(see figure 2). The boolean variable gameover
is used to check if the player has lost the game and the float variable s
is a general size specifying the size of the rectangles representing the objective and the snake.
Now, when the general properties are in place it’s time to add the properties for the snake. The snake will require a property specifying the position of each rectangle representing the snake’s tail and head. It will also require a property specifying the direction of the snake. To store the positions of the snake’s rectangles, add a property called snakePositions
of the type ArrayList<PVector>
and to store information about the snake’s direction, add a property called snakeDirection
of the type PVector
(see figure 3).
The last property, the game requires, is a variable specifying the positions of the objective. Add a property called objPosition
of the type PVector
(see figure 4).
2.2.2 Property data types
Section 2.2.1, adding properties, introduces a couple of data types that may be unfamiliar to beginners. boolean
and float
are primitive data types, boolean
refers to a value that can be either true or falseand float
refers to a number that unlike an integer can specify a whole number and a decimal part. ArrayList<T>
and PVector
are composite data types, ArrayList<T>
refers to a list of other data types that can be dynamically resized, PVector
refers to a 2 or 3-dimensional vector.
2.2.3 Adding custom helper methods
The next section covers a couple of helper methods used to help simplify the explanation of the game. The first method is used to check if the position of two points overlaps (see figure 5).
The procedure of the method can be defined as follows:
- Expect two vectors specifying the top left corner of a rectangle.
- Find the center position of the rectangle using its size (
s
). - Return true if the distance between the center positions is less than the size.
The next method is used to give a vector a random position (see figure 6).
The procedure of the method is as follows:
- Set the horizontal property (
x
) to a random float withina
andb
. - Set the vertical property (
y
) to a random float withina
andb
.
The last two helper methods are reset()
and endgame()
. reset()
is used to set the properties of the game to the same state as at the start of the application and endgame()
is used to start the end game functionality.
The procedure of endgame()
is:
- Set the
gameover
property totrue
to signal the game is ended. - Override the current content with a black background.
- Reset the fill color to set the text color to white.
- Display a text saying “Gameover”.
The procedure of reset()
is:
- Set the
gameover
property totrue
to signal the game is NOT ended. - Remove all saved positions from the
snakePositions
property. - Define a vector with the position of the screen’s center.
- Add the vector to the
snakePositions
property to define the snake’s head. - Set the objective’s position to a random position within the screen’s borders.
2.2.4 Add the built-in method: setup
The next method, the game requires, is the built-in setup method which is called once when the application starts.
The procedure of the method is as follows:
- Set the screen size to 250×250 pixels.
- Set the frame rate to 25 frames pr. second.
- Reset the properties of the game using the helper method: reset
2.2.5 Add the built-in method: draw
The built-in method draw()
is called continuously until the application is stopped. The code within the draw()
method is a bit more complex than other methods presented in the article and the code is, therefore, divided into several parts in the following section.
The procedure of the code presented in figure 9 can be described as follows:
- Set the screen’s background to black.
- If the property
gameover
is true, which means the game is ended, wait 5 seconds, and reset the game. - Set the fill color to white.
- Display a text saying “Score: x” at (x, y) = (10, 20).
- Set the fill color to black and stroke color to white.
- Draw the objective.
- Loop the
snakePositions
property in reversed order. - Get the current position.
- Check if the current index is equal to the head’s index to define behavior for the snake’s head, and add an else statement used to define the behavior for the snake’s tail.
- Draw a rectangle at the current position representing the snake’s tail or head.
Why loop the snakePositions
from the end to the start? The reason is related to the movement of the snake. Whenever the head of the snake moves one time in some direction, each rectangle of the tail also has to be moved one time.
The code is, therefore, designed as follows:
- Start by selecting the last element and set its position to the second last element’s position.
- Select the second last element and set its position to the third last element’s position.
- Continue to select an element, and set its position to the position of the element before it, until the first element is reached.
- When the first element is reached, move the position of that element one time towards the direction specified in the property called
snakeDirection
.
The draw()
method currently moves the position of the snake, checks if the game is ended, and draws the snake and the objective. But it still needs some functionality handling what should happen when the snake reaches the screen’s borders and some other functionality handling when the snake’s head overlaps with the objective or its own tail.
The procedure for when the snake reaches the screen’s borders (L 14–18, figure 11):
- If the horizontal property (
x
) of the snake is less than zero, set the property to the screen’s width. - If the horizontal property (
x
) of the snake is greater than the screen’s width, set the property to zero. - If the vertical property (
y
) of the snake is less than zero, set the property to the screen’s height. - If the vertical property (
y
) of the snake is greater than the screen’s height, set the property to zero.
The procedure for when the snake’s head overlaps with the objective (L 22–29, figure 11):
- If the position of the snake’s head overlaps with the position of the objective.
- Set the position of the objective to a new random position.
- Get the position of the snake’s last tail element.
- Define a position behind the last tail element.
- Add that position as the new last tail element.
The procedure for when the snake’s head overlaps with one of its tail elements (L 34–39, figure 11):
- If the tail element is not directly attached to the head and overlaps with the head.
- End the game.
- Stop the loop.
- If the tail element doesn’t overlap, set the position of the tail element.
2.2.6 Add the built-in method: keyPressed
The last functionality the game requires is something handling key events.
The directions the snake can move can be defined as follows:
Left
— (x, y) = (-1, 0)Right
— (x, y) = (1, 0)Up
— (x, y) = (0, -1)Down
— (x, y) = (0, 1)
The procedure for the keyPressed()
method is:
- If the ‘a’-key is pressed and if the snake is not moving
right
set the direction toleft
. - If the ‘d’-key is pressed and if the snake is not moving
left
set the direction toright
. - If the ‘s’-key is pressed and if the snake is not moving
up
set the direction todown
. - If the ‘w’-key is pressed and if the snake is not moving
down
set the direction toup
.
A Github Gist with a full example of the code for the game can be found at this link.
Processing is a graphical library and a development environment (IDE). It provides a graphical interface that can be used to draw different shapes and text. setup()
, draw()
and keyPressed()
are built-in Processing methods used to handle initialization, continuous behavior, and keypress events. ArrayList<T>
can be used to create a dynamically sized list andPVector
specifies a vector, and provides methods to calculate the distance between vectors. The movement of the snake is created by looping the snakePositions
in reversed order and assigning the position of each element to the position of the element before reaching the snake’s head which is moved towards the direction specified in snakeDirection
.
En.wikipedia.org. 2022. Processing (programming language) — Wikipedia. [online] Available at:
Processing.org. 2022a. [online] Available at:
Processing.org. 2022b. [online] Available at:
Processing.org. 2022c. [online] Available at: