javafx实现贪吃蛇游戏
时间: 2023-07-11 20:03:16 浏览: 128
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,同时在界面中随机生成新的食物,并且添加一个身体节点。
这只是一个简单的实现示例,你可以根据自己的需要对其进行修改和扩展。
阅读全文