失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > JavaFX 过时了吗?你怎么看 闲暇之余实现一版贪吃蛇小游戏 放松一下!

JavaFX 过时了吗?你怎么看 闲暇之余实现一版贪吃蛇小游戏 放松一下!

时间:2023-09-11 00:25:27

相关推荐

JavaFX 过时了吗?你怎么看 闲暇之余实现一版贪吃蛇小游戏 放松一下!

关于JavaFX技术这里不做过多介绍,简单说一句:

JavaFx平台作为Java gui的替代方案,是一个富客户端平台解决方案,它能够使用应用程序开发人员轻松的创建跨平台的富客户端应用程序。

通过JavaFX实现简单的贪吃蛇游戏,没有小蛇素材,使用老鼠代替😊😊😊

实现说明

W S A D 代表上下左右方向AnchorPane主面板,锚点类型Canvas绘图对象,获取画笔进行图像显示绘制,设置位置坐标和尺寸音乐播放使用MediaPlayer食物随机生成,使用子线程和阻塞队列进行生产。使用Timer实现蛇前进和速度控制

核心对象

Food: 食物对象Snake: 蛇对象SnakeHead: 蛇头对象SnakePart: 蛇身体一部分SnakeRun: 游戏启动类继承了javafx的Application

运行截图

代码实现

Food

