Today’s changes are an example of something that’s pretty simple to do, but which enhances the game experience quite a bit; scoring. This is a fleshed out version of the crude mechanism created in yesterday’s commits. Points properly accumulate per virus matched the way that they do in the original NES version of the game, with an added cascade bonus.
Viruses matched as part of a cascade have a multiplier attached to them that cause them to be worth more. Since the mechanism for scoring is simple, this means that you get the multiplier even if the cascade starts off with matches that contain no viruses. For now I like it that way because it provides a reward for setting up a cascade.
As a nice visual tweak, whenever a match happens, the traditional floating text appears to show you that you received points for doing something.
This is done via modifications to the bottle. The methods that used to return a boolean to tell you if they found a match or not now return either null or a stage location that represents where the match happened. Individual matches return the point exactly at the center of the matched segment (or null for no match) and when multiple matches happen, the centroid is calculated for the points so that the location is centralized to all of the matches.
This match location is passed back to the game scene as part of the match information along with the number of viruses and the cascade level. A new entity called FloatingText is used to display the actual score data. Essentially this is just a simple entity that displays text centered horizontally and vertically around a point. Its update() method shifts it up the screen at some speed, and after a certain number of ticks, makes it invisible, which stops it from updating.
The scene itself maintains a list of such objects, which is initially empty. Every time a match happens it checks the list to find the first already created item that is currently not displaying anything and gives it a new text and position and makes it visible again. This stops us from creating a whole bunch of useless entities or from having to manage entities in a more complex way (removing them from the stage or doing our own update of them, etc).
I also fixed a little bug in the forced drop code. In being super lazy, I just made it try to drop the capsule once, and if that doesn’t work it would force the last drop time to be in the past so that the next update a regular drop would happen. However the problem with this is that if you just hold the down button, you can “freeze” the game because it keeps resetting the drop time, stopping the drop from actually happening.
I got slightly less lazy by implementing a boolean that indicates that a drop should be forced no matter what. I could have just extracted the code that does a drop and checks for a game over into a method and called that so it could be called from here and from the update loop, but this way there is a mechanism already in place if we want to make drops happen sooner than scheduled, for some reason.
The last change is that debug mode is now a toggle. It’s off by default, and pressing F1 toggles debug mode on and off. In debug mode the traditional list of segments appears and you can modify the contents of the bottle; automated dropping of the capsule is also stopped by setting the drop speed super high. There is a quick flash of this happening in the screen capture above.
I’m reaching the limits of what I can add to this particular prototype without fleshing it out more into a full game project, so the next tasks will be to add a list of the next capsule or capsules that will be dropping and probably an actual game start/game over screen just to show how scene changes work in my “engine”.
After that I think I will go on with fleshing out the engine a little bit to handle preloading images and handling sound and music playback as well, because I’ve been wanting to do that for a while now.