Skip to content

Commit 9fdf949

Browse files
authored
Add files via upload
1 parent beaa013 commit 9fdf949

6 files changed

Lines changed: 209 additions & 0 deletions

File tree

SnakeGame$GameCycle.class

695 Bytes
Binary file not shown.

SnakeGame$MyKeyAdapter.class

794 Bytes
Binary file not shown.

SnakeGame.class

3.42 KB
Binary file not shown.

SnakeGame.java

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
import javax.swing.*;
2+
import java.awt.*;
3+
import java.awt.event.ActionEvent;
4+
import java.awt.event.ActionListener;
5+
import java.awt.event.KeyAdapter;
6+
import java.awt.event.KeyEvent;
7+
8+
public class SnakeGame extends JFrame {
9+
private static final int WIDTH = 300;
10+
private static final int HEIGHT = 300;
11+
private static final int UNIT_SIZE = 10;
12+
private static final int GAME_UNITS = (WIDTH * HEIGHT) / UNIT_SIZE;
13+
private static final int DELAY = 140;
14+
15+
private final int[] x = new int[GAME_UNITS];
16+
private final int[] y = new int[GAME_UNITS];
17+
private int bodyParts = 3;
18+
private int applesEaten;
19+
private int appleX;
20+
private int appleY;
21+
private char direction = 'R';
22+
private boolean running = false;
23+
private Timer timer;
24+
25+
public SnakeGame() {
26+
setPreferredSize(new Dimension(WIDTH, HEIGHT));
27+
setBackground(Color.BLACK);
28+
setFocusable(true);
29+
addKeyListener(new MyKeyAdapter());
30+
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
31+
pack();
32+
setVisible(true);
33+
34+
startGame();
35+
}
36+
37+
private void startGame() {
38+
running = true;
39+
40+
// Spawn the snake in the middle of the screen
41+
x[0] = WIDTH / 2 / UNIT_SIZE * UNIT_SIZE;
42+
y[0] = HEIGHT / 2 / UNIT_SIZE * UNIT_SIZE;
43+
44+
placeApple();
45+
timer = new Timer(DELAY, new GameCycle());
46+
timer.start();
47+
}
48+
49+
private void placeApple() {
50+
boolean validPosition = false;
51+
52+
while (!validPosition) {
53+
appleX = (int) (Math.random() * ((WIDTH - UNIT_SIZE * 2) / UNIT_SIZE)) * UNIT_SIZE + UNIT_SIZE;
54+
appleY = (int) (Math.random() * ((HEIGHT - UNIT_SIZE * 2) / UNIT_SIZE)) * UNIT_SIZE + UNIT_SIZE;
55+
56+
// Ensure apple is not on the snake's body
57+
validPosition = true;
58+
for (int i = 0; i < bodyParts; i++) {
59+
if (appleX == x[i] && appleY == y[i]) {
60+
validPosition = false;
61+
break;
62+
}
63+
}
64+
}
65+
}
66+
67+
private void move() {
68+
for (int i = bodyParts; i > 0; i--) {
69+
x[i] = x[i - 1];
70+
y[i] = y[i - 1];
71+
}
72+
73+
switch (direction) {
74+
case 'U':
75+
y[0] = y[0] - UNIT_SIZE;
76+
break;
77+
case 'D':
78+
y[0] = y[0] + UNIT_SIZE;
79+
break;
80+
case 'L':
81+
x[0] = x[0] - UNIT_SIZE;
82+
break;
83+
case 'R':
84+
x[0] = x[0] + UNIT_SIZE;
85+
break;
86+
}
87+
}
88+
89+
private void checkApple() {
90+
if ((x[0] == appleX) && (y[0] == appleY)) {
91+
bodyParts++;
92+
applesEaten++;
93+
placeApple(); // Ensure apple is placed immediately after eating one
94+
}
95+
}
96+
97+
private void checkCollisions() {
98+
// Remove self-collision check
99+
if (x[0] < 0 || x[0] >= WIDTH || y[0] < 0 || y[0] >= HEIGHT) {
100+
running = false;
101+
timer.stop();
102+
}
103+
}
104+
105+
private void draw(Graphics g) {
106+
if (running) {
107+
g.setColor(Color.RED);
108+
g.fillOval(appleX, appleY, UNIT_SIZE, UNIT_SIZE);
109+
110+
for (int i = 0; i < bodyParts; i++) {
111+
if (i == 0) {
112+
g.setColor(Color.GREEN);
113+
} else {
114+
g.setColor(new Color(45, 180, 0));
115+
}
116+
g.fillRect(x[i], y[i], UNIT_SIZE, UNIT_SIZE);
117+
}
118+
} else {
119+
gameOver(g);
120+
}
121+
}
122+
123+
private void gameOver(Graphics g) {
124+
g.setColor(Color.RED);
125+
g.setFont(new Font("Helvetica", Font.BOLD, 40));
126+
FontMetrics metrics = getFontMetrics(g.getFont());
127+
g.drawString("Game Over", (WIDTH - metrics.stringWidth("Game Over")) / 2, HEIGHT / 2);
128+
129+
// Display the reason for the game over
130+
g.setFont(new Font("Helvetica", Font.BOLD, 20));
131+
String message = "You hit the wall!";
132+
g.drawString(message, (WIDTH - metrics.stringWidth(message)) / 2, HEIGHT / 2 + 30);
133+
}
134+
135+
private class GameCycle implements ActionListener {
136+
@Override
137+
public void actionPerformed(ActionEvent e) {
138+
if (running) {
139+
move();
140+
checkApple();
141+
checkCollisions();
142+
}
143+
repaint();
144+
}
145+
}
146+
147+
private class MyKeyAdapter extends KeyAdapter {
148+
@Override
149+
public void keyPressed(KeyEvent e) {
150+
switch (e.getKeyCode()) {
151+
case KeyEvent.VK_LEFT:
152+
case KeyEvent.VK_A:
153+
if (direction != 'R') {
154+
direction = 'L';
155+
}
156+
break;
157+
case KeyEvent.VK_RIGHT:
158+
case KeyEvent.VK_D:
159+
if (direction != 'L') {
160+
direction = 'R';
161+
}
162+
break;
163+
case KeyEvent.VK_UP:
164+
case KeyEvent.VK_W:
165+
if (direction != 'D') {
166+
direction = 'U';
167+
}
168+
break;
169+
case KeyEvent.VK_DOWN:
170+
case KeyEvent.VK_S:
171+
if (direction != 'U') {
172+
direction = 'D';
173+
}
174+
break;
175+
}
176+
}
177+
}
178+
179+
@Override
180+
public void paint(Graphics g) {
181+
super.paint(g);
182+
draw(g);
183+
}
184+
185+
public static void main(String[] args) {
186+
new SnakeGame();
187+
}
188+
}

build.xml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<project name="SnakeGame" basedir="." default="jar">
2+
<target name="clean">
3+
<delete dir="build"/>
4+
</target>
5+
6+
<target name="compile">
7+
<mkdir dir="build/classes"/>
8+
<javac srcdir="." destdir="build/classes"/>
9+
</target>
10+
11+
<target name="jar" depends="compile">
12+
<mkdir dir="build/jar"/>
13+
<jar destfile="build/jar/SnakeGame.jar" basedir="build/classes">
14+
<manifest>
15+
<attribute name="Main-Class" value="SnakeGame"/>
16+
</manifest>
17+
</jar>
18+
</target>
19+
</project>
20+

manifest.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Main-Class: SnakeGame

0 commit comments

Comments
 (0)