一步一步写自表达代码——消小球(6)

好了,代码已经写到这里,基本功能都具备了,下面来进行一些收尾工作吧。

1. GameOver的判定。

首先在每次消除以后都进行GameOver判定。

1             if (game.isOver()) {
2                 EventDispatcher.send(Event.GAME_OVER);
3             }

然后实现GameOver判定算法。

 1     public boolean isOver() {
 2         for (int x = 0; x < ROW_COUNT; x++) {
 3             for (int y = 0; y < COLUMN_COUNT; y++) {
 4                 if (grid.balls[y][x].destroyed) {
 5                     continue;
 6                 }
 7                 markHomoNeighbor(x, y);
 8                 if (marked.size() > 1) {
 9                     return false;
10                 }
11                 clearMarkState();
12             }
13         }
14         return true;
15     }

最后,显示GameOver标签。

在GamePad类中增加

1         this.add(gameOver);
2         gameOver.setLocation(100, 300);
3         gameOver.setVisible(false);

并实现相应的GameOverFrame代码。

需要注意的是,由于GameOver是显示在最顶层的,所以在GamePad要先调用this.add();增加它。

 

2. 最后的奖励

    当消除到最后,剩余的小球数量不超过5个的时候给予分数奖励,每少1个,增加20分。

   

 1 public void addBonus() {
 2         int count = 0;
 3         for (int x = 0; x < ROW_COUNT; x++) {
 4             for (int y = 0; y < COLUMN_COUNT; y++) {
 5                 if (!grid.balls[y][x].destroyed) {
 6                     count++;
 7                 }
 8             }
 9         }
10         if (count < 5) {
11             score.current += (5 - count) * 20;
12         }
13         updateHighestScore();
14 
15     }
16 
17     public void updateHighestScore() {
18         if (score.highest < score.current) {
19             score.highest = score.current;
20         }
21     }

 

3. 分数的算式调整

   现在的累加分数太小,难以形成刺激玩家的动力。

   我们把累加的算法改进一下

   Sigma(n) = Accumulate(1) +.. Accumulate(n)

  

 1 public int countSelectedScore() {
 2         int selected = 0;
 3         int score = 0;
 4         for (int y = 0; y < 12; y++) {
 5             for (int x = 0; x < 12; x++) {
 6                 if (grid.balls[y][x].selected) {
 7                     selected++;
 8                     score += accumulate(selected + 1);
 9                 }
10             }
11         }
12         return score;
13     }
14 
15     private int accumulate(int x) {
16         int sum = 0;
17         for (int i = 0; i < x; i++) {
18             sum += i;
19         }
20         return sum;
21     }

 

4. 常量12,

   代码中用了大量的12这个常量,应该将其常量化,区分行和列。之所以到现在才处理是因为它的归属问题。

   现在我们把它放在Game类里。

1 public class Game {
2 
3     private static final int COLUMN_COUNT = 12;
4     private static final int ROW_COUNT = 12;
5 
6 }

5. 启动即开始

    取消EventDispatcher中的ControlFrame更新部分,默认Start按钮始终显示为Restart,并且启动即开始游戏。

1     public void startGame() {
2         shuffle();
3         score.clearCurrentScore();
4 
5         EventDispatcher.send(Event.UPDATE_BALLS);
6         EventDispatcher.send(Event.UPDATE_SCORES);
7     }

6. 点击已消除小球的分数

    点击已消除小球不应该有分数,但是程序中没有做相应处理。

public void startSelect(int x, int y) {
        clearMarkState();
        if (grid.balls[y][x].destroyed) {
            return;
        }
...

 

7.清空的时机

   只有在一局游戏结束之后才可以清空数据。

8. 其他一些小Bug和美化处理。

    略。

9.源代码下载:

   https://files.cnblogs.com/stephen-wang/BubbleBreaker.zip

   注意:整套源码采用Apache License 2.0许可。

posted @ 2012-11-27 19:32  史蒂芬.王  阅读(229)  评论(0编辑  收藏  举报