雖然主流大型遊戲多由 C/C++ 開發,但 Java 擁有跨平台、記憶體安全、豐富多媒體 API 等優勢,非常適合網頁嵌入式小遊戲、教學原型與獨立遊戲開發。本教學以 Applet 為載體(現代可轉向 JavaFX/LibGDX),循序漸進構建「保衛者」彈珠遊戲,涵蓋執行緒動畫、雙緩衝、多媒體、事件處理等核心技術。
| 方法 | 觸發時機 | 用途 |
|---|---|---|
| init() | 載入時一次 | 初始化組件、載入資源 |
| start() | 頁面顯示/恢復 | 啟動動畫執行緒 |
| stop() | 頁面隱藏 | 暫停耗資源工作 |
| destroy() | 卸載時 | 釋放資源、移除監聽器 |
| paint(Graphics) | 需重繪時 | 繪製遊戲畫面 |
public class Ball extends Applet implements Runnable {
Thread animator;
int x = 100, y = 20, r = 10, ySpeed = 1;
public void start() {
animator = new Thread(this);
animator.start();
}
public void run() {
while (true) {
y += ySpeed; // 更新邏輯
repaint(); // 觸發重繪
try { Thread.sleep(20); } catch (InterruptedException e) {}
}
}
public void paint(Graphics g) {
g.setColor(Color.BLUE);
g.fillOval(x, y, 2*r, 2*r);
}
}
關鍵點:repaint() → AWT 執行緒呼叫 update() → 清屏 + 呼叫 paint()。若無 sleep(),CPU 會跑滿且畫面來不及顯示。
預設 update() 先清屏再畫,造成閃爍。解決方案:離屏繪圖至 Image,再一次性貼上螢幕。
private Image offscreenImage;
private Graphics offscreenGraphics;
public void update(Graphics g) {
// 初始化離屏緩衝區
if (offscreenImage == null) {
offscreenImage = createImage(getWidth(), getHeight());
offscreenGraphics = offscreenImage.getGraphics();
}
// 後台清屏與繪圖
offscreenGraphics.setColor(getBackground());
offscreenGraphics.fillRect(0, 0, getWidth(), getHeight());
offscreenGraphics.setColor(getForeground());
paint(offscreenGraphics); // 重用 paint 邏輯
// 前台一次性貼圖
g.drawImage(offscreenImage, 0, 0, this);
}
public class GameApplet extends Applet implements MouseListener {
public void init() { addMouseListener(this); }
public void destroy() { removeMouseListener(this); }
public void mousePressed(MouseEvent e) {
// 例:點擊反彈小球
ySpeed = -Math.abs(ySpeed);
}
// 需實作介面所有方法(可留空)
public void mouseClicked(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
}
KeyListener| 格式 | 適用場景 | 載入方式 |
|---|---|---|
| WAV/AU/AIFF | 短音效 | getAudioClip(url) / Applet.newAudioClip(url) |
| MIDI | 背景音樂 | 需 Java Sound API (JDK 1.3+) |
| GIF/JPG/PNG | 圖像/幀動畫 | getImage(url) + drawImage() |
// 聲音範例
AudioClip bounceSound = getAudioClip(getCodeBase(), "bounce.wav");
bounceSound.play(); // 或 loop()、stop()
// 圖片動畫幀
Image[] frames = new Image[8];
for (int i = 0; i < 8; i++)
frames[i] = getImage(getCodeBase(), "frame" + i + ".gif");
init() 載入聲音/圖片、啟動滑鼠監聽、建立初始炸彈陣列start() 啟動動畫執行緒 → run() 週期性呼叫 bomb.down() 更新位置 → repaint()paint() 遍歷炸彈呼叫 drawBomb(g)、繪製分數/生命值mousePressed() 判斷座標是否命中炸彈 → 命中則 bomb.rebound() + 加分,未命中炸彈落地 → 扣命 + 播放音效從一顆下落的小球,到具備物理反彈、音效回饋、分數系統的完整遊戲,Java 提供了豐富的標準 API 讓創意落地。雖然 Applet 已退出歷史舞台,但本文涵蓋的遊戲迴圈、雙緩衝、事件驅動、資源管理、狀態機等核心概念,在 JavaFX、LibGDX、LWJGL 等現代框架中依然通用。建議讀者以此為基礎,嘗試重寫為 JavaFX 應用程式,體驗現代圖形管線的威力。