基于JavaFX的贪吃蛇小游戏

游戏背景介绍

贪吃蛇游戏是一款经典的小游戏,它的玩法很简单,就是控制蛇吃食物,每吃一个食物蛇的长度就会加一,直到蛇撞到墙壁或者撞到自己时游戏结束,最终的得分是蛇的长度减一。

JavaFX

用Java开发桌面端首选就是JavaFX,它的推出用来取代Swing(一个古老的Java桌面端框架)。

虽然都说Java开发桌面端性能不行,但是我们的Java开发工具IntelliJ IDEA的界面是由JavaFX构建的。最开始的我的世界(Minecraft)这款游戏是Java开发的,虽然没有使用Java标准GUI库(它自己的游戏引擎和自定义的用户界面),但也足以证明Java的魅力。

游戏规则

  • 初始时,蛇的长度为一,位于游戏界面的中心位置。
  • 每次随机生成一块食物,食物不能出现在蛇的身体上。
  • 蛇可以通过四个方向键上下左右移动,不能撞到墙壁或自己的身体。
  • 每吃一块食物,蛇的长度加一。
  • 穿过左边的墙壁,出现在右边;穿过上边的墙壁,出现在下面;反之亦然。
  • 游戏结束时,弹出得分对话框,点击重新开始新游戏。

代码结构

本教程主要涉及的代码文件是SnakeGame.java,整个代码文件的框架如下:

import java.util.ArrayDeque;
import java.util.Deque;
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class SnakeGame extends Application {

    // 游戏界面的宽度
    private static final int WIDTH = 20;

    // 游戏界面的高度
    private static final int HEIGHT = 20;

    // 每个格子的大小
    private static final int SIZE = 20;

    // 蛇的速度
    private static final int SPEED = 5;

    // 蛇的身体
    private Deque<Point> snake = new ArrayDeque<>();

    // 蛇的初始方向
    private Direction direction = Direction.RIGHT;

    // 食物的位置
    private Point food;

    // 游戏是否结束
    private boolean gameOver = false;

    // 游戏是否暂停
    private boolean gamePaused = false;

    @Override
    public void start(Stage primaryStage) throws Exception {
        // 界面初始化
        // ...

        // 初始化游戏
        // ...

        // 动画循环
        // ...
    }

    // 界面初始化方法
    private void initGUI() {
        // ...
    }

    // 初始化游戏方法
    private void initGame() {
        // ...
    }

    // 蛇的移动方法
    private void move() {
        // ...
    }

    // 检测碰撞方法
    private void checkCollision() {
        // ...
    }

    // 生成食物方法
    private void generateFood() {
        // ...
    }

    // 绘制游戏画面方法
    private void paint(GraphicsContext gc) {
        // ...
    }

    // 显示游戏结束对话框方法
    private void showGameOverDialog() {
        // ...
    }

    // 方向枚举类
    private enum Direction {
        UP, DOWN, LEFT, RIGHT
    }

    // 坐标点类
    private static class Point {
        private int x;
        private int y;

        public Point(int x, int y) {
            this.x = x;
            this.y = y;
        }

        public int getX() {
            return x;
        }

        public int getY() {
            return y;
        }

        @Override
        public boolean equals(Object o) {
            // ...
        }

        @Override
        public int hashCode() {
            // ...
        }
    }

    public static void main(String[] args) {
        launch(args);
    }

}

逻辑分析

在实现贪吃蛇游戏之前,我们需要先了解一下游戏的逻辑。

  • 在游戏界面内,不断地移动蛇的位置。
  • 蛇的移动方向可以通过键盘上的上下左右四个方向键来控制。
  • 当蛇头碰到边界或碰到自己的身体时,游戏结束。
  • 当蛇头碰到食物时,就会吃掉食物,长度加1,随后继续向前移动。
  • 吃掉食物后,会重新生成一个新的食物,判断新食物的位置是否和已有的蛇的位置冲突。

实现步骤

下面分步骤进行实现,每一个步骤都结合代码,逻辑清晰。

步骤1:界面初始化

