java编写一个贪吃蛇小游戏,具有存档功能和难度调整功能
时间: 2023-12-03 13:42:03 浏览: 36
这是一个简单的Java贪吃蛇小游戏示例,具有存档和难度调整功能。在游戏中,玩家通过控制蛇的移动来吃食物并获得分数,蛇的长度会随着吃下的食物增加而增加,如果蛇头碰到了墙壁或者自己的身体,则游戏结束。
```java
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.Timer;
public class SnakeGame extends JPanel implements ActionListener, KeyListener {
private static final long serialVersionUID = 1L;
// 游戏界面的大小
private static final int WIDTH = 600;
private static final int HEIGHT = 600;
// 蛇的初始长度
private static final int INITIAL_SNAKE_LENGTH = 5;
// 蛇头的位置
private Point head;
// 蛇的身体
private ArrayList<Point> body;
// 食物的位置
private Point food;
// 游戏的分数
private int score;
// 游戏的速度
private int speed;
// 游戏的难度
private int difficulty;
// 游戏是否结束
private boolean gameOver;
// 游戏是否在运行
private boolean running;
// 游戏的计时器
private Timer timer;
public SnakeGame() {
setPreferredSize(new Dimension(WIDTH, HEIGHT));
setBackground(Color.BLACK);
setFocusable(true);
addKeyListener(this);
// 初始化游戏
initGame();
}
// 初始化游戏
private void initGame() {
head = new Point(WIDTH / 2, HEIGHT / 2);
body = new ArrayList<Point>();
for (int i = 0; i < INITIAL_SNAKE_LENGTH; i++) {
body.add(new Point(head.x - i * 20, head.y));
}
food = new Point();
generateFood();
score = 0;
speed = 150;
difficulty = 1;
gameOver = false;
running = false;
timer = new Timer(speed, this);
timer.stop();
}
// 生成食物的位置
private void generateFood() {
Random random = new Random();
int x = random.nextInt(WIDTH / 20) * 20;
int y = random.nextInt(HEIGHT / 20) * 20;
food.setLocation(x, y);
}
// 保存游戏
private void saveGame() {
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("snake.sav")))) {
oos.writeObject(head);
oos.writeObject(body);
oos.writeObject(food);
oos.writeInt(score);
oos.writeInt(speed);
oos.writeInt(difficulty);
oos.flush();
System.out.println("Game saved.");
} catch (IOException e) {
e.printStackTrace();
}
}
// 加载游戏
private void loadGame() {
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("snake.sav")))) {
head = (Point) ois.readObject();
body = (ArrayList<Point>) ois.readObject();
food = (Point) ois.readObject();
score = ois.readInt();
speed = ois.readInt();
difficulty = ois.readInt();
System.out.println("Game loaded.");
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
// 开始游戏
public void startGame() {
running = true;
timer.start();
}
// 结束游戏
private void endGame() {
running = false;
gameOver = true;
timer.stop();
JOptionPane.showMessageDialog(this, "Game Over! Your score is " + score + ".", "Game Over",
JOptionPane.INFORMATION_MESSAGE);
initGame();
}
@Override
public void actionPerformed(ActionEvent e) {
if (!gameOver) {
// 移动蛇的身体
for (int i = body.size() - 1; i > 0; i--) {
body.get(i).setLocation(body.get(i - 1));
}
// 移动蛇的头
if (head.x == food.x && head.y == food.y) {
body.add(new Point(head));
generateFood();
score += 10 * difficulty;
}
if (head.x < 0 || head.x >= WIDTH || head.y < 0 || head.y >= HEIGHT) {
endGame();
} else {
for (int i = 1; i < body.size(); i++) {
if (head.x == body.get(i).x && head.y == body.get(i).y) {
endGame();
}
}
}
if (!gameOver) {
switch (difficulty) {
case 1:
speed = 150;
break;
case 2:
speed = 100;
break;
case 3:
speed = 50;
break;
}
timer.setDelay(speed);
switch (direction) {
case KeyEvent.VK_LEFT:
head.translate(-20, 0);
break;
case KeyEvent.VK_RIGHT:
head.translate(20, 0);
break;
case KeyEvent.VK_UP:
head.translate(0, -20);
break;
case KeyEvent.VK_DOWN:
head.translate(0, 20);
break;
}
}
repaint();
}
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.WHITE);
g.setFont(new Font("Arial", Font.BOLD, 20));
g.drawString("Score: " + score, 10, 30);
g.drawString("Difficulty: " + difficulty, 400, 30);
g.setColor(Color.GREEN);
g.fillRect(food.x, food.y, 20, 20);
g.setColor(Color.WHITE);
for (Point p : body) {
g.fillRect(p.x, p.y, 20, 20);
}
if (gameOver) {
g.setFont(new Font("Arial", Font.BOLD, 40));
g.drawString("Game Over", WIDTH / 2 - 100, HEIGHT / 2 - 20);
}
}
private int direction;
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_LEFT || keyCode == KeyEvent.VK_RIGHT || keyCode == KeyEvent.VK_UP
|| keyCode == KeyEvent.VK_DOWN) {
if (direction == 0 || direction != keyCode - 2 && direction != keyCode + 2) {
direction = keyCode;
}
} else if (keyCode == KeyEvent.VK_SPACE) {
if (running) {
timer.stop();
running = false;
} else {
timer.start();
running = true;
}
} else if (keyCode == KeyEvent.VK_S) {
saveGame();
} else if (keyCode == KeyEvent.VK_L) {
loadGame();
} else if (keyCode == KeyEvent.VK_1) {
difficulty = 1;
} else if (keyCode == KeyEvent.VK_2) {
difficulty = 2;
} else if (keyCode == KeyEvent.VK_3) {
difficulty = 3;
}
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyTyped(KeyEvent e) {
}
public static void main(String[] args) {
JFrame frame = new JFrame("Snake Game");
SnakeGame game = new SnakeGame();
frame.getContentPane().add(game);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
game.startGame();
}
}
```
该游戏具有以下功能:
- 初始化游戏:在游戏开始前,创建蛇的初始状态、食物的位置、分数、速度、难度等状态。
- 生成食物:随机生成食物的位置。
- 保存游戏:在游戏进行中,可以按下“S”键保存游戏状态。
- 加载游戏:在游戏开始前,可以按下“L”键加载游戏状态。
- 开始游戏:在游戏开始前,可以调用startGame()方法开始游戏。
- 结束游戏:在游戏结束时,弹出对话框显示分数,并初始化游戏状态。
- 移动蛇的身体:在每一次计时器事件中,更新蛇的身体位置。
- 移动蛇的头:在每一次计时器事件中,根据方向更新蛇头位置。
- 判断游戏是否结束:在每一次计时器事件中,判断蛇是否碰到墙壁或者自己的身体。
- 保存游戏:在游戏进行中,可以按下“S”键保存游戏状态。
- 加载游戏:在游戏开始前,可以按下“L”键加载游戏状态。
- 调整难度:在游戏进行中,可以按下“1”、“2”、“3”键调整游戏难度。
在这个示例中,我们使用了Java的面向对象特性,将游戏界面封装为一个JPanel,通过添加KeyListener来监听用户的输入,使用Timer来控制游戏的运行。同时,我们还使用了Java的序列化机制来保存和加载游戏状态,实现了游戏的存档功能。