Designing a Classic Snake Game Using Java

Table of Contents

Introduction

Remember the days when mobile games were simple, yet incredibly addictive? One such classic game is Snake. Today, we’ll take a nostalgic trip back to those times by designing our very own Snake game using Java. Whether you’re a beginner or an experienced developer, this step-by-step guide will help you create a fun and engaging Snake game. Let’s dive in!

Snake Game using Java

Step 1: Setting Up Your Project

First, you’ll need to set up your Java development environment. You can use any IDE you prefer, such as IntelliJ IDEA, Eclipse, or NetBeans. For this tutorial, we’ll use IntelliJ IDEA.

  1. Create a New Project:
    • Open IntelliJ IDEA and select “New Project.”
    • Choose “Java” and click “Next.”
    • Name your project “SnakeGame” and select the location where you want to save it.
    • Click “Finish.”
  2. Create a New Java Class:
    • Right-click on the src folder and select “New” → “Java Class.”
    • Name your class SnakeGame.

Step 2: Setting Up Your Game Window

We’ll start by setting up the game window where the Snake game will be played. We’ll use JFrame to create the main window and JPanel to draw the game’s components.

				
					import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Toolkit;

public class SnakeGame extends JFrame {
    private static final int WINDOW_WIDTH = 800;
    private static final int WINDOW_HEIGHT = 600;

    public SnakeGame() {
        setTitle("Snake Game");
        setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
        setLocationRelativeTo(null);

        GamePanel panel = new GamePanel();
        add(panel);
        setVisible(true);
    }

    public static void main(String[] args) {
        new SnakeGame();
    }
}

class GamePanel extends JPanel {
    private static final int PANEL_WIDTH = 800;
    private static final int PANEL_HEIGHT = 600;

    public GamePanel() {
        setPreferredSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT));
        setBackground(Color.BLACK);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        // Drawing code will go here
    }
}
				
			

Step 3: Designing the Snake

Now, let’s design the Snake. The Snake will be a series of rectangles (or “segments“) that move in a specified direction.

				
					import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;

public class Snake {
    private List<Rectangle> body;
    private int direction;
    private static final int SEGMENT_SIZE = 20;

    public Snake() {
        body = new ArrayList<>();
        body.add(new Rectangle(100, 100, SEGMENT_SIZE, SEGMENT_SIZE)); // Head of the snake
        direction = KeyEvent.VK_RIGHT; // Initial direction
    }

    public void move() {
        // Move the snake in the current direction
        Rectangle head = body.get(0);
        int x = head.x;
        int y = head.y;

        switch (direction) {
            case KeyEvent.VK_UP -> y -= SEGMENT_SIZE;
            case KeyEvent.VK_DOWN -> y += SEGMENT_SIZE;
            case KeyEvent.VK_LEFT -> x -= SEGMENT_SIZE;
            case KeyEvent.VK_RIGHT -> x += SEGMENT_SIZE;
        }

        body.add(0, new Rectangle(x, y, SEGMENT_SIZE, SEGMENT_SIZE));
        body.remove(body.size() - 1);
    }

    public void setDirection(int direction) {
        this.direction = direction;
    }

    public List<Rectangle> getBody() {
        return body;
    }
}
				
			

Step 4: Drawing the Snake

Next, we’ll draw the Snake on the game panel.

				
					@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);

    for (Rectangle segment : snake.getBody()) {
        g.setColor(Color.GREEN);
        g.fillRect(segment.x, segment.y, segment.width, segment.height);
    }
}
				
			

Step 5: Handling User Input

We need to allow the player to control the Snake’s direction using the arrow keys. We’ll add a KeyListener to the game panel.

				
					import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

public class GamePanel extends JPanel {
    private Snake snake;

    public GamePanel() {
        setPreferredSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT));
        setBackground(Color.BLACK);
        snake = new Snake();

        addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                snake.setDirection(e.getKeyCode());
            }
        });
        setFocusable(true);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        for (Rectangle segment : snake.getBody()) {
            g.setColor(Color.GREEN);
            g.fillRect(segment.x, segment.y, segment.width, segment.height);
        }
    }
}
				
			

Step 6: Game Loop

We need a game loop to continuously update the game state and repaint the game panel.

				
					import javax.swing.Timer;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class GamePanel extends JPanel implements ActionListener {
    private Snake snake;
    private Timer timer;

    public GamePanel() {
        setPreferredSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT));
        setBackground(Color.BLACK);
        snake = new Snake();

        addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                snake.setDirection(e.getKeyCode());
            }
        });
        setFocusable(true);

        timer = new Timer(100, this);
        timer.start();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        for (Rectangle segment : snake.getBody()) {
            g.setColor(Color.GREEN);
            g.fillRect(segment.x, segment.y, segment.width, segment.height);
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        snake.move();
        repaint();
    }
}
				
			