start方法中进行界面的初始化,包括创建CanvasGraphicsContext等,并将Canvas添加到StackPane作为根节点,最后显示舞台。代码如下:

@Override
public void start(Stage primaryStage) throws Exception {
    // 创建Canvas
    Canvas canvas = new Canvas(WIDTH * SIZE, HEIGHT * SIZE);
    GraphicsContext gc = canvas.getGraphicsContext2D();

    // 创建根节点
    StackPane root = new StackPane(canvas);
    root.setAlignment(Pos.CENTER);

    // 创建场景
    Scene scene = new Scene(root);
    scene.setOnKeyPressed(event -> {
        KeyCode keyCode = event.getCode();
        switch (keyCode) {
            // ...
        }
    });

    // 显示舞台
    primaryStage.setScene(scene);
    primaryStage.setTitle("贪吃蛇游戏");
    primaryStage.setResizable(false);
    primaryStage.show();
}
步骤2:初始化游戏

在游戏开始前,需要初始化一些参数,包括蛇的位置、食物位置、游戏状态等。具体实现代码如下:

// 初始化游戏方法
private void initGame() {
    // 清空蛇的身体
    snake.clear();

    // 在游戏界面的中心生成蛇头
    int x = WIDTH / 2;
    int y = HEIGHT / 2;
    snake.add(new Point(x, y));

    // 生成食物
    generateFood();

    // 初始化游戏状态
    gameOver = false;
    gamePaused = false;
}
步骤3:蛇的移动

在游戏中,蛇可以通过键盘上的上下左右四个方向键来控制移动方向。我们可以在Scene的按键监听事件中实现,根据按下的方向键修改蛇的移动方向。具体代码实现如下:

// Scene的按键监听事件
scene.setOnKeyPressed(event -> {
    KeyCode keyCode = event.getCode();
    switch (keyCode) {
        case UP:
            if (direction != Direction.DOWN) {
                direction = Direction.UP;
            }
            break;
        case DOWN:
            if (direction != Direction.UP) {
                direction = Direction.DOWN;
            }
            break;
        case LEFT:
            if (direction != Direction.RIGHT) {
                direction = Direction.LEFT;
            }
            break;
        case RIGHT:
            if (direction != Direction.LEFT) {
                direction = Direction.RIGHT;
            }
            break;
        case P:
            gamePaused = !gamePaused;
            break;
        case R:
            initGame();
            break;
        default:
            break;
    }
});

在每次动画循环中,根据蛇的移动方向来计算移动后的新位置。如果新位置在蛇的身体上或者超出了边界,就说明游戏结束了。判断蛇是否吃到了食物,如果吃到了就让蛇的身体变长,并在新位置生成一个新的食物。

// 蛇的移动方法
private void move() {
    Point head = snake.getFirst();
    Point newHead = null;
    switch (direction) {
        case UP:
            newHead = new Point(head.getX(), head.getY() - 1);
            break;
        case DOWN:
            newHead = new Point(head.getX(), head.getY() + 1);
            break;
        case LEFT:
            newHead = new Point(head.getX() - 1, head.getY());
            break;
        case RIGHT:
            newHead = new Point(head.getX() + 1, head.getY());
            break;
        default:
            break;
    }

    // 判断是否撞到自己的身体
    if (snake.contains(newHead)) {
        gameOver = true;
        showGameOverDialog();
        return;
    }

    // 判断是否撞到墙壁
    if (newHead.getX() < 0 || newHead.getX() >= WIDTH ||
            newHead.getY() < 0 || newHead.getY() >= HEIGHT) {
        gameOver = true;
        showGameOverDialog();
        return;
    }

    // 更新蛇的位置
    snake.addFirst(newHead);

    // 判断是否吃到了食物
    if (newHead.equals(food)) {
        // 如果吃到了食物,就让蛇的身体变长
        generateFood();
    } else {
        // 如果没有吃到食物,就让蛇的尾巴消失
        snake.removeLast();
    }
}
步骤4:检测碰撞

