JavaFx 2.0 block game animation / code design

To preserve my programming skills, I recently created a Java version of this game (Block blaster) using JavaFx 2.0. Since this was only for me, there was no real thought about software templates or design, and so all of the game logic ended up in GUI classes that became more and more bloated as I added functions. Finally, I decided to reorganize the code base to separate the game logic and model from the presentation (GUI).

After some research, I decided to use something like MVC or MVP. At the same time, I decided that the animations (the block slides along the game grid at startup, the blocks flash as they are removed from the game, etc.) should be part of the view layer.

The problem this causes is that when the user starts the block and the controller tells the view to move the block, it creates a JavaFx timeline for the animation and calls timeline.play() . This does not stop the program from executing in the view during the animation, so the view method returns just by starting the animation, which means that the controller goes to checks to see if the block has created a group of blocks. and if so, removes them before the move animation gets anywhere.

In the old (dirty) implementation, I used timeline.onFinish to call a check for a group of blocks as soon as the animation was complete, but since the timeline now in the view and the check function in the controller, I don’t know how to put this in my new design.

Is there a way to wait for JavaFx animations to complete (without a sleeping application thread), or is there another design pattern I should use to help avoid these problems?

Controller Code

 public void fire() { //Get the current column the launcher is in. int x = launcher.getX(), startY = launcher.getY(); //Find the next available block in the column. int endY; for(endY = h; endY > 0 && blockMap[endY - 1][x] == null; endY--){} //Create a new block of the same colour and location as that on the launcher. addBlock(x, launcher.getY(), getCurrentColourAndRotate()); //Move the block in the GUI and model (this will trigger the animation in the GUI) moveBlock(x, startY, x, endY); //Remove any block groups that have been made. checkBlock(blockMap[endY][x]); //Remove any blocks now not connected to the top of the game grid removeUnconnectedBlocks(); } 

Game screenshot

Sample game picture
(source: myhappygames.com )

+4
source share
1 answer

OK, so this was done in a hurry, but assuming that the block is the square you click, and Group is a collection of 3 or more adjacent blocks with the same color as in my drawing, then the problem is, with which you find that you do too much in the same method.

enter image description here

enter image description here

When you press a block, you must notify your controller. This should decide if this is part of the group, and if so, is the group set on fire? (I am not familiar with the terminology). Then the blocks in this group must be assigned a new state, for example ON_FIRE. The model will notify all observers that these blocks are now ON_FIRE. As soon as View gets this information, you will do ON_FIRE animation, crash or whatever. When this is completed, which should correspond to timeLine.onFinnish , you now call the next method in the controller, for example completedBurning . Now it will be responsible for cleaning and indirectly triggering new things.

Hope this makes sense.

Class diagram

+6
source

Source: https://habr.com/ru/post/1445277/


All Articles