貪吃蛇
- 貪吃蛇
- 原始碼:
貪吃蛇
貪吃蛇這一款小游戲,在以前的諾基亞手機中基本都會帶有這款,曾經風靡一時,
那么我們如何將這一款小游戲實作出來呢?
在這里,我們會使用到javaFX圖形化編程,將圖形化界面列印出來,通過用戶的實際操作,來控制游戲,如下圖:

這就是,游戲最終實作的情況,
我們可以通過蛇的速度來控制游戲難度,通過控制方向左右移動,實作游戲的邏輯,最后完成,
首先我們會匯入很多的包,大多數都是javafx的,因為需要圖形化界面,我們需要匯入它,javafx是jdk自帶的,
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import java.util.Arrays;
import java.util.Random;
我們定義貪吃蛇的身體初始為3,食物隨機生成,每次吃完食物速度會增加,同時獲得一分,當頭部撞墻,或者頭部撞到身體后,游戲結束,當游戲結束,按R從新開始游戲,
具體看原始碼,參照注釋閱讀:
原始碼:
public class Point {
public int x;
public int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
package snake;
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import java.util.Arrays;
import java.util.Random;
public class SnakeAPP extends Application {
//定義變數
//游戲區域大小,格子的的寬和高
private static final int WIDTH = 20;
private static final int HEIGHT = 20;
//繪制圖形的時候,格子所占的大小
private static final int GRID_SIZE = 40;
private static final int CANVAS_WIDTH = WIDTH * GRID_SIZE;
private static final int CANVAS_HEIGHT = HEIGHT * GRID_SIZE;
//定義游戲本身
//移動速度
//speed,每秒的幀數
private static int speed;
//食物
private static Point food = new Point(-1, -1);
//蛇,最多長1000節
private static Point[] snake = new Point[1000];
//現在多少節
private static int snakeLength = 0;
//朝向
enum Direction {
UP, LEFT, DOWN, RIGHT
}
private static Direction direction;
//隨機生成器
private static Random random = new Random();
//游戲結束標志
private static boolean gameOver;
//初始化游戲資料
private static void newGame() {
speed = 3;
//蛇的初始有3節
Arrays.fill(snake, null);
snakeLength = 0;
snake[snakeLength++] = new Point(WIDTH / 2, HEIGHT / 2);
snake[snakeLength++] = new Point(WIDTH / 2, HEIGHT / 2);
snake[snakeLength++] = new Point(WIDTH / 2, HEIGHT / 2);
//生成食物
newFood();
direction = Direction.LEFT;
//游戲未結束
gameOver = false;
}
//在地圖上隨機生成食物
private static void newFood() {
//1,不能生成在外面
//2.不能和蛇的身體碰撞
int x, y;
do {
x = random.nextInt(WIDTH);
y = random.nextInt(HEIGHT);
} while (isCollision(x, y));
food.x = x;
food.y = y;
}
private static boolean isCollision(int x, int y) {
//遍歷蛇
//不要用foreach
for (int i = 0; i < snakeLength; i++) {
Point point = snake[i];
if (point.x == x && point.y == y) {
return true;
}
}
return false;
}
//每一幀做的動作
private static void frame() {
//移動身體
for (int i = snakeLength - 1; i >= 1; i--) {
//變成前一個坐標
snake[i].x = snake[i - 1].x;
snake[i].y = snake[i - 1].y;
}
//移動頭
Point head = snake[0];
switch (direction) {
case UP:
head.y--;
break;
case DOWN:
head.y++;
break;
case LEFT:
head.x--;
break;
case RIGHT:
head.x++;
break;
}
//判斷頭是否出邊界
if (head.x < 0 || head.x >= WIDTH || head.y < 0 || head.y >= HEIGHT) {
gameOver = true;
return;
}
//判斷是否碰到身體
for (int i = 1; i < snakeLength; i++) {
Point point = snake[i];
if (head.x == point.x && head.y == point.y) {
gameOver = true;
return;
}
}
//判斷是否吃到食物
// 如果吃到食物
// 1.身體增加1節 2.重新生成食物 3. 速度增加
if (head.x == food.x && head.y == food.y) {
snake[snakeLength++] = new Point(-1, -1);
newFood();
speed++;
}
}
//每一幀繪制作業,渲染
private static void render(GraphicsContext gc) {
//1.從新繪制背景
gc.setFill(Color.BLACK);
gc.fillRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
//2.蛇的繪制
for (int i = 0; i < snakeLength; i++) {
Point point = snake[i];
gc.setFill(Color.GREEN);
gc.fillRect(point.x * GRID_SIZE + 1, point.y * GRID_SIZE + 1, GRID_SIZE - 2, GRID_SIZE - 2);
}
//3.食物的繪制
gc.setFill(Color.YELLOW);
gc.fillOval(food.x * GRID_SIZE + 1, food.y * GRID_SIZE + 1, GRID_SIZE, GRID_SIZE);
//3.進行游戲結束繪制
if (gameOver) {
gc.setFill(Color.RED);
gc.setFont(new Font(40));
gc.fillText("游戲結束,按R繼續", 200, 200);
}
//得分
gc.setFill(Color.AQUAMARINE);
gc.setFont(new Font(20));
gc.fillText("當前得分"+ (speed-3)+"分", 40, 40);
//作者
gc.setFill(Color.AQUA);
gc.setFont(new Font(15));
gc.fillText("版本:v1.0 作者:H485301267 ", 20, 740);
}
@Override
public void start(Stage primaryStage) throws Exception {
//游戲的初始化
newGame();
Pane pane = new Pane();
Canvas canvas = new Canvas(CANVAS_WIDTH, CANVAS_HEIGHT);
pane.getChildren().add(canvas);
Scene scene = new Scene(pane);
final GraphicsContext gc = canvas.getGraphicsContext2D();
AnimationTimer timer = new AnimationTimer() {
long lastTiick;
@Override
public void handle(long now) {
if (gameOver) {
return;
}
if (lastTiick == 0 || now - lastTiick > 1e9 / speed) {
lastTiick = now;
frame();
render(gc);
}
}
};
timer.start();
scene.setOnKeyPressed(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
switch (event.getCode()) {
case W:
case UP:
if (direction != Direction.DOWN) {
direction = Direction.UP;
}
break;
case A:
case LEFT:
if (direction != Direction.RIGHT) {
direction = Direction.LEFT;
}
break;
case S:
case DOWN:
if (direction != Direction.UP) {
direction = Direction.DOWN;
}
break;
case D:
case RIGHT:
if (direction != Direction.LEFT) {
direction = Direction.RIGHT;
}
break;
case R:
if (gameOver) {
newGame();
}
break;
}
}
});
primaryStage.setScene(scene);
primaryStage.setTitle("貪吃蛇");
primaryStage.setResizable(false);
primaryStage.sizeToScene();
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/258820.html
標籤:其他
上一篇:“春節檔”游戲運營核心方法論
下一篇:歌評-《朧月夜》-神前暁