在每次蛇的移动后,需要检测蛇是否撞到了自己的身体。如果撞到了,说明游戏结束了。具体代码实现如下:

// 检测碰撞方法
private void checkCollision() {
    Point head = snake.getFirst();
    for (Point point : snake) {
        if (point != head && point.equals(head)) {
            gameOver = true;
            showGameOverDialog();
            break;
        }
    }
}
步骤5:生成食物

每个食物都是在游戏界面上随机出现的,食物不能出现在蛇的身体上。生成食物时,可以使用do-while循环来判断是否有重合的情况。具体代码实现如下:

// 生成食物方法
private void generateFood() {
    boolean validPosition;
    int x, y;
    do {
        validPosition = true;
        x = (int) (Math.random() * WIDTH);
        y = (int) (Math.random() * HEIGHT);
        for (Point point : snake) {
            if (point.getX() == x && point.getY() == y) {
                validPosition = false;
                break;
            }
        }
    } while (!validPosition);
    food = new Point(x, y);
}
步骤6:绘制游戏画面

Canvas上通过GraphicsContext绘制蛇、食物等游戏元素,实现游戏的画面。具体代码实现如下:

// 绘制游戏画面方法
private void paint(GraphicsContext gc) {
    // 清空画布
    gc.clearRect(0, 0, WIDTH * SIZE, HEIGHT * SIZE);

    // 绘制蛇身
    gc.setFill(javafx.scene.paint.Color.GREEN);
    for (Point point : snake) {
        gc.fillRect(point.getX() * SIZE, point.getY() * SIZE, SIZE, SIZE);
    }

    // 绘制头部
    gc.setFill(javafx.scene.paint.Color.DARKGREEN);
    Point head = snake.getFirst();
    gc.fillRect(head.getX() * SIZE, head.getY() * SIZE, SIZE, SIZE);

    // 绘制食物
    gc.setFill(javafx.scene.paint.Color.RED);
    gc.fillRect(food.getX() * SIZE, food.getY() * SIZE, SIZE, SIZE);
}
步骤7:显示游戏结束对话框

当游戏结束时,弹出得分对话框,点击重新开始新游戏。具体代码实现如下:

// 显示游戏结束对话框方法
private void showGameOverDialog() {
    Alert alert = new Alert(AlertType.INFORMATION);
    alert.setTitle("游戏结束");
    alert.setHeaderText(null);
    alert.setContentText("游戏结束,您的得分是:" + (snake.size() - 1));
    alert.show();

    alert.setOnHidden(event -> {
        initGame();
    });
}

至此,贪吃蛇游戏的实现已经完成了。

完整代码如下:

package org.example;

import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

import java.util.ArrayDeque;
import java.util.Deque;

public class SnakeGame extends Application {

    private static final int WIDTH = 20; // 游戏界面的宽度
    private static final int HEIGHT = 20; // 游戏界面的高度
    private static final int SIZE = 20; // 每个格子的大小
    private static final int SPEED = 5; // 蛇的速度

    private Deque<Point> snake = new ArrayDeque<>(); // 蛇的身体
    private Direction direction = Direction.RIGHT; // 蛇的初始方向

    private Point food; // 食物的位置

    private boolean gameOver = false; // 游戏是否结束
    private boolean gamePaused = false; // 游戏是否暂停

