type
status
date
slug
summary
tags
category
icon
password

🐍 最终效果和源码


snake game
snake game

主要功能


  1. 计分功能;
  1. 简单、适中、困难模式:
    1. 通过键盘1,2,3控制;
  1. SPACE键控制暂停或者重新开始;

源码


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.Label; import javafx.scene.input.KeyCode; import javafx.scene.layout.BorderPane; import javafx.scene.layout.HBox; import javafx.scene.paint.Color; import javafx.scene.text.Font; import javafx.stage.Stage; import java.util.ArrayList; import java.util.List; import java.util.Random; public class SnakeGame extends Application { private static final int TILE_SIZE = 20; private static final int WIDTH = 20; private static final int HEIGHT = 20; private static final double INITIAL_SPEED = 0.1; private static final double SPEED_INCREMENT = 0.01; private Direction currentDirection = Direction.RIGHT; private boolean gameOver = false; private boolean gamePaused = false; private int score = 0; private double speed = INITIAL_SPEED; private long lastUpdate = 0; private List<Position> snake = new ArrayList<>(); private Position food; private enum Direction { UP, DOWN, LEFT, RIGHT } private enum GameMode { EASY(0.1), NORMAL(0.08), HARD(0.05); private double speed; GameMode(double speed) { this.speed = speed; } public double getSpeed() { return speed; } } private GameMode currentMode = GameMode.EASY; @Override public void start(Stage primaryStage) { Canvas canvas = new Canvas(WIDTH * TILE_SIZE, HEIGHT * TILE_SIZE); GraphicsContext gc = canvas.getGraphicsContext2D(); Label scoreLabel = new Label("Score: 0"); scoreLabel.setFont(Font.font(20)); Label modeLabel = new Label("Mode: " + currentMode.name()); modeLabel.setFont(Font.font(20)); HBox infoBox = new HBox(20, scoreLabel, modeLabel); infoBox.setAlignment(Pos.CENTER); BorderPane root = new BorderPane(); root.setCenter(canvas); root.setBottom(infoBox); Scene scene = new Scene(root); scene.setOnKeyPressed(event -> { KeyCode keyCode = event.getCode(); if (keyCode == KeyCode.UP && currentDirection != Direction.DOWN) { currentDirection = Direction.UP; } else if (keyCode == KeyCode.DOWN && currentDirection != Direction.UP) { currentDirection = Direction.DOWN; } else if (keyCode == KeyCode.LEFT && currentDirection != Direction.RIGHT) { currentDirection = Direction.LEFT; } else if (keyCode == KeyCode.RIGHT && currentDirection != Direction.LEFT) { currentDirection = Direction.RIGHT; } else if (keyCode == KeyCode.SPACE) { if (gameOver) { initializeGame(); gamePaused = false; gameOver = false; draw(gc); } else { gamePaused = !gamePaused; } } else if (keyCode == KeyCode.DIGIT1) { currentMode = GameMode.EASY; modeLabel.setText("Mode: " + currentMode.name()); } else if (keyCode == KeyCode.DIGIT2) { currentMode = GameMode.NORMAL; modeLabel.setText("Mode: " + currentMode.name()); } else if (keyCode == KeyCode.DIGIT3) { currentMode = GameMode.HARD; modeLabel.setText("Mode: " + currentMode.name()); } }); primaryStage.setTitle("贪吃蛇游戏"); primaryStage.setScene(scene); primaryStage.show(); initializeGame(); AnimationTimer gameLoop = new AnimationTimer() { @Override public void handle(long now) { if (gameOver || gamePaused) { return; } long elapsedNanoSeconds = now - lastUpdate; double elapsedSeconds = elapsedNanoSeconds / 1_000_000_000.0; if (elapsedSeconds >= currentMode.getSpeed()) { update(); draw(gc); lastUpdate = now; } } }; gameLoop.start(); } private void initializeGame() { snake.clear(); snake.add(new Position(WIDTH / 2, HEIGHT / 2)); snake.add(new Position(WIDTH / 2 - 1, HEIGHT / 2)); snake.add(new Position(WIDTH / 2 - 2, HEIGHT / 2)); generateFood(); gameOver = false; score = 0; speed = INITIAL_SPEED; lastUpdate = 0; } private void generateFood() { Random random = new Random(); int x, y; do { x = random.nextInt(WIDTH); y = random.nextInt(HEIGHT); } while (isSnakeCollision(x, y)); food = new Position(x, y); } private boolean isSnakeCollision(int x, int y) { for (Position position : snake) { if (position.x == x && position.y == y) { return true; } } return false; } private void update() { Position head = snake.get(0); int dx = 0, dy = 0; switch (currentDirection) { case UP: dy = -1; break; case DOWN: dy = 1; break; case LEFT: dx = -1; break; case RIGHT: dx = 1; break; } int newHeadX = (head.x + dx + WIDTH) % WIDTH; int newHeadY = (head.y + dy + HEIGHT) % HEIGHT; Position newHead = new Position(newHeadX, newHeadY); if (isSnakeCollision(newHead.x, newHead.y)) { gameOver = true; return; } snake.add(0, newHead); if (newHead.x == food.x && newHead.y == food.y) { score++; generateFood(); speed -= SPEED_INCREMENT; if (speed < 0.05) { speed = 0.05; } } else { snake.remove(snake.size() - 1); } } private void draw(GraphicsContext gc) { gc.setFill(Color.BLACK); gc.fillRect(0, 0, WIDTH * TILE_SIZE, HEIGHT * TILE_SIZE); gc.setFill(Color.GREEN); for (int i = 0; i < snake.size(); i++) { Position position = snake.get(i); if (i == 0) { gc.setFill(Color.YELLOW); } else { gc.setFill(Color.GREEN); } gc.fillRect(position.x * TILE_SIZE, position.y * TILE_SIZE, TILE_SIZE, TILE_SIZE); } gc.setFill(Color.RED); gc.fillRect(food.x * TILE_SIZE, food.y * TILE_SIZE, TILE_SIZE, TILE_SIZE); Label scoreLabel = (Label) ((HBox) ((BorderPane) gc.getCanvas().getParent()).getBottom()).getChildren().get(0); scoreLabel.setText("Score: " + score); if (gameOver) { gc.setFill(Color.WHITE); gc.setFont(Font.font(30)); gc.fillText("Game Over", WIDTH * TILE_SIZE / 2 - 80, HEIGHT * TILE_SIZE / 2); } } private static class Position { int x; int y; Position(int x, int y) { this.x = x; this.y = y; } } public static void main(String[] args) { launch(args); } }

