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

我的第一個 Java 手機遊戲:趙雲騎馬跑動 + TiledLayer 背景拼貼完整實錄

     編輯:J2ME

前言

從《Java手機遊戲實例手冊》第 6 章範例改寫而來。書中源碼不全、圖片缺失,逼我自找素材、修 Bug、踩坑。雖成品簡單——趙雲騎馬從左跑到右、背景拼貼——但每個細節都讓我從「看懂」走到「會寫」。記錄完整代碼與關鍵踩坑點,給同路人參考。

專案結構

MyCartoonMidlet.java  // MIDlet 入口
MainCanvas.java       // 遊戲畫布邏輯
res/
  zhaoyun.png         // 精靈圖 (6 幀橫向排列)
  bk.jpg              // 背景素材 (60x40 單元)

核心代碼

MyCartoonMidlet.java

package mycartoon;
import javax.microedition.midlet.MIDlet;
import javax.microedition.lcdui.Display;

public class MyCartoonMidlet extends MIDlet {
    private MainCanvas canvas;

    protected void startApp() {
        if (canvas == null) {
            canvas = new MainCanvas();
            Display.getDisplay(this).setCurrent(canvas);
            // 遊戲主迴路
            while (true) {
                try {
                    Thread.sleep(100); // 10 FPS
                    canvas.repaint();
                } catch (Exception e) {}
            }
        }
    }
    protected void pauseApp() {}
    protected void destroyApp(boolean unconditional) {}
}

MainCanvas.java

package mycartoon;
import java.io.IOException;
import javax.microedition.lcdui.*;

public class MainCanvas extends Canvas {
    private Sprite zhaoyun;      // 精靈
    private TiledLayer bgLayer;  // 背景圖層
    private LayerManager manager; // 圖層管理器
    private Image bgImage;

    public MainCanvas() {
        try {
            // 1. 精靈:6 幀,每幀 40x60
            Image spriteImg = Image.createImage("/zhaoyun.png");
            zhaoyun = new Sprite(spriteImg, 40, 60);
            zhaoyun.setPosition(0, getHeight() / 2 - 30);

            // 2. 背景圖層:4 列 x 8 行,每單元 60x40
            bgImage = Image.createImage("/bk.jpg");
            bgLayer = new TiledLayer(4, 8, bgImage, 60, 40);
            bgLayer.setPosition(0, 0);
            setBgCells(); // 設置單元格圖塊索引

            // 3. 圖層管理器:繪製順序 = 添加順序 (先背景後精靈)
            manager = new LayerManager();
            manager.append(zhaoyun); // 顯示在上層
            manager.append(bgLayer); // 顯示在下層
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void setBgCells() {
        // 第一行:索引 2,3,4,5 (特定圖塊)
        bgLayer.setCell(0, 0, 2);
        bgLayer.setCell(1, 0, 3);
        bgLayer.setCell(2, 0, 4);
        bgLayer.setCell(3, 0, 5);
        // 第 2-8 行:全部填索引 6 (草地)
        for (int y = 1; y < 8; y++) {
            for (int x = 0; x < 4; x++) {
                bgLayer.setCell(x, y, 6);
            }
        }
    }

    protected void paint(Graphics g) {
        // 精靈動畫:循環播放 6 幀
        int frame = zhaoyun.getFrame();
        zhaoyun.setFrame((frame + 1) % 6);

        // 精靈移動:每幀 +10px,超出右邊界從左側重入
        int x = zhaoyun.getX() + 10;
        if (x > getWidth()) x = -zhaoyun.getWidth();
        zhaoyun.setPosition(x, zhaoyun.getY());

        // 一鍵繪製所有圖層 (自動處理 Z 軸順序)
        manager.paint(g, 0, 0);
    }
}

關鍵踩坑與心得

1. 構造函數陷阱 (參考文章 78602)

初寫 public void MainCanvas() 加了 void,導致非構造函數,成員未初始化,startApp 中 repaint() 拋 NPE。構造函數絕不能有返回類型。

2. 精靈圖片準備流程

  1. 網上找 GIF 動畫 → 用 pngmate (命令行工具) 提取幀並合併為橫向排列 PNG。
  2. 發現白色背景未去除 → 用 Total Commander 內建圖片轉換功能批量透明化 (原以為需專業工具,原來常用工具就有)。

3. TiledLayer 參數順序坑

new TiledLayer(cols, rows, image, cellWidth, cellHeight) —— 先列後行,再寬高。我最初寫反,背景全亂。必須查閱 JavaDoc 確認參數順序。

4. LayerManager 添加順序 = Z 軸順序

append(zhaoyun) 後 append(bgLayer),精靈在上層。若直接用 sprite.paint(g) + layer.paint(g),繪製順序相反 (先背景後精靈)。統一用 LayerManager 管理,少犯錯。

5. 主迴路 sleep 位置

書中 while(true) { sleep; repaint; } 會佔滿 CPU。正確做法:Thread.sleep 在渲染執行緒中,或用 Display.callSerially 配合 Timer。本例為教學簡化,實戰請用獨立渲染執行緒。

素材處理工具鏈推薦

任務工具備註
GIF 拆幀/合圖pngmate命令行、功能強、免費
批量透明化/格式轉換Total Commander (內建圖片轉換)鍵盤操作快、支援濾鏡
像素級編輯GraphicsGale / Aseprite專業像素動畫編輯器

總結

第一個遊戲雖簡陋,但串聯了 MIDlet 生命週期、Canvas 繪製、Sprite 動畫、TiledLayer 拼貼、LayerManager 合成、資源載入與異常處理完整鏈路。動手改代碼、找素材、查文檔、修 Bug,才是唯一捷徑。

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