    @Override
    public void start(Stage primaryStage) throws Exception {
        Canvas canvas = new Canvas(WIDTH * SIZE, HEIGHT * SIZE);
        GraphicsContext gc = canvas.getGraphicsContext2D();
        StackPane root = new StackPane(canvas);
        root.setAlignment(Pos.CENTER);

        Scene scene = new Scene(root);
        scene.setOnKeyPressed(event -> {
            KeyCode keyCode = event.getCode();
            switch (keyCode) {
                case UP:
                    if (direction != Direction.DOWN) {
                        direction = Direction.UP;
                    }
                    break;
                case DOWN:
                    if (direction != Direction.UP) {
                        direction = Direction.DOWN;
                    }
                    break;
                case LEFT:
                    if (direction != Direction.RIGHT) {
                        direction = Direction.LEFT;
                    }
                    break;
                case RIGHT:
                    if (direction != Direction.LEFT) {
                        direction = Direction.RIGHT;
                    }
                    break;
                case P:
                    gamePaused = !gamePaused;
                    break;
                case R:
                    initGame();
                    break;
                default:
                    break;
            }
        });

        primaryStage.setScene(scene);
        primaryStage.setTitle("贪吃蛇游戏");
        primaryStage.setResizable(false);
        primaryStage.show();

        initGame();

        new AnimationTimer() {
            private long lastUpdateTime;

            @Override
            public void handle(long now) {
                if (now - lastUpdateTime >= 1_000_000_000 / SPEED) { // 调整蛇的速度
                    lastUpdateTime = now;
                    if (!gameOver && !gamePaused) {
                        move();
                        checkCollision();
                        paint(gc);
                    }
                }
            }
        }.start();
    }

    // 初始化游戏
    private void initGame() {
        snake.clear();
        snake.add(new Point(WIDTH / 2, HEIGHT / 2));
        generateFood();
        gameOver = false;
        gamePaused = false;
    }

    // 蛇的移动
    private void move() {
        Point head = snake.getFirst();
        Point newHead = null;
        switch (direction) {
            case UP:
                newHead = new Point(head.getX(), head.getY() - 1);
                break;
            case DOWN:
                newHead = new Point(head.getX(), head.getY() + 1);
                break;
            case LEFT:
                newHead = new Point(head.getX() - 1, head.getY());
                break;
            case RIGHT:
                newHead = new Point(head.getX() + 1, head.getY());
                break;
            default:
                break;
        }
        // 判断是否撞到自己的身体
        if (snake.contains(newHead)) {
            gameOver = true;
            showGameOverDialog();
            return;
        }
        // 判断是否撞到墙壁
        if (newHead.getX() < 0 || newHead.getX() >= WIDTH ||
                newHead.getY() < 0 || newHead.getY() >= HEIGHT) {
            gameOver = true;
            showGameOverDialog();
            return;
        }
        snake.addFirst(newHead);
        if (newHead.equals(food)) {
            generateFood();
        } else {
            snake.removeLast();
        }
    }

    // 检测碰撞
    private void checkCollision() {
        Point head = snake.getFirst();
        for (Point point : snake) {
            if (point != head && point.equals(head)) {
                gameOver = true;
                showGameOverDialog();
                break;
            }
        }
    }

    // 生成食物
    private void generateFood() {
        boolean validPosition;
        int x, y;
        do {
            validPosition = true;
            x = (int) (Math.random() * WIDTH);
            y = (int) (Math.random() * HEIGHT);
            for (Point point : snake) {
                if (point.getX() == x && point.getY() == y) {
                    validPosition = false;
                    break;
                }
            }
        } while (!validPosition);
        food = new Point(x, y);
    }

    // 绘制游戏画面
    private void paint(GraphicsContext gc) {
        // 清空画布
        gc.clearRect(0, 0, WIDTH * SIZE, HEIGHT * SIZE);

        // 绘制蛇身
        gc.setFill(javafx.scene.paint.Color.GREEN);
        for (Point point : snake) {
            gc.fillRect(point.getX() * SIZE, point.getY() * SIZE, SIZE, SIZE);
        }

        // 绘制头部
        gc.setFill(javafx.scene.paint.Color.DARKGREEN);
        Point head = snake.getFirst();
        gc.fillRect(head.getX() * SIZE, head.getY() * SIZE, SIZE, SIZE);

        // 绘制食物
        gc.setFill(javafx.scene.paint.Color.RED);
        gc.fillRect(food.getX() * SIZE, food.getY() * SIZE, SIZE, SIZE);
    }

    // 显示游戏结束对话框
    private void showGameOverDialog() {
        Alert alert = new Alert(AlertType.INFORMATION);
        alert.setTitle("游戏结束");
        alert.setHeaderText(null);
        alert.setContentText("游戏结束,您的得分是:" + (snake.size() - 1));
        alert.show();

        alert.setOnHidden(event -> {
            initGame(); // 游戏结束后重新开始游戏
        });
    }

