I originally started out this Devember day by deciding that I would do a little bit more cleanup before proceeding to the task at hand. Specifically, I wanted to modify things so that the Maze contents only include the actual contents and not the outside walls as well, since we can’t interact with them anyway. This led me down a bit of a rabbit hole that I didn’t like, so I stashed those changes (literally; thanks git!) and went ahead with what I was planning on doing. Now we can do things like this:
What we’re seeing here is some new logic whereby every time a ball finishes moving through the maze, we run a check to see if all possible moves have been made or not. If they have, we vanish away all of the gray bricks. What should happen next is that all remaining balls in the maze get one last chance to move before being scored, but due to my false start I didn’t quite get that far today.
The theory behind how this works is simple since our code already knows when it has decided a ball is no longer moving. However visually it is more pleasing that the vanish of the gray bricks not start until the ball vanishes (if it’s going to), so things get a little more tricky. This requires some logic for being able to detect when a ball is finished playing a vanish animation.
The first changes made were to modify the Brick and Ball entities so that they both conform to a new Interface that provides a hidden state and the ability to hide or show the entity by way of standard method calls that cause them to play the appropriate animation. This cleans up a lot of code in the Maze entity that was crudely checking what animations were playing in the cells to know if they were hidden or not (as well as telling them to play specific animations), so that is some clean up we got for free.
Additionally, ActorPool has been enhanced to be able to give you the list of currently live entities. This is so that we can quickly scan through only the Ball, gray Brick entities or Bonus brick entities (this is why they are all stored in their own pools) to perform a check to see if they’re visible or not. Any entity which thinks it is hidden and whose animation is no longer playing is truly hidden (as opposed to still vanishing, for example).
I also implemented an entity reaper specific to pools of objects that conform to the new hide-able interface. This allows us to scan through all of the live entities in any given ActorPool and check to see if they think they are hidden or not. Using the criteria above we can kill any of them that are fully hidden and remove them from the maze. By returning the count of objects that are killed in this manner, we can detect when the ball animation is finished playing.
In order to see if there are any moves available, we just have to scan the top row of the maze; if all of the cells in the top row are empty, then all of the balls have moved, so we know that there are no moves available. In the case where there is a ball there, we do a supplemental check to see if the cell under that ball is something that would block the ball from moving, so that we know if it’s possible to actually push the ball or not.
As written the code populates a boolean value when the gray bricks have finished vanishing, which would be used to trigger the last stage of the logic, whereby we drop all balls still in the maze one at a time, starting from the bottom and moving upwards, to give them one last chance to move after the gray bricks are gone.
That shall be the task for tomorrow, possibly with some additional cleanup to the debugging code. Some of it is redundant now that hidden objects actually removed from the maze after they are finished vanishing.