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!
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.
- 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.”
- 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 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 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 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 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😊!!
5 thoughts on “Designing a Classic Snake Game Using Java”