Step by step write self-expression code-elimination ball (2)

Source: Internet
Author: User

This chapter describes how to add actions to a game.

In general, there are many Java examples.ProgramLike to directlyCodeAdd:

Button. addactionlistener (New actionlistener () {public void upload maction (event e ){}});

Such code. This is not good, because it does not conform to the single responsibility principle. The actionlistener should be independent and separate into classes. In this way, it is easy to find when a problem occurs. There are two forms: one is the form of separate classes used in this article, and the other is to declare internal classes in the corresponding object. For example:

Class mybutton. actionlistener {}.

In general, we will add:

Startactionlistener, clearactionlistener, exitactionlistener, and ballactionlistener classes are bound to objects. Next, refine each action. During this period, we found that the jlabel of the small ball cannot be added to the actionlistener, So we changed it to a jbutton. This is very common in coding, that is, the design cannot be perfect during detailed design, problems can only be detected during encoding. This is also why we advocate that detailed design is not required. For details, refer to the waste in the software development process-Detailed Design

 

The process of binding and joining is omitted.

The first one is start. Start the game when you click Start. And the start button changes to restart, which indicates that the current Bureau is restarted.

The actions after start are as follows:

Generate a random ball game. getinstance (). Shuffle ();

Layout to game. getinstance (). gamepad. Main. Render ();

Clear the current score game. getinstance (). Score. Current = 0;

Game. getinstance (). Score. Selected = 0;

Refresh the score to display game. getinstance (). gamepad. helper. Render ();

Change the text of the Start button to restart game. getinstance (). gamepad. Control. Start. settext ("restart ");

According to the above Code, the following compilation problems will occur:

1. game does not contain the gamepad object.

2. Many variables are not public and cannot be accessed.

3. The render method is not declared in mainframe and helperframe.

4. The shuffle () method is not declared.

Indeed.Self-expressing code claims to first write the required operations in self-expressing mode, and then implement these operationsInstead of implementing some operations and then calling them.

In addition, the Code extracts game. getinstance () as a local variable.

However, we found that listener tries to update both the model layer and the view layer, and increases the code access permission. This is not a good method. Although the entire code can be implemented by following this method, the written method will combine the originally opened MVC structure. Therefore, in order to maintain separation, we do not adopt the above method, but introduce the message mechanism to send the message update UI when data is updated. When talking about this message mechanism, we should also mention that we should not abuse the message mechanism. message transmission is used for everything, because although the message mechanism can decouple code, it also reduces readability and comprehension.
So here, let's talk about it first. The message mechanism is only used for UI update.

Distribution explanation,

The code for startactionlistener is as follows:

 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 Startactionlistener Implements  Actionlistener {  11   12   @ Override  13       Public   Void  Actionreceivmed (actionevent e ){  14 Game = Game. getinstance (); 15   Game. Shuffle ();  16   Game. Score. clearcurrentscore ();  17 Game. State = Game. state. Playing;  18   19   Eventdispatcher. Send (event. update_bils );  20   Eventdispatcher. Send (event. update_scores );  21   Eventdispatcher. Send (event. update_buttons );  22  }  23 }

Game. Shuffle () indicates that a random ball is generated.

The Code is as follows:

 1   Public   Void  Shuffle (){  2           For ( Int Y = 0; y <12; y ++ ){  3               For ( Int X = 0; x <12; X ++ ){ 4 Grid. bils [y] [x] = New  Ball ();  5 Grid. bils [y] [X]. Color = ball. color. Values ()[( Int  ) (Math  6 . Random ()* Ball. color. Values (). Length)];  7 Grid. bils [y] [X]. x = X;  8 Grid. bils [y] [X]. Y = Y; 9 Grid. bils [y] [X]. State = Ball. state. normal;  10   }  11   }  12 }

However, ball. color changes are involved. Because the range of ball color values is limited, the color is changed to the custom internal enumeration color.

This enumeration is defined:

1 Public EnumColor {2 Red, green, blue, yellow, purple;3PublicImageicon getimageicon (){4Return NewImageicon ("image/" + name (). tolowercase () + ". PNG");5 }6}

It can be seen that the selected value range is red, green, blue, yellow, and purple, and each color is matched with an image. When you rearrange the image, you can obtain the relevant image by name and display it.

Then there is clearcurrentscore () of the score ();

1 Public VoidClearcurrentscore (){2Selected = 0;3Current = 0;4}

Then, game. State, which is an intermediate variable used to notify button changes, will also take effect at the end of the game.

 
1 Public EnumState {2 Stand_by, playing, game_over;3}

Followed by event and eventdispatcher

 1  Package  Org. Stephen. bubblebreaker. model;  2   3   Public   Class  Event {  4       Public   Static   Final   Int Update_bils = 0x1000 ;  5       Public   Static  Final   Int Update_scores = 0x1001 ;  6       Public   Static   Final   Int Update_buttons = 0x1002 ;  7 }

 

 1   Package  Org. Stephen. bubblebreaker. Control;  2   3  Import  Org. Stephen. bubblebreaker. model. event;  4   Import  Org. Stephen. bubblebreaker. model. game;  5   Import  Org. Stephen. bubblebreaker. View. gamepad;  6   7   Public   Class  Eventdispatcher {  8   9       Public  Static   Void Send ( Int  Event ){  10 Gamepad = Game. getinstance (). gamepad;  11           Switch  (Event ){  12           Case  Event. update_bils:  13   Gamepad. Main. Render ();  14              Break  ;  15           Case  Event. update_scores:  16   Gamepad. helper. Render ();  17               Break  ;  18           Case  Event. update_buttons:  19   Gamepad. Control. Render ();  20              Break  ;  21   }  22   }  23 }

Then start running, debugging, and find that there are still many bugs. First, the button boundary displayed at the start is not required and relevant code is deleted.

Then, the variables should be initialized during game initialization.

1PrivateGame (){2Grid =NewGrid ();3Score =NewScore ();4State =State. stand_by;5}

Game. gamepad should be assigned a value during gamepad initialization.

 
1PublicGamepad (){2Game. getinstance (). gamepad =This;3}

The variable declaration in grid should also be initialized.

 
1 PackageOrg. Stephen. bubblebreaker. model;2 3 Public ClassGrid {4 5PublicBall [] [] bballs =NewBall [12] [12];6}

Then the implementation of each render

Mainframe. Render ()

 1   Public   Void  Render (){ 2 Ball [] [] bballs = Game. getinstance (). Grid. bils;  3           For ( Int Y = 0; y <12; y ++ ){  4               For ( Int X = 0; x <12; X ++ ){  5                   This  . Bils [y] [X]. seticon (bils [y] [X]. color. getimageicon ());  6                  This  . Bils [y] [X]. invalidate ();  7   }  8   }  9 }

Helperframe. Render ()

 1       Public   Void  Render (){  2 Score = Game. getinstance (). Score;  3  Current. settext (string. valueof (score. Current ));  4   Selected. settext (string. valueof (score. Selected ));  5   Highest. settext (string. valueof (score. Highest ));  6   Average. settext (string. valueof (score. Average ));  7   Playcount. settext (string. valueof (score. playcount ));  8 }

At the same time, we found that the selected value in the old Code is not correctly assigned and modified together.

Controlframe. Render ()

1Public VoidRender (){2Game. State state =Game. getinstance (). State;3If(State =Game. state. Playing ){4Start. settext ("restart");5}Else{6Start. settext ("START");7 }8}

Then debug and correct the error.

Click Start on the following page:

In the next chapter, we will explain the implementation of ballactionlistener.

 

 

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.