赞
踩
设计一个贪吃蛇游戏,我们应当遵循了一系列步骤来确保游戏的基本功能:蛇的移动、吃苹果、游戏结束判断、以及重新开始游戏。以下是设计思路的分步总结.
JFrame
和JPanel
创建游戏窗口和绘图面板。paintComponent
方法:使用Graphics
对象绘制蛇、苹果和游戏结束时的提示信息。javax.swing.Timer
用于控制游戏的更新频率,每个时间间隔都会重绘界面并更新游戏状态。KeyListener
接口,根据用户的按键输入改变蛇的移动方向。ActionListener
,在游戏结束时显示按钮,并在点击时重置游戏状态。Timer
)来控制游戏逻辑的周期性执行,这涉及到Java的并发编程。在贪吃蛇游戏中,最主要的两个功能是蛇的移动和游戏状态的管理(包括吃苹果和碰撞检测)。这两个功能是游戏运行的核心,决定了游戏的基本玩法和用户体验。
蛇的移动是贪吃蛇游戏的基础。玩家通过控制蛇的移动来吃苹果,游戏的乐趣和挑战性主要来自于如何控制蛇的移动路径和速度。
实现思路:
游戏状态的管理决定了游戏的进程和结束条件。它包括检测蛇是否吃到苹果以增长身体,以及蛇是否撞到自己或游戏边界导致游戏结束。
实现思路:
这两个功能的实现是构建一个可玩的贪吃蛇游戏的关键。它们不仅涉及到游戏的基本逻辑和用户交互,还需要考虑如何在界面上有效地反映游戏状态的变化,提供流畅和有趣的游戏体验。
- 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 checkApple() {
- if ((x[0] == apple_x) && (y[0] == apple_y)) {
- dots++;
- locateApple();
- }
- }
- 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] >= HEIGHT) {
- inGame = false;
- }
-
- if (y[0] < 0) {
- inGame = false;
- }
-
- if (x[0] >= WIDTH) {
- inGame = false;
- }
-
- if (x[0] < 0) {
- inGame = false;
- }
-
- if (!inGame) {
- timer.stop();
- }
- }
- import javax.swing.*;
- import java.awt.*;
- import java.awt.event.ActionEvent;
- import java.awt.event.ActionListener;
- import java.awt.event.KeyEvent;
- import java.awt.event.KeyListener;
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.Random;
-
- public class SnakeGame extends JPanel implements KeyListener, ActionListener {
-
- private final int WIDTH = 300;
- private final int HEIGHT = 300;
- private final int DOT_SIZE = 10;
- private final int ALL_DOTS = 900;
- private final int RANDOM_POSITION = 29;
- private final int DELAY = 140;
- private final int x[] = new int[ALL_DOTS];
- private final int y[] = new int[ALL_DOTS];
- // 在SnakeGame类中添加
- private JButton restartButton;
- 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 boolean paused = false;
-
- private Timer timer;
- private Random random;
-
- private ArrayList<Integer> highScores = new ArrayList<>();
-
- public SnakeGame() {
- initBoard();
- }
-
- private void initBoard() {
- restartButton = new JButton("Restart");
- restartButton.setBounds(WIDTH / 2 - 50, HEIGHT / 2, 100, 30);
- restartButton.addActionListener(this);
- restartButton.setFocusable(false);
- restartButton.setVisible(false); // 初始时不显示按钮
- this.add(restartButton);
- addKeyListener(this);
- setBackground(Color.black);
- setFocusable(true);
- setPreferredSize(new Dimension(WIDTH, HEIGHT));
- initGame();
- }
-
- 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);
- timer.start();
- }
-
- private void restartGame() {
- dots = 3;
- for (int z = 0; z < dots; z++) {
- x[z] = 50 - z * 10;
- y[z] = 50;
- }
- rightDirection = true;
- leftDirection = false;
- upDirection = false;
- downDirection = false;
- inGame = true;
- restartButton.setVisible(false); // 重置游戏时隐藏按钮
- timer.start(); // 重新开始计时
- locateApple(); // 重新放置苹果
- }
-
- public void paintComponent(Graphics g) {
- super.paintComponent(g);
- doDrawing(g);
- }
-
- private void doDrawing(Graphics g) {
- if (inGame) {
- g.setColor(Color.red);
- g.fillOval(apple_x, apple_y, DOT_SIZE, DOT_SIZE);
-
- for (int z = 0; z < dots; z++) {
- if (z == 0) {
- g.setColor(Color.green);
- g.fillRect(x[z], y[z], DOT_SIZE, DOT_SIZE);
- } else {
- g.setColor(new Color(45, 180, 0));
- g.fillRect(x[z], y[z], DOT_SIZE, DOT_SIZE);
- }
- }
- Toolkit.getDefaultToolkit().sync();
- } else {
- gameOver(g);
- }
- }
-
- private void gameOver(Graphics g) {
- String msg = "Game Over";
- Font small = new Font("Helvetica", Font.BOLD, 14);
- FontMetrics metr = getFontMetrics(small);
-
- g.setColor(Color.white);
- g.setFont(small);
- g.drawString(msg, (WIDTH - metr.stringWidth(msg)) / 2, HEIGHT / 2);
-
- checkHighScore();
- displayHighScores(g);
- restartButton.setVisible(true); // 显示重新开始按钮
- }
-
- private void checkHighScore() {
- highScores.add(dots);
- Collections.sort(highScores, Collections.reverseOrder());
-
- while (highScores.size() > 3) {
- highScores.remove(highScores.size() - 1);
- }
- }
-
- private void displayHighScores(Graphics g) {
- g.drawString("High Scores:", 100, HEIGHT / 2 + 50);
- for (int i = 0; i < highScores.size(); i++) {
- g.drawString((i + 1) + ". " + highScores.get(i), 100, HEIGHT / 2 + 65 + i * 15);
- }
- }
-
- 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] >= HEIGHT) {
- inGame = false;
- }
-
- if (y[0] < 0) {
- inGame = false;
- }
-
- if (x[0] >= WIDTH) {
- inGame = false;
- }
-
- if (x[0] < 0) {
- inGame = false;
- }
-
- if (!inGame) {
- timer.stop();
- }
- }
-
- private void locateApple() {
- int r = (int) (Math.random() * RANDOM_POSITION);
- apple_x = ((r * DOT_SIZE));
-
- r = (int) (Math.random() * RANDOM_POSITION);
- apple_y = ((r * DOT_SIZE));
- }
-
- @Override
- public void actionPerformed(ActionEvent e) {
- if (inGame) {
- checkApple();
- checkCollision();
- move();
- } else if (e.getSource() == restartButton) {
- restartGame();
- }
- repaint();
- }
-
- @Override
- public void keyPressed(KeyEvent e) {
- int key = e.getKeyCode();
-
- 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;
- }
-
- if (key == KeyEvent.VK_P) {
- paused = !paused;
- if (paused) {
- timer.stop();
- } else {
- timer.start();
- }
- }
- }
-
- @Override
- public void keyReleased(KeyEvent e) {
- }
-
- @Override
- public void keyTyped(KeyEvent e) {
- }
-
- public static void main(String[] args) {
- SwingUtilities.invokeLater(() -> {
- JFrame frame = new JFrame("Snake Game");
- frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- frame.add(new SnakeGame());
- frame.pack();
- frame.setResizable(false);
- frame.setVisible(true);
- frame.setLocationRelativeTo(null);
- });
- }
- }
-
本文提供了一个贪吃蛇游戏的完整Java实现,包括游戏设计思路、关键功能的实现方法、以及完整的代码。游戏使用Java Swing库构建图形用户界面,通过面向对象编程、事件驱动编程、图形用户界面(GUI)设计、以及多线程和并发控制,实现了一个基本但功能完整的贪吃蛇游戏。游戏的核心功能包括蛇的移动、吃苹果、碰撞检测、游戏状态管理、以及游戏的重新开始功能。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。