以「指法練習遊戲」為載體,完整演示 JBuilder 2005 開發 Applet 全生命週期:GUI 設計、動畫執行緒、聲音播放、事件處理、多執行緒、I/O 存檔、JAR 打包、數位簽名、JRE 插件部署、JDK 5.0 新特性應用。
TypeTrainApplet (主類別, 繼承 JApplet)
├── UI 初始化 (init)
│ ├── Canvas 畫布 (10 欄位)
│ ├── 控制按鈕:開始/暫停、停止
│ └── 計分/等級顯示
├── DropCharThread (內部類別, 繼承 Thread)
│ ├── 隨機字母、指定欄位、下落速度
│ ├── 繪製字符、碰撞檢測、計分邏輯
│ └── 睡眠控制動畫幀率
├── 聲音管理 (AudioClip)
│ ├── 撞擊音、錯誤音、關卡升級音
│ └── Applet.getAudioClip() 載入
├── 狀態持久化
│ ├── 最高分寫入本地檔案 (簽名後可存取)
│ └── 讀取歷史記錄
└── 數位簽名與部署
├── JAR 打包 → keytool 生成密鑰 → jarsigner 簽名
└── HTMLConverter 轉換 → 部署含 JRE 自動安裝標籤
class DropCharThread extends Thread {
private final int column; // 所屬欄位
private char currentChar; // 當前下落字符
private int yPos = 0; // Y 座標
private final int speed; // 下落速度 (ms/幀)
public void run() {
while (!isInterrupted() && yPos < canvasHeight) {
// 繪製邏輯在 paint() 中統一處理,這裡只更新狀態
yPos += step;
if (hitDetected()) { score++; interrupt(); }
try { sleep(speed); } catch (InterruptedException e) { break; }
}
}
}
設計理由:內部類別直接存取外部類欄位,減少跨類別通訊複雜度;每個下落字母一條執行緒,簡化同步邏輯。
private Image offscreenImage;
private Graphics offscreenGraphics;
public void update(Graphics g) { paint(g); } // 禁用預設清屏
public void paint(Graphics g) {
if (offscreenImage == null) {
offscreenImage = createImage(getWidth(), getHeight());
offscreenGraphics = offscreenImage.getGraphics();
}
// 1. 清背景
offscreenGraphics.setColor(Color.BLACK);
offscreenGraphics.fillRect(0, 0, getWidth(), getHeight());
// 2. 繪製所有下落字符、分隔線、分數
for (DropCharThread t : activeThreads) {
offscreenGraphics.drawString(String.valueOf(t.currentChar), t.columnX, t.yPos);
}
// 3. 一次性翻轉到螢幕
g.drawImage(offscreenImage, 0, 0, this);
}
| 階段 | 操作 | 工具/命令 |
|---|---|---|
| 1. 打包 | 將所有 .class、圖片、聲音打成 JAR | JBuilder Deployment Wizard / jar cvf game.jar * |
| 2. 生成密鑰 | 建立 keystore、產生公私鑰對 | keytool -genkey -alias mykey -keystore mykeystore |
| 3. 簽名 | 用私鑰簽署 JAR | jarsigner -keystore mykeystore game.jar mykey |
| 4. 驗證 | 確認簽名有效 | jarsigner -verify -verbose game.jar |
簽名後 Applet 可獲得:本地檔案讀寫、網路連線、系統屬性讀取、系統剪貼簿存取等權限(IE/舊版瀏覽器需匯入信任憑證)。
// 原始 HTML
<applet code="TypeTrainApplet.class" archive="game.jar" width="600" height="400"></applet>
// 執行轉換 (JDK 附贈)
HtmlConverter.exe -source index.html -target deploy -latest -standard
// 產出 deploy/index.html 包含:
// <object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" ...>
// <param name="code" value="TypeTrainApplet">
// <param name="archive" value="game.jar">
// <!-- 自動提示用戶安裝指定版本 JRE -->
// </object>
List<DropCharThread> threads = new ArrayList<>(); 型別安全for (DropCharThread t : threads) ...int score = 0; score++; 無缺轉換import static java.lang.Math.*; 簡化數學呼叫enum GameState { RUNNING, PAUSED, STOPPED } 狀態機更清晰Applet 技術已隨瀏覽器移除 NPAPI 支援而退出歷史舞台(JDK 9 標記棄用,JDK 11 移除)。現代替代方案:
但本專案涵蓋的「遊戲迴圈、狀態機、資源管理、多執行緒繪圖、聲音同步、持久化、安全部署」核心技能,在任何平台遊戲開發中通用。