Step 7: Adding Food

The Snake needs to eat food to grow. Let’s add food to the game.

				
					import java.awt.Rectangle;
import java.util.Random;

public class Food {
    private Rectangle food;
    private static final int SIZE = 20;

    public Food() {
        generateNewFood();
    }

    public void generateNewFood() {
        Random random = new Random();
        int x = random.nextInt(SnakeGame.WINDOW_WIDTH / SIZE) * SIZE;
        int y = random.nextInt(SnakeGame.WINDOW_HEIGHT / SIZE) * SIZE;
        food = new Rectangle(x, y, SIZE, SIZE);
    }

    public Rectangle getFood() {
        return food;
    }
}
				
			

Update the GamePanel class to include the food.

				
					private Food food;

public GamePanel() {
    setPreferredSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT));
    setBackground(Color.BLACK);
    snake = new Snake();
    food = new Food();

    addKeyListener(new KeyAdapter() {
        @Override
        public void keyPressed(KeyEvent e) {
            snake.setDirection(e.getKeyCode());
        }
    });
    setFocusable(true);

    timer = new Timer(100, this);
    timer.start();
}

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);

    for (Rectangle segment : snake.getBody()) {
        g.setColor(Color.GREEN);
        g.fillRect(segment.x, segment.y, segment.width, segment.height);
    }

    g.setColor(Color.RED);
    g.fillRect(food.getFood().x, food.getFood().y, food.getFood().width, food.getFood().height);
}
				
			

Step 8: Collision Detection

Finally, let’s add collision detection to determine if the Snake has eaten the food or collided with itself or the walls.

				
					public class Snake {
    private List<Rectangle> body;
    private int direction;
    private boolean growing;

    public Snake() {
        body = new ArrayList<>();
        body.add(new Rectangle(100, 100, SEGMENT_SIZE, SEGMENT_SIZE)); // Head of the snake
        direction = KeyEvent.VK_RIGHT; // Initial direction
        growing = false;
    }

    public void move() {
        Rectangle head = body.get(0);
        int x = head.x;
        int y = head.y;

        switch (direction) {
            case KeyEvent.VK_UP -> y -= SEGMENT_SIZE;
            case KeyEvent.VK_DOWN -> y += SEGMENT_SIZE;
            case KeyEvent.VK_LEFT -> x -= SEGMENT_SIZE;
            case KeyEvent.VK_RIGHT -> x += SEGMENT_SIZE;
        }

        body.add(0, new Rectangle(x, y, SEGMENT_SIZE, SEGMENT_SIZE));
        if (!growing) {
            body.remove(body.size() - 1);
        } else {
            growing = false;
        }
    }

    public void grow() {
        growing = true;
    }

    public boolean checkCollision() {
        Rectangle head = body.get(0);

        // Check collision with walls
        if (head.x < 0 || head.x >= SnakeGame.WINDOW_WIDTH || head.y < 0 || head.y >= SnakeGame.WINDOW_HEIGHT) {
            return true;
        }

        // Check collision with itself
        for (int i = 1; i < body.size(); i++) {
            if (head.intersects(body.get(i))) {
                return true;
            }
        }

        return false;
    }

    public List<Rectangle> getBody() {
        return body;
    }
}

@Override
public void actionPerformed(ActionEvent e) {
    snake.move();

    // Check if the snake has eaten the food
    if (snake.getBody().get(0).intersects(food.getFood())) {
        snake.grow();
        food.generateNewFood();
    }

    // Check if the snake has collided with the walls or itself
    if (snake.checkCollision()) {
        timer.stop();
        JOptionPane.showMessageDialog(this, "Game Over", "Game Over", JOptionPane.INFORMATION_MESSAGE);
    }

    repaint();
}

				
			

Conclusion

Congratulations! You’ve successfully created a Classic Snake game using Java. This project covers essential game development concepts, including setting up a game window, handling user input, implementing a game loop, and detecting collisions. Feel free to enhance and customize your game by adding features like different levels, obstacles, or a scoring system. Happy coding😊!!

Related Articles

Sachin S Marnur

Sachin S Marnur

I am an Engineer and a passionate Web Developer and Blogger, who loves to share tips about Web Development, Blogging, SEO, Google Ranking and UI designing.