大量子彈的對象池復用、狀態數組驅動、半徑碰撞檢測是飛行射擊遊戲的核心模塊。本文詳細剖析 Bullets 類的完整實現。
數百顆子彈共享一個 Sprite 對象,通過狀態數組 記錄每顆子彈的獨立屬性:
private int[][] bullets; // [index][0:type, 1:x, 2:y, 3:vx, 4:vy, 5:alive]
private int bulletTotal; // 池大小
Bullets 類實現public class Bullets extends GameObject {
public static final int TYPE_LEFT = 0, TYPE_RIGHT = 1, TYPE_TOP = 2, TYPE_BOTTOM = 3;
private int[][] bullets;
private int bulletTotal;
private Random rnd;
private int screenW, screenH;
public Bullets(Image img, int fw, int fh, int total, int w, int h) {
super(img, fw, fh); // 共享 Sprite
this.bulletTotal = total;
this.bullets = new int[total][6];
this.rnd = new Random();
this.screenW = w; this.screenH = h;
}
public void initBullets() { for (int i=0;i screenW+5) bullets[i][3] *= -1;
if (bullets[i][2] < -5 || bullets[i][2] > screenH+5) bullets[i][4] *= -1;
}
// 繪製整群 (復用 sprite)
public void paint(Graphics g) {
for (int i=0;i
| 技術 | 實現細節 | 優勢 |
|---|---|---|
| 對象池 | 固定大小數組 + alive 標記 + initBullet 重置 | 零 GC、分配極快、適合 J2ME 受限環境 |
| Sprite 復用 | 單 Sprite 實例,繪製前 setPosition | 內存佔用極低 |
| 半徑碰撞 | 中心點距離 range 判斷,非像素級 | 運算極簡單 (無乘除)、足夠遊戲手感、避免誤判 |
| 線性遍歷 | O(N) 檢測所有存活子彈 | N≤50 時極快;大量子彈需空間分區 (Grid/QuadTree) |
range 稍小導致「漏判」(子彈擦邊不中) 遠好過「誤判」(明顯沒碰卻死),前者覺得難,後者覺得爛。refreshBullets 中檢測到碰撞先標記、再統一處理,避免遍歷中修改數組導致邏輯錯亂。killBullets 調用 initBullet(i) 實現對象池循環,而非創建新對象。Bullets(img, fw, fh, total, w, h) 建構子initBullets() 初始化池paint(g) 繪製全群refreshBullets(plane, needCollision) 幀更新入口killBullets(plane, range) 道具清屏此模式可直接擴展至粒子系統、敵機群管理,是 2D 遊戲高性能渲染邏輯的基石。