Java Snake
Java Snake
Java Snake
last modified July 20, 2020
In this part of the Java 2D games tutorial, we create a Java Snake game clone. Source code
and images can be found at the author's Github Java-Snake-Game repository.
Snake
Snake is an older classic video game. It was first created in late 70s. Later it was brought to
PCs. In this game the player controls a snake. The objective is to eat as many apples as
possible. Each time the snake eats an apple its body grows. The snake must avoid the walls
and its own body. This game is sometimes called Nibbles.
OPEN
Board.java
package com.zetcode;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.Timer;
public Board() {
initBoard();
}
addKeyListener(new TAdapter());
setBackground(Color.black);
setFocusable(true);
dots = 3;
locateApple();
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
doDrawing(g);
}
if (inGame) {
Toolkit.getDefaultToolkit().sync();
} else {
gameOver(g);
}
}
dots++;
locateApple();
}
}
if (leftDirection) {
x[0] -= DOT_SIZE;
}
if (rightDirection) {
x[0] += DOT_SIZE;
}
if (upDirection) {
y[0] -= DOT_SIZE;
}
if (downDirection) {
y[0] += DOT_SIZE;
}
}
if (y[0] < 0) {
inGame = false;
}
if (x[0] < 0) {
inGame = false;
}
if (!inGame) {
timer.stop();
}
}
@Override
public void actionPerformed(ActionEvent e) {
if (inGame) {
checkApple();
checkCollision();
move();
}
repaint();
}
@Override
public void keyPressed(KeyEvent e) {
The B_WIDTH and B_HEIGHT constants determine the size of the board. The DOT_SIZE is the
size of the apple and the dot of the snake. The ALL_DOTS constant defines the maximum
number of possible dots on the board (900 = (300*300)/(10*10)). The RAND_POS constant
is used to calculate a random position for an apple. The DELAY constant determines the
speed of the game.
These two arrays store the x and y coordinates of all joints of a snake.
private void loadImages() {
In the loadImages() method we get the images for the game. The ImageIcon class is used
for displaying PNG images.
dots = 3;
locateApple();
In the initGame() method we create the snake, randomly locate an apple on the board,
and start the timer.
dots++;
locateApple();
}
}
If the apple collides with the head, we increase the number of joints of the snake. We call
the locateApple() method which randomly positions a new apple object.
In the move() method we have the key algorithm of the game. To understand it, look at
how the snake is moving. We control the head of the snake. We can change its direction
with the cursor keys. The rest of the joints move one position up the chain. The second
joint moves where the first was, the third joint where the second was etc.
if (leftDirection) {
x[0] -= DOT_SIZE;
}
In the checkCollision() method, we determine if the snake has hit itself or one of the
walls.
If the snake hits one of its joints with its head the game is over.
The game is finished if the snake hits the bottom of the board.
Snake.java
package com.zetcode;
import java.awt.EventQueue;
import javax.swing.JFrame;
public Snake() {
initUI();
}
add(new Board());
setResizable(false);
pack();
setTitle("Snake");
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
EventQueue.invokeLater(() -> {
JFrame ex = new Snake();
ex.setVisible(true);
});
}
}
setResizable(false);
pack();
The setResizable() method affects the insets of the JFrame container on some
platforms. Therefore, it is important to call it before the pack() method. Otherwise, the
collision of the snake's head with the right and bottom borders might not work correctly.
Figure: Snake