首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 經典小遊戲實戰:從零構建「貪吃蛇」極速版 (Swing 實現)

     編輯:Java 相關知識

項目概覽

本文將引導你使用 Java Swing 庫從零構建一款經典的「貪吃蛇」遊戲極速版。涵蓋遊戲主循環、雙緩衝繪圖、鍵盤事件監聽、碰撞檢測及分數統計等核心遊戲開發技術。

核心類設計

  • SnakeFrame:繼承 JFrame,遊戲主窗口。
  • GamePanel:繼承 JPanel,核心繪圖與邏輯面板,實現 Runnable 和 KeyListener。
  • Node:內部類,表示蛇身節點(x, y 座標)。

關鍵代碼實現

1. 遊戲面板初始化與雙緩衝

public class GamePanel extends JPanel implements Runnable, KeyListener {
    private final int WIDTH = 800;
    private final int HEIGHT = 600;
    private final int UNIT_SIZE = 20; // 每個格子大小
    private final int GAME_UNITS = (WIDTH * HEIGHT) / (UNIT_SIZE * UNIT_SIZE);
    
    private final int DELAY = 75; // 極速版:刷新間隔 75ms
    
    private int[] x = new int[GAME_UNITS]; // 蛇身 X 座標數組
    private int[] y = new int[GAME_UNITS]; // 蛇身 Y 座標數組
    private int bodyParts = 6; // 初始長度
    private int applesEaten = 0;
    private int appleX, appleY;
    private char direction = 'R'; // 初始向右
    private boolean running = false;
    private Thread gameThread;
    private Image offScreenImage; // 雙緩衝圖像

    public GamePanel() {
        setPreferredSize(new Dimension(WIDTH, HEIGHT));
        setBackground(Color.BLACK);
        setFocusable(true);
        addKeyListener(this);
        startGame();
    }

    public void startGame() {
        newApple();
        running = true;
        gameThread = new Thread(this);
        gameThread.start();
    }
    // ...
}

2. 遊戲主循環

@Override
public void run() {
    while (running) {
        try {
            Thread.sleep(DELAY);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        if (running) {
            move();      // 移動蛇身
            checkApple(); // 檢測吃食物
            checkCollisions(); // 檢測碰撞
        }
        repaint(); // 觸發 paintComponent 重繪
    }
}

3. 移動邏輯與碰撞檢測

public void move() {
    // 身體跟隨頭部移動(從尾部向前更新座標)
    for (int i = bodyParts; i > 0; i--) {
        x[i] = x[i - 1];
        y[i] = y[i - 1];
    }
    // 根據方向更新頭部座標
    switch (direction) {
        case 'U': y[0] -= UNIT_SIZE; break;
        case 'D': y[0] += UNIT_SIZE; break;
        case 'L': x[0] -= UNIT_SIZE; break;
        case 'R': x[0] += UNIT_SIZE; break;
    }
}

public void checkCollisions() {
    // 撞牆檢測
    if (x[0] < 0 || x[0] >= WIDTH || y[0] < 0 || y[0] >= HEIGHT) {
        running = false;
    }
    // 撞自己檢測
    for (int i = bodyParts; i > 0; i--) {
        if (x[0] == x[i] && y[0] == y[i]) {
            running = false;
            break;
        }
    }
    if (!running) gameThread.interrupt();
}

4. 雙緩衝繪圖

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    doDrawing(g);
}

private void doDrawing(Graphics g) {
    if (offScreenImage == null) {
        offScreenImage = createImage(WIDTH, HEIGHT);
    }
    Graphics gOff = offScreenImage.getGraphics();
    
    // 繪製背景網格、食物、蛇身、分數...
    gOff.setColor(Color.RED);
    gOff.fillOval(appleX, appleY, UNIT_SIZE, UNIT_SIZE);
    
    for (int i = 0; i < bodyParts; i++) {
        gOff.setColor(i == 0 ? Color.GREEN : new Color(45, 180, 0));
        gOff.fillRect(x[i], y[i], UNIT_SIZE, UNIT_SIZE);
    }
    
    g.drawImage(offScreenImage, 0, 0, this); // 將離屏圖像一次性繪到屏幕
}

5. 鍵盤控制

@Override
public void keyPressed(KeyEvent e) {
    int key = e.getKeyCode();
    // 防止 180 度掉頭
    if ((key == KeyEvent.VK_LEFT || key == KeyEvent.VK_A) && direction != 'R') direction = 'L';
    else if ((key == KeyEvent.VK_RIGHT || key == KeyEvent.VK_D) && direction != 'L') direction = 'R';
    else if ((key == KeyEvent.VK_UP || key == KeyEvent.VK_W) && direction != 'D') direction = 'U';
    else if ((key == KeyEvent.VK_DOWN || key == KeyEvent.VK_S) && direction != 'U') direction = 'D';
}
// keyReleased, keyTyped 留空

運行入口

public class SnakeGameMain {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("Java 貪吃蛇極速版");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setResizable(false);
            frame.add(new GamePanel());
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }
}

優化建議

  • 使用 BufferStrategy 替代手動雙緩衝,性能更強。
  • 引入狀態機管理:菜單、運行、暫停、結束。
  • 添加本地最高分記錄(文件或 Preferences API)。
  • 支持多關卡、障礙物、道具系統。

總結

通過約 200 行核心代碼,我們實現了流暢的「貪吃蛇」極速版。此項目是理解 Java 遊戲循環、Swing 繪圖機制、事件驅動編程的絕佳入門實踐。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved