專案概覽
- 類型:飛行射擊變體(潛艇題材)
- 平台:MIDP 2.0 / CLDC 1.1,Sun WTK 2.2 調試通過
- 架構:單例控制器 + GameCanvas + 層管理器 + 時間觸發器
- 資源聲明:美術素材多來自網絡,代碼僅供非商業學習參考
- 源碼下載:JAD/JAR/RAR 完整包(含詳細註釋)
核心架構設計
1. 單例控制器模式
public class Controller {
private static Controller instance = new Controller();
private Display display;
private Displayable currentScreen;
private Controller() {}
public static Controller getInstance() { return instance; }
public void setScreen(Displayable d) {
currentScreen = d;
display.setCurrent(d);
}
// 管理:主選單、遊戲畫布、幫助、Alert 切換
}
2. GameCanvas + 獨立渲染線程
- 繼承
GameCanvas,關閉系統繪製,採用 flushGraphics() 雙緩衝
- 主線程每 25ms 掃描按鍵,每 50ms 掃描實體運動
- 子彈發射等即時響應覆寫
keyPressed() 直接處理
3. 實體註冊機制(避免線程爆炸)
// 畫布持有各類型實體向量
Vector enemySubs = new Vector();
Vector torpedoes = new Vector();
Vector seaCreatures = new Vector();
// 註冊介面
interface SubObject { // 可移動圖層統一介面
void move(); // 邏輯更新
void draw(Graphics g); // 繪製(可選,統一由層管理器處理)
boolean isAlive();
int getLayerX(), getLayerY();
}
// 新增實體
public void spawnEnemy() {
EnemySub e = new EnemySub(...);
enemySubs.addElement(e);
layerManager.append(e.getSprite()); // 圖層管理器同步
}
// 主循環掃描
private void updateEntities() {
updateVector(enemySubs);
updateVector(torpedoes);
updateVector(seaCreatures);
}
private void updateVector(Vector v) {
for (int i = v.size()-1; i >= 0; i--) {
SubObject o = (SubObject)v.elementAt(i);
if (o.isAlive()) o.move();
else {
layerManager.remove(((Sprite)o).getSprite());
v.removeElementAt(i);
}
}
}
4. 大世界座標與層管理器
- 遊戲世界遠大於螢幕(如 2048x2048 像素)
- 所有 Sprite 掛載於
LayerManager
- 玩家移動時,計算相對偏移,調用
layerManager.setViewWindow(px, py, w, h)
類結構關係圖
Controller (單例)
├─ MainMenu (List)
├─ SubCanvas (GameCanvas) 核心
│ ├─ Sub (玩家潛艇) implements SubObject
│ ├─ EnemySub implements SubObject
│ ├─ Tinfish (魚雷) implements SubObject
│ ├─ MoveableSprite (海洋生物) implements SubObject
│ └─ LayerManager (圖層管理)
├─ HelpScreen
└─ Alerts

流程圖解析


已知問題與優化方向
| 問題 | 原因 | 改進方案 |
| 玩家生命值顯示異常 | UI 刷新邏輯與邏輯線程不同步 | 引入 volatile/同步塊,或統一在渲染幀讀取 |
| 長時間運行幀率下降 | Vector 遍歷未清理死對象 / 圖層管理器未釋放 | 定期 compact Vector、離屏實體及時 remove |
| 真機記憶體不足 | 圖片資源過大、未釋放 | 圖片統一 PNG 8-bit、用 Image.createImage(byte[]) 流式加載 |
給後續開發者的建議
- 先跑通 Demo:下載源碼在 WTK 2.2 編譯運行,理解生命週期
- 模塊化重構:將 SubCanvas 拆分為 Logic/Render/Input 三類
- 引入狀態機:遊戲狀態(菜單/遊戲/暫停/結算)用 State Pattern 管理
- 真機測試優先:模擬器無法反映 GC 停頓、按鍵延遲、記憶體碎片
結語
這個 Demo 展示了在 MIDP 2.0 受限環境下構建完整動作遊戲的工程化路徑:單例控制器、GameCanvas 雙緩衝、實體註冊機制、大世界座標映射。源碼開放供學習,歡迎 Fork 改進、修復遺留 Bug、移植到更多機型。
- 上一篇文章: J2ME 平台實時戰略遊戲 (RTS) 架構設計:突破 GPRS 延遲與資源瓶頸
- 下一篇文章: J2ME MIDlet 生命週期深度解析:狀態機模型與常見誤區
Copyright ©
程式碼之家 All Rights Reserved