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

接上节我们发现的遗留问题。

先来解决GridBagLayout的问题。

MainFrame.build方法修改如下:

 1     public void build() {

 2         this.setLayout(null);

 3         this.setSize(480, 480);

 4         balls = new JButton[12][12];

 5 

 6         for (int y = 0; y < 12; y++) {

 7             for (int x = 0; x < 12; x++) {

 8                 JButton ball = new JButton("");

 9                 ball.setSize(40, 40);

10                 this.add(ball);

11                 ball.setLocation(x * 40, y * 40);

12                 ball.addActionListener(new BallActionListener(x, y));

13                 balls[y][x] = ball;

14             }

15         }

16     }

然后,增加统计分数功能,更新BallActionListener

 1     public void actionPerformed(ActionEvent e) {

 2         Game game = Game.getInstance();

 3         if (game.isSelectedBall(x, y)) {

 4             game.destroySelectedBalls();

 5             game.fallDown();

 6             game.alignRight();

 7             game.score.current += game.score.selected;

 8             game.score.selected = 0;

 9             if (game.score.highest < game.score.current) {

10                 game.score.highest = game.score.current;

11             }

12         } else {

13             game.startSelect(x, y);

14             game.score.selected = game.countSelectedScore();

15         }

16         EventDispatcher.send(Event.UPDATE_BALLS);

17         EventDispatcher.send(Event.UPDATE_SCORES);

18     }

下面是其中的countSelectedScore()的具体实现:

 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 += selected;

 9                 }

10             }

11         }

12         return score;

13     }

然后增加后悔功能。

增加按钮以及相应的Listener。

然后在Grid类中增加backup,用来存放数据。

1     public Ball[][] backup = new Ball[12][12];

然后修改BallActionListener,当消除小球时,保存数据。

 1 public void actionPerformed(ActionEvent e) {

 2         Game game = Game.getInstance();

 3         if (game.isSelectedBall(x, y)) {

 4             game.backup();

 5             game.destroySelectedBalls();

 6             game.fallDown();

 7             game.alignRight();

 8             game.score.current += game.score.selected;

 9             game.score.selected = 0;

10             if (game.score.highest < game.score.current) {

11                 game.score.highest = game.score.current;

12             }

13         } else {

14             game.startSelect(x, y);

15             game.score.selected = game.countSelectedScore();

16         }

17         EventDispatcher.send(Event.UPDATE_BALLS);

18         EventDispatcher.send(Event.UPDATE_SCORES);

19     }

当点击后悔按钮时,恢复数据。

 1 package org.stephen.bubblebreaker.listener;

 2 

 3 import java.awt.event.ActionEvent;

 4 import java.awt.event.ActionListener;

 5 

 6 import org.stephen.bubblebreaker.control.EventDispatcher;

 7 import org.stephen.bubblebreaker.model.Event;

 8 import org.stephen.bubblebreaker.model.Game;

 9 

10 public class UndoActionListener implements ActionListener {

11 

12     @Override

13     public void actionPerformed(ActionEvent arg0) {

14         Game.getInstance().rollback();

15         EventDispatcher.send(Event.UPDATE_BALLS);

16         EventDispatcher.send(Event.UPDATE_SCORES);

17     }

18 

19 }

备份时应该备份界面和分数两者。

 1 public void backup() {

 2         for (int x = 0; x < 12; x++) {

 3             for (int y = 0; y < 12; y++) {

 4                 grid.backup[y][x].color = grid.balls[y][x].color;

 5                 grid.backup[y][x].destroyed = grid.balls[y][x].destroyed;

 6                 grid.backup[y][x].marked = grid.balls[y][x].marked;

 7                 grid.backup[y][x].selected = grid.balls[y][x].selected;

 8             }

 9         }

10         backupScore.current = score.current;

11         backupScore.selected = score.selected;

12         backupScore.highest = score.highest;

13         backupScore.playCount = score.playCount;

14         backupScore.average = score.average;

15     }

16 

17     public void rollback() {

18         for (int x = 0; x < 12; x++) {

19             for (int y = 0; y < 12; y++) {

20                 grid.balls[y][x].color = grid.backup[y][x].color;

21                 grid.balls[y][x].destroyed = grid.backup[y][x].destroyed;

22                 grid.balls[y][x].marked = grid.backup[y][x].marked;

23                 grid.balls[y][x].selected = grid.backup[y][x].selected;

24             }

25         }

26 

27     }

为实现上述功能,还需要一些相应的初始化操作。

Grid类:

1     public Grid() {

2 

3         for (int y = 0; y < 12; y++) {

4             for (int x = 0; x < 12; x++) {

5                 balls[y][x] = new Ball();

6                 backup[y][x] = new Ball();

7             }

8         }

9     }

Game类:

1     Score backupScore;

2     backupScore = new Score();

好的,又增加了两个功能。

然后实现一下清空功能

 1 package org.stephen.bubblebreaker.listener;

 2 

 3 import java.awt.event.ActionEvent;

 4 import java.awt.event.ActionListener;

 5 

 6 import org.stephen.bubblebreaker.control.EventDispatcher;

 7 import org.stephen.bubblebreaker.model.Event;

 8 import org.stephen.bubblebreaker.model.Game;

 9 import org.stephen.bubblebreaker.model.Score;

10 

11 public class ClearActionListener implements ActionListener {

12 

13     @Override

14     public void actionPerformed(ActionEvent e) {

15         // TODO show a dialog if possible.

16         Score score = Game.getInstance().score;

17         score.current = 0;

18         score.selected = 0;

19         score.highest = 0;

20         score.average = 0;

21         score.playCount = 0;

22 

23         EventDispatcher.send(Event.UPDATE_SCORES);

24     }

25 }

和退出功能:

 1 package org.stephen.bubblebreaker.listener;

 2 

 3 import java.awt.event.ActionEvent;

 4 import java.awt.event.ActionListener;

 5 

 6 public class ExitActionListener implements ActionListener {

 7 

 8     @Override

 9     public void actionPerformed(ActionEvent e) {

10         System.exit(0);

11     }

12 

13 }

 

在结尾的地方,我们继续优化一下代码:

1. 选中时应该考虑destroy标志。

2. 去掉Ball类中的无用变量x, y, state以及State定义。

 

 

 

你可能感兴趣的:(代码)