    // 方向枚举类
    private enum Direction {
        UP, DOWN, LEFT, RIGHT
    }

    // 坐标点类
    private static class Point {
        private int x;
        private int y;

        public Point(int x, int y) {
            this.x = x;
            this.y = y;
        }

        public int getX() {
            return x;
        }

        public int getY() {
            return y;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Point point = (Point) o;
            return x == point.x && y == point.y;
        }

        @Override
        public int hashCode() {
            return x * 31 + y;
        }
    }

    public static void main(String[] args) {
        launch(args);
    }

}

关注微信公众号:“小虎哥的技术博客”。我们会定期发布关于Java技术的详尽文章,让您能够深入了解该领域的各种技巧和方法,让我们一起成为更优秀的程序员👩‍💻👨‍💻!

相关文章源码放在:gitee仓库github仓库上。

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。
JavaFX 是一种基于 Java 的图形用户界面(GUI)框架,可以用来开发跨平台的应用程序。在 JavaFX 中,可以使用 Canvas 组件来绘制 2D 图形,我们可以利用这个组件来实现贪吃蛇游戏。 下面是一个简单的贪吃蛇游戏实现的示例代码: ```java import javafx.animation.Animation; import javafx.animation.KeyFrame; import javafx.animation.Timeline; import javafx.application.Application; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.geometry.Pos; import javafx.scene.Scene; import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; import javafx.scene.control.Label; import javafx.scene.input.KeyCode; import javafx.scene.layout.BorderPane; import javafx.scene.layout.VBox; import javafx.scene.paint.Color; import javafx.scene.text.Font; import javafx.stage.Stage; import javafx.util.Duration; public class SnakeGame extends Application { // 游戏界面的宽度和高度 private static final int GAME_WIDTH = 500; private static final int GAME_HEIGHT = 500; // 贪吃蛇的移动速度 private static final int SNAKE_SPEED = 5; // 贪吃蛇的初始长度 private static final int SNAKE_LENGTH = 5; // 贪吃蛇的方向 private enum Direction { UP, DOWN, LEFT, RIGHT } // 贪吃蛇的身体组成,每个节点包含 x,y 坐标 private class Body { public int x; public int y; public Body(int x, int y) { this.x = x; this.y = y; } } // 贪吃蛇的当前方向 private Direction direction = Direction.RIGHT; // 贪吃蛇的身体 private Body[] body = new Body[SNAKE_LENGTH]; // 食物的位置 private int foodX; private int foodY; // 游戏是否结束 private boolean gameOver = false; // 分数显示标签 private Label scoreLabel; // 当前分数 private int score = 0; // 游戏界面的 Canvas 组件 private Canvas canvas; // 游戏界面的 GraphicsContext 对象,用来绘制图形 private GraphicsContext gc; @Override public void start(Stage primaryStage) throws Exception { // 初始化游戏界面 BorderPane root = new BorderPane(); // 创建游戏界面的 Canvas 组件 canvas = new Canvas(GAME_WIDTH, GAME_HEIGHT); gc = canvas.getGraphicsContext2D(); // 创建分数显示标签 scoreLabel = new Label("Score: " + score); scoreLabel.setFont(new Font("Arial", 20)); scoreLabel.setTextFill(Color.WHITE); // 将 Canvas 组件和分数显示标签添加到界面中 VBox vbox = new VBox(); vbox.setAlignment(Pos.CENTER); vbox.getChildren().addAll(canvas, scoreLabel); root.setCenter(vbox); // 初始化贪吃蛇的身体 for (int i = 0; i < SNAKE_LENGTH; i++) { body[i] = new Body(SNAKE_LENGTH - i, 1); } // 在界面中随机生成食物 generateFood(); // 每隔一段时间更新游戏界面 Timeline timeline = new Timeline(new KeyFrame(Duration.millis(1000 / 60), new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { // 清空画布 gc.setFill(Color.BLACK); gc.fillRect(0, 0, GAME_WIDTH, GAME_HEIGHT); // 绘制食物 gc.setFill(Color.RED); gc.fillOval(foodX * SNAKE_SPEED, foodY * SNAKE_SPEED, SNAKE_SPEED, SNAKE_SPEED); // 更新贪吃蛇的身体 updateBody(); // 绘制贪吃蛇的头部 gc.setFill(Color.GREEN); gc.fillOval(body[0].x * SNAKE_SPEED, body[0].y * SNAKE_SPEED, SNAKE_SPEED, SNAKE_SPEED); // 绘制贪吃蛇的身体 gc.setFill(Color.LIGHTGREEN); for (int i = 1; i < body.length; i++) { gc.fillOval(body[i].x * SNAKE_SPEED, body[i].y * SNAKE_SPEED, SNAKE_SPEED, SNAKE_SPEED); } // 判断是否撞到边界或者自己的身体 if (body[0].x < 0 || body[0].x >= GAME_WIDTH / SNAKE_SPEED || body[0].y < 0 || body[0].y >= GAME_HEIGHT / SNAKE_SPEED) { gameOver = true; } for (int i = 1; i < body.length; i++) { if (body[0].x == body[i].x && body[0].y == body[i].y) { gameOver = true; } } // 判断是否吃到了食物 if (body[0].x == foodX && body[0].y == foodY) { score += 10; scoreLabel.setText("Score: " + score); generateFood(); addBody(); } // 如果游戏结束,停止更新界面 if (gameOver) { timeline.stop(); } } })); timeline.setCycleCount(Animation.INDEFINITE); timeline.play(); // 处理键盘事件,控制贪吃蛇的方向 canvas.setOnKeyPressed(event -> { if (event.getCode() == KeyCode.UP && direction != Direction.DOWN) { direction = Direction.UP; } else if (event.getCode() == KeyCode.DOWN && direction != Direction.UP) { direction = Direction.DOWN; } else if (event.getCode() == KeyCode.LEFT && direction != Direction.RIGHT) { direction = Direction.LEFT; } else if (event.getCode() == KeyCode.RIGHT && direction != Direction.LEFT) { direction = Direction.RIGHT; } }); // 显示界面 Scene scene = new Scene(root); primaryStage.setScene(scene); primaryStage.setTitle("Snake Game"); primaryStage.show(); } // 生成随机食物 private void generateFood() { foodX = (int) (Math.random() * (GAME_WIDTH / SNAKE_SPEED)); foodY = (int) (Math.random() * (GAME_HEIGHT / SNAKE_SPEED)); } // 添加贪吃蛇的身体 private void addBody() { Body[] newBody = new Body[body.length + 1]; System.arraycopy(body, 0, newBody, 0, body.length); newBody[newBody.length - 1] = new Body(body[body.length - 1].x, body[body.length - 1].y); body = newBody; } // 更新贪吃蛇的身体 private void updateBody() { for (int i = body.length - 1; i > 0; i--) { body[i].x = body[i - 1].x; body[i].y = body[i - 1].y; } switch (direction) { case UP: body[0].y--; break; case DOWN: body[0].y++; break; case LEFT: body[0].x--; break; case RIGHT: body[0].x++; break; } } public static void main(String[] args) { launch(args); } } ``` 在这个实现中,我们使用了 JavaFX 中的 Canvas 组件来绘制游戏界面。我们通过 Timeline 来更新游戏界面,每隔一段时间更新一次。我们使用了一个 Body 类来表示贪吃蛇的身体节点,使用一个 Body 数组来保存贪吃蛇的身体。我们使用了一个 Direction 枚举类型来表示贪吃蛇的方向,通过处理键盘事件来控制贪吃蛇的移动方向。在游戏中,如果贪吃蛇撞到了边界或者自己的身体,游戏结束;如果贪吃蛇吃到了食物,分数加 10,同时在界面中随机生成新的食物,并且添加一个身体节点。 这只是一个简单的实现示例,你可以根据自己的需要对其进行修改和扩展。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小虎哥的技术博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值