🥠 训练流程


讲述想要的游戏


notion image
notion image
notion image

发现bug


我运行的时候发现了两个bug:
  1. 食物可以生成在身体上;
  1. 蛇撞到自己身体还能继续运行;
notion image
notion image
它会告诉我是怎么解决这些bug的。

询问ChatGPT如何改进游戏


notion image
wooooo,它居然能告诉我这么多的改进方案

让ChatGPT帮我改进


notion image
notion image
其实它只帮我改进了第五点,这个有点失望。。。。
那就再让它增加其他功能
notion image
notion image

让它帮我改进游戏体验


notion image
notion image
notion image
让它对界面进行优化
notion image
notion image
一如既往的告诉我它的解决方案 👍🏻

发现代码bug让ChatGPT修复


notion image
把代码片段给到它,它也能理解bug是什么,而且还解释原因。wooo,🐂
这里提一下,它生成代码的时候之前的功能可能会丢失,就在上一次生成代码的时候,它把SPACE的功能丢失了,这个时候我直接使用文字的形式告诉它问题,它也能解决,这个也太牛逼了🐂🐂
notion image
notion image
它会把代码片段给到我,这个厉害了。

🔗 引用文章


 
 
💡
有关于博客的任何问题,请在下方留言,感谢~ 🤞🏻
vim编辑器KMP算法

  • Giscus
  • Cusdis
Sheamus
Sheamus
I'm a geeker!
公告
type
status
date
slug
summary
tags
category
icon
password

📢📢📢 重磅更新 📢📢📢

首页添加了 ChatGPT 的入口,只要添加上你自己的 OpenAI API key 你就能轻松玩转 ChatGPT 了~~~
使用过程有任何问题请到留言区留言,感谢 👏🏻👏🏻👏🏻