0% found this document useful (0 votes)
2 views7 pages

Java Snake Case Study

The document outlines a case study of a beginner-friendly Snake game implemented in Java using Swing/AWT, detailing its architecture, features, and game flow. It includes code snippets for the main application and game logic classes, along with explanations of key methods and functionalities. The conclusion highlights areas for improvement, such as better separation of concerns and the need for dynamic data structures.

Uploaded by

prawingaming
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views7 pages

Java Snake Case Study

The document outlines a case study of a beginner-friendly Snake game implemented in Java using Swing/AWT, detailing its architecture, features, and game flow. It includes code snippets for the main application and game logic classes, along with explanations of key methods and functionalities. The conclusion highlights areas for improvement, such as better separation of concerns and the need for dynamic data structures.

Uploaded by

prawingaming
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

# Title

**Java Snake Game (Swing) — Case Study**

---

# Introduction of the Game

A lightweight, beginner-friendly Snake game implemented in Java using **Swing/AWT**. The g

---

# About the Game

* Desktop (Swing) application.


* Grid-based movement (snake moves by fixed DOT_SIZE steps).
* Uses a Swing `Timer` for the game loop (actionPerformed → update → repaint).
* Two Java classes in `src/com/zetcode`: `Snake` (main JFrame) and `Board` (game logic + r

---

# Features of the Game

* Arrow-key controls (left/right/up/down) with direction-locking to avoid immediate revers


* Random placement of apples (food).
* Snake grows when it eats an apple.
* Collision detection: self-collision and wall collision → game over.
* Simple sprite rendering using `ImageIcon` and `[Link]`.
* Timer-driven deterministic update loop (DELAY). ([GitHub][2])

---

# Flowchart of the Game (ASCII)

```
[Start]

[Init UI + loadImages + initGame]

[Start Timer -> Game Loop]

[On Timer tick]

[1) process input (key adapter updates direction)]

[2) move snake body positions]

[3) check if apple eaten -> if yes increase dots + place new apple]

[4) check collisions (self/walls) -> if collision stop timer & set inGame=false]

[5) repaint() -> paintComponent() -> draw images or draw "Game Over"]

[Repeat until inGame == false]

[End]
```

(You can convert this to a UML activity diagram for the report.)

---
# Architecture (component-level)

* **UI Layer**: `Snake` (JFrame) — creates window and adds the `Board` JPanel.
* **Game Layer**: `Board` (JPanel) — contains game state arrays, logic for movement, colli
* **Event Layer**: `TAdapter` (inner class of `Board`) — keyboard events to change directi
* **Timing**: `[Link]` used to trigger repeated updates via `actionPerformed`.
* **Resources**: `src/resources/*` — images (`[Link]`, `[Link]`, `[Link]`) used in r

---

# Frontend and Backend Chart

(For a simple Swing game the distinction is conceptual: frontend == view + input; backend

| Layer |
| ---------------------------- | ---------------------------------------------------------
| Frontend (View + Input) | Window, re
| Backend (Game state & Logic) | Snake body array, apple coordinates, collision detection,

---

# Files in `src` (and explanation + code)

Below are the two Java source files in `src/com/zetcode` used by the repo. I present a rea

---

## 1) `[Link]`

**Purpose:** Application entry point — creates the main JFrame window and places the `Boar

**Code:**

```java
package [Link];

import [Link];
import [Link];

public class Snake extends JFrame {

public Snake() {
initUI();
}

private void initUI() {


add(new Board());
setResizable(false);
pack();
setTitle("Snake");
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

public static void main(String[] args) {


[Link](() -> {
JFrame ex = new Snake();
[Link](true);
});
}
}
```

**Explanation (short):**

* `main` schedules UI creation on the EDT (`[Link]`).


* The `Snake` frame adds a `Board` instance (the game canvas), disables resizing (so colli

**Source:** repository raw file. ([GitHub][1])

---

## 2) `[Link]`

**Purpose:** All game logic, rendering, key handling, timer, and resource loading. This cl

**Code (readable):**

```java
package [Link];

import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];

public class Board extends JPanel implements ActionListener {

private final int B_WIDTH = 300;


private final int B_HEIGHT = 300;
private final int DOT_SIZE = 10;
private final int ALL_DOTS = 900;
private final int RAND_POS = 29;
private final int DELAY = 140;

private final int x[] = new int[ALL_DOTS];


private final int y[] = new int[ALL_DOTS];

private int dots;


private int apple_x;
private int apple_y;

private boolean leftDirection = false;


private boolean rightDirection = true;
private boolean upDirection = false;
private boolean downDirection = false;
private boolean inGame = true;

private Timer timer;


private Image ball;
private Image apple;
private Image head;

public Board() {
initBoard();
}

private void initBoard() {


addKeyListener(new TAdapter());
setBackground([Link]);
setFocusable(true);
setPreferredSize(new Dimension(B_WIDTH, B_HEIGHT));
loadImages();
initGame();
}

private void loadImages() {


ImageIcon iid = new ImageIcon("src/resources/[Link]");
ball = [Link]();

ImageIcon iia = new ImageIcon("src/resources/[Link]");


apple = [Link]();

ImageIcon iih = new ImageIcon("src/resources/[Link]");


head = [Link]();
}

private void initGame() {


dots = 3;

for (int z = 0; z < dots; z++) {


x[z] = 50 - z * 10;
y[z] = 50;
}

locateApple();

timer = new Timer(DELAY, this);


[Link]();
}

@Override
public void paintComponent(Graphics g) {
[Link](g);
doDrawing(g);
}

private void doDrawing(Graphics g) {


if (inGame) {
[Link](apple, apple_x, apple_y, this);

for (int z = 0; z < dots; z++) {


if (z == 0) {
[Link](head, x[z], y[z], this);
} else {
[Link](ball, x[z], y[z], this);
}
}

[Link]().sync();
} else {
gameOver(g);
}
}

private void gameOver(Graphics g) {


String msg = "Game Over";
Font small = new Font("Helvetica", [Link], 14);
FontMetrics metr = getFontMetrics(small);

[Link]([Link]);
[Link](small);
[Link](msg, (B_WIDTH - [Link](msg)) / 2, B_HEIGHT / 2);
}

private void checkApple() {


if ((x[0] == apple_x) && (y[0] == apple_y)) {
dots++;
locateApple();
}
}

private void move() {


for (int z = dots; z > 0; z--) {
x[z] = x[(z - 1)];
y[z] = y[(z - 1)];
}

if (leftDirection) {
x[0] -= DOT_SIZE;
}
if (rightDirection) {
x[0] += DOT_SIZE;
}
if (upDirection) {
y[0] -= DOT_SIZE;
}
if (downDirection) {
y[0] += DOT_SIZE;
}
}

private void checkCollision() {


for (int z = dots; z > 0; z--) {
if ((z > 4) && (x[0] == x[z]) && (y[0] == y[z])) {
inGame = false;
}
}

if (y[0] >= B_HEIGHT) {


inGame = false;
}
if (y[0] < 0) {
inGame = false;
}
if (x[0] >= B_WIDTH) {
inGame = false;
}
if (x[0] < 0) {
inGame = false;
}

if (!inGame) {
[Link]();
}
}

private void locateApple() {


int r = (int) ([Link]() * RAND_POS);
apple_x = (r * DOT_SIZE);

r = (int) ([Link]() * RAND_POS);


apple_y = (r * DOT_SIZE);
}

@Override
public void actionPerformed(ActionEvent e) {
if (inGame) {
checkApple();
checkCollision();
move();
}

repaint();
}

private class TAdapter extends KeyAdapter {


@Override
public void keyPressed(KeyEvent e) {
int key = [Link]();

if ((key == KeyEvent.VK_LEFT) && (!rightDirection)) {


leftDirection = true;
upDirection = false;
downDirection = false;
}

if ((key == KeyEvent.VK_RIGHT) && (!leftDirection)) {


rightDirection = true;
upDirection = false;
downDirection = false;
}

if ((key == KeyEvent.VK_UP) && (!downDirection)) {


upDirection = true;
rightDirection = false;
leftDirection = false;
}

if ((key == KeyEvent.VK_DOWN) && (!upDirection)) {


downDirection = true;
rightDirection = false;
leftDirection = false;
}
}
}
}
```

**Explanation (short, focused on OOP):**

* `Board` encapsulates state arrays `x[], y[]` representing snake segment coordinates.
* `dots` stores current snake length (number of visible segments).
* Movement implemented by shifting array indices upward (`x[z] = x[z-1]`) — a common simpl
* Direction booleans encode the current direction; input handling sets them with reversal
* Collision logic uses coordinate equality checks (simple and deterministic).
* Rendering is immediate mode: `paintComponent` → `doDrawing` draws apple and snake parts
* `Timer` serves as the game loop driving `actionPerformed` updates at fixed DELAY.

**Source:** repository raw file. ([GitHub][2])

---

# Summary Table (quick reference)

| File | Role | Key methods/fields


| ----------------- | ---------------------- | -------------------------------------------
| `[Link]` | App entry / JFrame | `main`, `initUI()`
| `[Link]` | Game logic + rendering | `initGame()`, `move()`, `checkApple()`, `ch
| `resources/*.png` | Visual assets | `[Link]`, `[Link]`, `[Link]`

Sources: repo raw files and README/tutorial. ([GitHub][1])

---

# Output Explanation (what you see when you run it)

1. The application window titled **"Snake"** opens with a 300×300 black board.
2. A single apple image is drawn at a random grid coordinate (multiples of 10).
3. The snake (head image + body images) starts with length 3 at initial coordinates.
4. Arrow keys move the snake. On each Timer tick: input is read (via state booleans), `mov
5. On game over the string "Game Over" is centered in white. ([GitHub][2])

---

# Conclusion (critical, no-nonsense)

This implementation is intentionally minimal and educational — perfect for demonstrating c

* **Hard-coded magic numbers**: Board size, DOT_SIZE, RAND_POS, DELAY are constants in `Bo
* **Tight coupling to file paths**: `ImageIcon("src/resources/...")` expects a specific wo
* **Array-based snake with fixed max length** (`ALL_DOTS = 900`) — better to use dynamic `
* **No separation of model vs view**: `Board` mixes rendering and logic. For larger projec
* **No score tracking or restart mechanic**: No `score` field, no way to restart without r
* **Collision precision**: Uses exact equality of pixel coordinates; reliant on consistent
* **Input handling** relies on booleans and KeyAdapter; consider buffering direction chang

Include these critiques in your "Improvements" subsection — they show you can think beyond

---

# SDG Mapping

* **SDG 4 — Quality Education**: The project is a learning resource teaching programming,


* **SDG 9 — Industry, Innovation and Infrastructure**: Demonstrates software prototyping a

(Explain in your submission how this small educational repo supports learning and technica

You might also like