Then, we can click the ball.
When you click a small ball, you can perform the following two steps: select the first step, and clear the second step.
This chapter first studies and selects.
First, we need to know the position of the clicked ball. However, the previous design did not include relevant parameters.
So we need to refactor ballactionlistener first.
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 Ballactionlistener Implements Actionlistener { 11 12 Int X; 13 Int Y; 14 15 Public Ballactionlistener ( Int X, Int Y ){ 16 This . X = X; 17 This . Y = Y; 18 } 19 20 @ Override 21 Public Void Actionreceivmed (actionevent e ){ 22 Game. getinstance (). startselect (x, y ); 23 Eventdispatcher. Send (event. update_bils ); 24 } 25 }
In this way, through X, Y can know the selected position, and through the selected position, select the adjacent same color ball (game. getinstance (). startselect (INT, INT )). Then update the display.
The processing of the selection, because we need to spread from the selected point to the surrounding area constantly looking for adjacent same color balls. Therefore, we create a map to store the balls of the same color and use a Boolean to indicate whether the ball has been traversed.
1Map <integer, Boolean> marked =NewHashmap <integer, Boolean> ();
The flag indicating that all data values in the map are true.
Then the selectedAlgorithmIt can be described as follows:
1 Public Void Startselect ( Int X, Int Y ){ 2 Clearmarkstate (); 3 Marked. Put (y * 12 + X, False ); 4 Integer key = y * 12 + X; 5 While (Key! = Null ){ 6 Markhomoneighbor (Key % 12, key/12 ); 7 Key = Getnextunselectedkey (); 8 } 9 }
The following three methods are required for implementation:
Clearmarkstate
1 Public Void Clearmarkstate (){ 2 Marked. Clear (); 3 For (Ball [] row: grid. bballs ){ 4 For (Ball ball: Row ){ 5 Ball. Marked = False ; 6 Ball. Selected = False ; 7 } 8 } 9 }
Markhomoneighbor
1 Public Void Markhomoneighbor ( Int X, Int Y ){ 2 Ball [] [] bballs = Grid. bils; 3 Bils [y] [X]. Marked = True ; 4 Bils [y] [X]. Selected = True ; 5 Marked. Put (y * 12 + X,True ); 6 If (X> 0 & bils [y] [x-1 ]. Color. Equals (bils [y] [X]. Color )){ 7 Bils [y] [x-1]. Marked = True ; 8 If (! Marked. containskey (y * 12 + X-1 )){ 9 Marked. Put (y * 12 + X-1, False ); 10 } 11 } 12 If (X <11 & bils [y] [x + 1 ]. Color. Equals (bils [y] [X]. Color )){ 13 Bils [y] [x + 1]. Marked = True ; 14 If (! Marked. containskey (y * 12 + x + 1 )){ 15 Marked. Put (y * 12 + x + 1, False ); 16 } 17 } 18 If (Y> 0 & bils [Y-1 ] [X]. color. Equals (bils [y] [X]. Color )){ 19 Bils [Y-1] [X]. Marked = True ; 20 If (! Marked. containskey (Y-1) * 12 + X )){ 21 Marked. Put (Y-1) * 12 + X, False ); 22 } 23 } 24 If (Y <11 & bils [Y + 1 ] [X]. color. Equals (bils [y] [X]. Color )){ 25 Bils [Y + 1] [X]. Marked = True ; 26 If (! Marked. containskey (Y + 1) * 12 + X )){ 27 Marked. Put (Y + 1) * 12 + X, False ); 28 } 29 } 30 }
Getnextunselectedkey
1 Private Integer getnextunselectedkey (){ 2 Set <integer> set = Marked. keyset (); 3 Iterator <integer> iterator = Set. iterator (); 4 While (Iterator. hasnext ()){ 5 Integer key = Iterator. Next (); 6 If (Marked. Get (key) = False ){ 7 Return Key; 8 } 9 } 10 Return Null ; 11 }
AboveCodeMarked and selected variables are generated during writing.
Note: The above code can also be implemented using recursive calls, and the code is more concise.
Then the display processing is added to the original mainframe. Render processing.
1If(Bils [y] [X]. Selected ){2This. Bils [y] [X]. setborder (borderfactory3 . Createlineborder (color. Cyan ));4}Else{5This. Bils [y] [X]. setborder (Null);6}
In this way, the selected operation can be processed, as shown in.