一步一步写自表达代码——消小球(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许可。
-----------------------------------------------------------------
现为独立咨询师。为软件企业或者其他企业的软件采购部门提供咨询,帮助改进软件开发流程,员工技术能力提升,以帮助企业在质量成本交货期三方面得到改善。