package com.example.snake;import javafx.scene.canvas.GraphicsContext;import javafx.scene.paint.Color;import java.util.Random;public class Food {private final int x;private final int y;private final int size;private final Color color;private final GraphicsContext graphics;public Food(int x, int y, int size, Color color, GraphicsContext graphics) {this.x = x;this.y = y;this.size = size;this.color = color;this.graphics = graphics;}public Food(int x, int y, GraphicsContext graphics) {this.x = x;this.y = y;this.size = SnakePart.DEF_LEN;Random random = new Random();this.color = Color.rgb(random.nextInt(255), random.nextInt(255), random.nextInt(255));this.graphics = graphics;}public Food show() {graphics.setFill(color);// graphics.fillRect(x, y, size, size);graphics.drawImage(Caches.mouseImage2, x, y, size, size);return this;}public void vanish() {graphics.clearRect(x, y, size, size);}public int getX() {return x;}public int getY() {return y;}public int getSize() {return size;}public Color getColor() {return color;}}

SnakePart

package com.example.snake;import javafx.scene.canvas.GraphicsContext;import javafx.scene.paint.Color;import java.util.Random;/*** 身体片段*/public class SnakePart {public static final int DEF_LEN = 40;protected int x;protected int y;protected final int len;protected final Color color;protected final GraphicsContext graphics;public SnakePart(int x, int y, GraphicsContext graphics) {this.x = x;this.y = y;this.len = DEF_LEN;Random random = new Random();this.color = Color.rgb(random.nextInt(255), random.nextInt(255), random.nextInt(255));this.graphics = graphics;}public SnakePart(int x, int y, Color color, GraphicsContext graphics) {this.x = x;this.y = y;this.len = DEF_LEN;this.color = color;this.graphics = graphics;}public SnakePart(int x, int y, int len, Color color, GraphicsContext graphics) {this.x = x;this.y = y;this.len = len;this.color = color;this.graphics = graphics;}public void remove() {graphics.clearRect(x, y, len, len);}public SnakePart move(int dX, int dY) {x += dX;y += dY;graphics.drawImage(Caches.snakeBodyImage, x, y, len, len);return this;}public SnakePart updateLocation(int pX, int pY) {x = pX;y = pY;graphics.drawImage(Caches.snakeBodyImage, x, y, len, len);return this;}public int getX() {return x;}public int getY() {return y;}public int getLen() {return len;}@Overridepublic String toString() {return "SnakePart{" +"x=" + x +", y=" + y +", color=" + color +'}';}}

SnakeHead

package com.example.snake;import javafx.scene.canvas.GraphicsContext;import javafx.scene.paint.Color;public class SnakeHead extends SnakePart {public SnakeHead(int x, int y, GraphicsContext graphics) {super(x, y, graphics);}public SnakeHead(int x, int y, Color color, GraphicsContext graphics) {super(x, y, color, graphics);}public SnakeHead(int x, int y, int len, Color color, GraphicsContext graphics) {super(x, y, len, color, graphics);}@Overridepublic SnakePart move(int dX, int dY) {x += dX;y += dY;// graphics.setFill(color);graphics.drawImage(Caches.snakeHeadImage, x, y, len, len);return this;}@Overridepublic SnakePart updateLocation(int pX, int pY) {x = pX;y = pY;// graphics.setFill(color);graphics.drawImage(Caches.snakeHeadImage, x, y, len, len);return this;}}

Snake

package com.example.snake;import javafx.application.Platform;import javafx.scene.canvas.Canvas;import javafx.scene.canvas.GraphicsContext;import javafx.scene.input.KeyCode;import javafx.scene.input.KeyEvent;import java.util.*;import java.util.concurrent.ArrayBlockingQueue;public class Snake {private int initX;private int initY;private int initLen;private int speed;//方向 w s a d -> 上下左右private KeyCode direction;private SnakeHead head;private List<SnakePart> body;private GraphicsContext graphics;private Canvas canvas;private ArrayBlockingQueue<Food> foodQueue;private Timer timer;private SnakeEvent snakeEvent;public Snake(int initX, int initY, int initLen, int speed, Canvas canvas, ArrayBlockingQueue<Food> foodQueue) {this.initX = initX;this.initY = initY;this.initLen = initLen;this.speed = speed;this.canvas = canvas;this.foodQueue = foodQueue;this.graphics = canvas.getGraphicsContext2D();}public void init() {head = new SnakeHead(initX, initY, graphics);body = new ArrayList<>();for (int i = 0; i < initLen; i++) {body.add(new SnakePart(initX - SnakePart.DEF_LEN * (i + 1), initY, graphics).move(0, 0));}timer = new Timer();direction = KeyCode.D;}public void turn(KeyEvent keyEvent) {KeyCode code = keyEvent.getCode();if (code != KeyCode.W && code != KeyCode.S && code != KeyCode.A && code != KeyCode.D) {return;}if (code == KeyCode.W && direction == KeyCode.S) {return;}if (code == KeyCode.S && direction == KeyCode.W) {return;}if (code == KeyCode.A && direction == KeyCode.D) {return;}if (code == KeyCode.D && direction == KeyCode.A) {return;}direction = code;}public boolean eat() {Food food = foodQueue.peek();if (food == null) {return false;}if (head.getX() == food.getX() && head.getY() == food.getY()) {food = foodQueue.poll();if (food == null) {return false;}SnakePart tail = body.get(body.size() - 1);if (direction == KeyCode.W) {body.add(new SnakePart(tail.getX(), tail.getY() + SnakePart.DEF_LEN, food.getColor(), graphics).move(0, 0));} else if (direction == KeyCode.S) {body.add(new SnakePart(tail.getX(), tail.getY() - SnakePart.DEF_LEN, food.getColor(), graphics).move(0, 0));} else if (direction == KeyCode.A) {body.add(new SnakePart(tail.getX() + SnakePart.DEF_LEN, tail.getY(), food.getColor(), graphics).move(0, 0));} else if (direction == KeyCode.D) {body.add(new SnakePart(tail.getX() - SnakePart.DEF_LEN, tail.getY(), food.getColor(), graphics).move(0, 0));}food.vanish();return true;}return false;}public void remove() {for (SnakePart snakePart : body) {snakePart.remove();}}public void move(int dX, int dY) {if (dX == 0 && dY == 0) {return;}remove();for (int i = body.size() - 1; i > 0; i--) {body.get(i).updateLocation(body.get(i - 1).getX(), body.get(i - 1).getY());}int headX = head.getX();int headY = head.getY();head.remove();body.get(0).updateLocation(headX, headY);head.move(dX, dY);}public void run() {timer.scheduleAtFixedRate(new TimerTask() {@Overridepublic void run() {Platform.runLater(()->{die();eat();switch (direction) {case W: {move(0, -SnakePart.DEF_LEN);break;}case S: {move(0, SnakePart.DEF_LEN);break;}case A: {move(-SnakePart.DEF_LEN, 0);break;}case D: {move(SnakePart.DEF_LEN, 0);break;}}});}}, 0, 2000 / speed);}public void die() {double width = canvas.getWidth();double height = canvas.getHeight();if (head.getX() < 0 || head.getY() < 0 ||(head.getX() + SnakePart.DEF_LEN) > width ||(head.getY() + SnakePart.DEF_LEN) > height) {timer.cancel();EventType die = EventType.DIE;die.getData().setScore((body.size() - initLen) * 5);die.getData().setSnake(this);Platform.runLater(() -> snakeEvent.onEvent(die));}}public void clearAll() {remove();head.remove();body.clear();Food food;if ((food = foodQueue.poll()) != null) {food.vanish();}}public List<SnakePart> getHeadAndBody() {ArrayList<SnakePart> snakeParts = new ArrayList<>();snakeParts.add(head);snakeParts.addAll(body);return snakeParts;}public void setSnakeEvent(SnakeEvent snakeEvent) {this.snakeEvent = snakeEvent;}public interface SnakeEvent {void onEvent(EventType type);}public enum EventType {DIE(new Data(0));private final Data data;EventType(Data data) {this.data = data;}public Data getData() {return data;}}public static class Data {private Snake snake;private int score;public Data() {}public Data(int score) {this.score = score;}public int getScore() {return score;}public void setScore(int score) {this.score = score;}public Snake getSnake() {return snake;}public void setSnake(Snake snake) {this.snake = snake;}}}

SnakeRun

package com.example.snake;import javafx.application.Application;import javafx.application.Platform;import javafx.scene.Scene;import javafx.scene.canvas.Canvas;import javafx.scene.control.Alert;import javafx.scene.control.ButtonBar;import javafx.scene.control.ButtonType;import javafx.scene.image.Image;import javafx.scene.layout.*;import javafx.scene.media.Media;import javafx.scene.media.MediaPlayer;import javafx.stage.Stage;import javafx.stage.StageStyle;import java.util.Optional;import java.util.Random;import java.util.concurrent.ArrayBlockingQueue;public class SnakeRun extends Application {private static final int multiple = 22;private static final int width = SnakePart.DEF_LEN * (multiple + 10);private static final int height = SnakePart.DEF_LEN * multiple;private double windowXOffset = 0;private double windowYOffset = 0;private final ArrayBlockingQueue<Food> foodQueue = new ArrayBlockingQueue<>(1);private MediaPlayer mediaPlayer;private AnchorPane pane;private Canvas canvas;private boolean stop;@Overridepublic void start(Stage stage) throws Exception {pane = new AnchorPane();canvas = new Canvas(width, height);Snake snake = new Snake(SnakePart.DEF_LEN * 6, SnakePart.DEF_LEN * 6, 5, 10, canvas, foodQueue);//监听死亡事件snake.setSnakeEvent(type -> alert(type, stage));snake.init();pane.getChildren().add(canvas);pane.setOnKeyPressed(snake::turn);pane.setBackground(getBackground());//鼠标按下 记录位置pane.setOnMousePressed(event -> {windowXOffset = event.getSceneX();windowYOffset = event.getSceneY();});//鼠标拖动 移动stage窗口pane.setOnMouseDragged(event -> {stage.setX(event.getScreenX() - windowXOffset);stage.setY(event.getScreenY() - windowYOffset);});Scene scene = new Scene(pane);stage.setScene(scene);stage.setResizable(false);//stage.setTitle("贪吃蛇");//隐藏窗口标题和操作stage.initStyle(StageStyle.UNDECORATED);//退出事件stage.setOnCloseRequest(event -> {Platform.exit();System.exit(0);});stage.show();//获取窗口焦点canvas.requestFocus();//初始化并播放音乐initMedia();//开启食物生成线程genFood(snake, canvas);//运行蛇snake.run();}private Background getBackground() {BackgroundImage bImg = new BackgroundImage(new Image(this.getClass().getResourceAsStream("/com/example/fx/bj11.jpg")),BackgroundRepeat.NO_REPEAT,BackgroundRepeat.NO_REPEAT,BackgroundPosition.DEFAULT,new BackgroundSize(-1, -1, true, true, false, true));return new Background(bImg);}private void initMedia() {Media media = new Media(this.getClass().getResource("/com/example/fx/dizi.mp3").toString());mediaPlayer = new MediaPlayer(media);mediaPlayer.setCycleCount(Integer.MAX_VALUE);mediaPlayer.play();}private void genFood(Snake snake, Canvas canvas) {new Thread(() -> {Random random = new Random();while (!stop) {int x = random.nextInt(multiple - 1);int y = random.nextInt(multiple - 1);for (SnakePart snakePart : snake.getHeadAndBody()) {if (snakePart.getX() == x && snakePart.getY() == y) {x = random.nextInt(multiple - 1);y = random.nextInt(multiple - 1);}}try {Food food = new Food(x * SnakePart.DEF_LEN, y * SnakePart.DEF_LEN, canvas.getGraphicsContext2D());foodQueue.put(food);if (!stop) {Platform.runLater(food::show);}} catch (InterruptedException e) {e.printStackTrace();}}}).start();}private void alert(Snake.EventType eventType, Stage stage) {if (eventType == Snake.EventType.DIE) {Alert alert = new Alert(Alert.AlertType.CONFIRMATION);alert.setTitle("死亡确认");alert.setHeaderText("警报,你已经死亡了!!");alert.setContentText("当前得分:" + eventType.getData().getScore() + "分");ButtonType buttonTypeOne = new ButtonType("重新开始");ButtonType buttonTypeTwo = new ButtonType("关闭游戏");ButtonType buttonTypeCancel = new ButtonType("取消", ButtonBar.ButtonData.CANCEL_CLOSE);alert.getButtonTypes().setAll(buttonTypeOne, buttonTypeTwo, buttonTypeCancel);Optional<ButtonType> result = alert.showAndWait();if (result.get() == buttonTypeOne) {eventType.getData().getSnake().clearAll();Snake snake = new Snake(SnakePart.DEF_LEN * 6, SnakePart.DEF_LEN * 6, 5, 10, canvas, foodQueue);snake.setSnakeEvent(type -> alert(type, stage));pane.setOnKeyPressed(snake::turn);snake.init();snake.run();} else if (result.get() == buttonTypeTwo) {stop = true;mediaPlayer.stop();eventType.getData().getSnake().clearAll();stage.close();} else {alert.close();}}}}

如果觉得《JavaFX 过时了吗?你怎么看 闲暇之余实现一版贪吃蛇小游戏 放松一下!》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。