Next, we will eliminate it.
The elimination is divided into two steps. The first step is to remove the selected ball, and the second step is to land.
Eliminate first,
In ballactionlistener, perform branch processing.
1 public void actionPerformed(ActionEvent e) {2 Game game = Game.getInstance();3 if (game.isSelectedBall(x, y)) {4 game.destroySelectedBalls();5 } else {6 game.startSelect(x, y);7 }8 EventDispatcher.send(Event.UPDATE_BALLS);9 }
Then implement the two new methods:
Isselectedball (INT, INT) and destroyselectedbballs ()
1 public boolean isSelectedBall(int x, int y) { 2 return grid.balls[y][x].selected && marked.size() > 1; 3 } 4 5 public void destroySelectedBalls() { 6 Set<Integer> set = marked.keySet(); 7 Iterator<Integer> iterator = set.iterator(); 8 while (iterator.hasNext()) { 9 Integer key = iterator.next();10 grid.balls[key / 12][key % 12].destroyed = true;11 }12 marked.clear();13 }
Then update the display part and perform special processing on the destroyed ball.
Modify mainframe. Render:
1 public void render() { 2 Ball[][] balls = Game.getInstance().grid.balls; 3 for (int y = 0; y < 12; y++) { 4 for (int x = 0; x < 12; x++) { 5 if (balls[y][x].destroyed) { 6 this.balls[y][x].setBorder(null); 7 this.balls[y][x].setIcon(null); 8 continue; 9 }10 if (balls[y][x].selected) {11 this.balls[y][x].setBorder(BorderFactory12 .createLineBorder(Color.CYAN));13 } else {14 this.balls[y][x].setBorder(null);15 }16 this.balls[y][x].setIcon(balls[y][x].color.getImageIcon());17 this.balls[y][x].invalidate();18 }19 }20 }
So far, the elimination action has been completed.
Then, start landing.
When you land, you need to float up all the cleared spaces until all the colored spaces are flushed.
The algorithm is to traverse from the bottom right to the top left of the row based on the first column and then float up when a blank cell is encountered until the current cell is no longer a blank cell. In addition, it is necessary to prevent infinite loops. The Code is as follows:
1 public void fallDown() { 2 for (int x = 11; x >= 0; x--) { 3 for (int y = 11; y >= 0; y--) { 4 while (swapLine(x, y)) 5 ; 6 } 7 } 8 } 9 10 private boolean swapLine(int x, int y) {11 boolean frozen = false;12 if (grid.balls[y][x].destroyed) {13 for (int i = y; i > 0; i--) {14 frozen |= bubbleUp(x, i);15 }16 }17 return frozen;18 }19 20 private boolean bubbleUp(int x, int y) {21 Ball temp = grid.balls[y][x];22 grid.balls[y][x] = grid.balls[y - 1][x];23 grid.balls[y - 1][x] = temp;24 return !grid.balls[y][x].destroyed;25 }
Then, if a vertical column is left blank, it should be folded to the right. Likewise, you should avoid endless loops.
1 public void alignRight() { 2 int emptyColumnIndex = -1; 3 while (true) { 4 emptyColumnIndex = getEmptyColumnIndex(); 5 if (emptyColumnIndex == -1) { 6 break; 7 } 8 moveColumnRight(emptyColumnIndex); 9 }10 }11 12 private int getEmptyColumnIndex() {13 for (int x = 1; x < 11; x++) {14 if (isEmptyColumn(x) && !isEmptyColumn(x - 1)) {15 System.out.println("empty@" + x);16 return x;17 }18 }19 return -1;20 }21 22 private void moveColumnRight(int x) {23 for (int i = x; i > 0; i--) {24 for (int y = 0; y < 12; y++) {25 grid.balls[y][i] = grid.balls[y][i - 1];26 }27 }28 for (int y = 0; y < 12; y++) {29 grid.balls[y][0].destroyed = true;30 }31 }32 33 private boolean isEmptyColumn(int x) {34 for (int y = 0; y < 12; y++) {35 if (!grid.balls[y][x].destroyed) {36 return false;37 }38 }39 return true;40 }
So far, the elimination of the same color ball has been completed.
However, we found that there are still the following problems:
1. gridbaglayout causes scattered display after the ball is eliminated.
2. No regret function.
3. Some algorithms are indeed inefficient.
4. The class below control is not used.
We will explain it step by step in subsequent chapters.