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

J2ME 經典貪吃蛇完整原始碼解析

     編輯:J2ME

專案結構

  • SnakeMIDlet.java — MIDlet 入口,建立並顯示 SnakeCanvas
  • SnakeCanvas.java — 繼承 Canvas 實作 Runnable,包含完整遊戲邏輯

核心資料結構

// 蛇身節點座標陣列,最大 200 節
int[][] snake = new int[200][2]; // [節點索引][0=x, 1=y]
int snakeLen = 7;                // 當前長度

// 移動方向常數
final int UP = 0, DOWN = 1, LEFT = 2, RIGHT = 3;
int dir = RIGHT; // 初始向右

// 遊戲區尺寸
int width, height;
final byte UNIT = 4; // 每格 4 像素

// 食物
int foodX, foodY;
boolean foodVisible = true; // 閃爍控制
Random rnd = new Random();

// 狀態旗標
boolean paused = false;
boolean running = true;
final int SLEEP = 300; // 幀延遲毫秒

初始化

private void init() {
    snakeLen = 7;
    for (int i = 0; i < snakeLen; i++) {
        snake[i][0] = 100 - UNIT * i; // 水平排列
        snake[i][1] = 40;
    }
    dir = RIGHT;
    foodX = 100; foodY = 100;
    new Thread(this).start(); // 啟動遊戲迴路
}

繪圖 (paint)

protected void paint(Graphics g) {
    // 清背景
    g.setColor(0xFFFFFF); g.fillRect(0, 0, width, height);
    g.setColor(0); // 黑色蛇身

    // 繪製蛇身每節
    for (int i = 0; i < snakeLen; i++)
        g.fillRect(snake[i][0], snake[i][1], UNIT, UNIT);

    // 繪製閃爍食物
    if (foodVisible)
        g.fillRect(foodX, foodY, UNIT, UNIT);
}

移動邏輯

private void move(int dir) {
    // 1. 身體跟隨:從尾部向前複製前一節座標
    for (int i = snakeLen - 1; i > 0; i--) {
        snake[i][0] = snake[i-1][0];
        snake[i][1] = snake[i-1][1];
    }
    // 2. 頭部根據方向移動一格
    switch (dir) {
        case UP:    snake[0][1] -= UNIT; break;
        case DOWN:  snake[0][1] += UNIT; break;
        case LEFT:  snake[0][0] -= UNIT; break;
        case RIGHT: snake[0][0] += UNIT; break;
    }
}

吃食物與生成新食物

private void eatFood() {
    if (snake[0][0] == foodX && snake[0][1] == foodY) {
        snakeLen++; // 增長
        generateFood();
    }
}

private void generateFood() {
    while (true) {
        // 對齊網格:隨機數取模後乘回 UNIT
        foodX = Math.abs(rnd.nextInt() % (width - UNIT + 1)) / UNIT * UNIT;
        foodY = Math.abs(rnd.nextInt() % (height - UNIT + 1)) / UNIT * UNIT;
        // 檢查不與蛇身重疊
        boolean ok = true;
        for (int i = 0; i < snakeLen; i++)
            if (foodX == snake[i][0] && foodY == snake[i][1]) { ok = false; break; }
        if (ok) break;
    }
}

遊戲結束判定

private boolean isGameOver() {
    // 1. 撞牆
    if (snake[0][0] < 0 || snake[0][0] > width - UNIT ||
        snake[0][1] < 0 || snake[0][1] > height - UNIT)
        return true;
    // 2. 撞自己 (從第 4 節開始檢查,前 3 段不可能自撞)
    for (int i = 4; i < snakeLen; i++)
        if (snake[0][0] == snake[i][0] && snake[0][1] == snake[i][1])
            return true;
    return false;
}

鍵盤控制

public void keyPressed(int keyCode) {
    int action = getGameAction(keyCode); // 映射為邏輯鍵 UP/DOWN/LEFT/RIGHT/FIRE
    switch (action) {
        case UP:    if (dir != DOWN)  dir = UP;    break;
        case DOWN:  if (dir != UP)    dir = DOWN;  break;
        case LEFT:  if (dir != RIGHT) dir = LEFT;  break;
        case RIGHT: if (dir != LEFT)  dir = RIGHT; break;
        case FIRE:  paused = !paused; break; // 暫停/繼續
    }
}

使用 getGameAction() 吸收鍵碼差異,防止 180 度反向導致瞬間自殺。

遊戲主迴路 (精確幀率控制)

public void run() {
    try {
        while (running) {
            long start = System.currentTimeMillis();

            if (!paused) {
                eatFood();
                move(dir);
                if (isGameOver()) break; // 結束迴路
                foodVisible = !foodVisible; // 食物閃爍
            }
            repaint();

            long elapsed = System.currentTimeMillis() - start;
            int sleep = SLEEP - (int)elapsed;
            if (sleep > 0) Thread.sleep(sleep);
        }
    } catch (Exception e) {}
    // 遊戲結束處理可在這裡加入 Game Over 畫面
}

採用 時間補償法:測量邏輯耗時,動態睡眠剩餘時間,維持穩定 ~3.3 FPS (300ms/幀)。

代碼亮點總結

  1. 極簡資料結構:二維陣列存蛇身,無需鏈表,適合 J2ME 記憶體環境。
  2. 網格對齊算法:食物生成與移動均基於 UNIT 對齊,邏輯清晰。
  3. 輸入映射標準化:getGameAction() 屏蔽硬體差異。
  4. 精確幀率控制:時間補償迴路,跨裝置速度一致。
  5. 閃爍食物:單一布林旗標控制可見性,視覺提示明確。
  6. 暫停機制:旗標法,不阻塞執行緒,即時響應。

此代碼為 J2ME 遊戲入門最佳範例,涵蓋迴路、輸入、繪圖、邏輯、狀態管理所有核心要素。

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