本文實作三大遊戲輔助系統:
private long gameTime = 0; // 遊戲已用秒數
private long gameTimeOffset = 0; // 起始時間戳 (ms)
public void onGameStart() {
gameTime = 0;
gameTimeOffset = System.currentTimeMillis();
}
public void updateTimer() {
if (!gameOver) {
gameTime = (System.currentTimeMillis() - gameTimeOffset) / 1000; // 轉秒
}
}
private long pauseStartTime = 0;
public void onPause() {
if (!gameOver) {
pauseStartTime = System.currentTimeMillis();
}
}
public void onResume() {
if (!gameOver && pauseStartTime > 0) {
// 補償暫停耗時
gameTimeOffset += (System.currentTimeMillis() - pauseStartTime);
pauseStartTime = 0;
}
}
使用預製數字圖集 (b_number.png,每字符 10x15 像素) 繪製,避免系統字體大小不一、不支持對齊等問題。
// 初始化 (載入一次)
private BitmapFont fontBig;
fontBig = new BitmapFont(g, Image.createImage("/pic/b_number.png"),
10, 15, "0123456789".toCharArray());
// 繪製 (每幀)
fontBig.drawString(String.valueOf(gameTime), screenWidth/2 - 15, 10);
BitmapFont 關鍵方法:
drawString(String, int x, int y):逐字符查表繪製 drawRegionREWARD_INTERVAL = 20 秒MAX_REWARDS = 5 (對應 100 秒內)boolean[] rewardClaimed 標記各區間是否已領
private static final int REWARD_INTERVAL = 20;
private static final int MAX_REWARDS = 5;
private boolean[] rewardClaimed = new boolean[MAX_REWARDS];
private int bombCount = 0;
private int[] rewardAmount = {1, 1, 1, 1, 1}; // 每次給 1 個
public void checkTimeRewards() {
int intervalIndex = (int) (gameTime / REWARD_INTERVAL); // 當前區間索引
if (intervalIndex >= MAX_REWARDS) intervalIndex = MAX_REWARDS - 1;
if (!rewardClaimed[intervalIndex]) {
bombCount += rewardAmount[intervalIndex];
rewardClaimed[intervalIndex] = true;
// 可觸發音效/特效提示玩家
playSound("reward");
}
}
調用時機:在 updateTimer() 後調用,確保每秒檢查一次。
public final class GameEvaluator {
private GameEvaluator() {} // 工具類禁止實例化
public static String getTimeEvaluation(long gameTimeSeconds) {
if (gameTimeSeconds < 10) {
return "Do you play with your foot?";
} else if (gameTimeSeconds < 16) {
return "Come on, you can do it!";
} else if (gameTimeSeconds < 20) {
return "What a pity! Try again.";
} else if (gameTimeSeconds < 25) {
return "Very well, you are a real pro.";
} else if (gameTimeSeconds < 30) {
return "I know you have talent for this game.";
} else if (gameTimeSeconds < 40) {
return "I can't believe it, you are a game master.";
} else {
return "Oh my god, are you human?";
}
}
}
public void onGameOver() {
gameOver = true;
String evaluation = GameEvaluator.getTimeEvaluation(gameTime);
// 使用系統字體繪製多行文本 (或位圖字體)
g.drawString(evaluation, 5, 22, Graphics.LEFT | Graphics.TOP);
// 同時顯示最終用時
fontBig.drawString(String.valueOf(gameTime), screenWidth/2 - 15, 10);
}
public void gameLoop() {
while (running) {
long frameStart = System.currentTimeMillis();
handleInput();
updateGameLogic(); // 移動、碰撞、AI...
// 計時系統
if (!gameOver) {
updateTimer();
checkTimeRewards();
}
renderFrame(g);
flushGraphics();
// 幀率控制
long elapsed = System.currentTimeMillis() - frameStart;
long sleep = FRAME_DELAY - elapsed;
if (sleep > 0) Thread.sleep(sleep);
}
}
| 維度 | 擴展點 |
|---|---|
| 計時器 | 毫秒級顯示、倒計時模式、網絡同步時間 (服務端權威) |
| 獎勵 | 動態間隔 (難度自適應)、多樣獎勵 (生命、護盾、分數倍率)、每日首次登錄獎勵 |
| 評價 | 多維度評分 (時間、分數、連擊、無傷) → 綜合等級 S/A/B/C/D、排行榜上傳、分享圖生成 |
| 本地化 | 評價文本外部化至資源包,支持多語言、文化適配 |
「計時器 + 時間獎勵 + 通關評價」三位一體,構成了輕量級遊戲的核心節奏調節回路:
代碼量極小 (核心 < 50 行),卻能顯著提升遊戲的「一局感」與留存動力,是休閒/動作類小遊戲的高性價比系統設計范例。