For the obsidian tower boss, a cat, I wanted to do something special because it’s the final boss of a fairly hard tower, so I made his movements unlike the movements of any other enemy in the whole app. This has led to some interesting challenges.
One of the most interesting is the single-tile movement which uses the same AI as regular enemies. Reusing that Breadth-First Search algorithm for part of the cat’s movement would be a great engineering design pattern. However, when I added the movement AI to the cat boss, it moved to the bottom-left corner of the room every time instead of toward the player.
I thought that there was some mistranslation between the boss room locations and the actual location of the player which caused the AI to think that the player is all the way to the bottom-left. After a bunch of playing around with the locations, I finally printed out what the AI thinks the locations are, and they seemed to match what was expected for the boss room.
Then I looked closer at the AI code and it clicked!
To understand why the cat boss was moving the way it did, I’ve drawn some diagrams to explain how the movement AI is working for all the other enemies in the app.
The movement AI always finds and takes the shortest route to the player. (You can see this in any of the skeleton enemy movement AI in the app.) For example, here is a potential path an enemy would take to the player. As you can see, it takes 5 moves to move next to the player to begin attacking them.
One additional feature I’ve added to the movement AI is that enemies cannot move on top of each other. For example, if there was an enemy already above the enemy in question, it might pick a path like this one. Notice this path is also only 5 moves away from the player making it equally as good as the previous path.
In this lies the root of the issue with the cat. The cat is the only enemy that is 2×2 tiles large. He gets in the way of himself, and I’m tracking the cat’s location using the bottom-left tile, so it calculates a path to the player like so:
As you can see, the cat is unable to move up or right because it recognizes that there is already an enemy there (which turns out to be himself), and is calculating a path around himself. This results in the cat only being able to move left or down, which eventually leads him to the bottom-left corner and trapping himself there.
To fix this issue, I’ve added a check to see if an enemy tile in the room is the same as the enemy that the movement AI is calculating for. If it is, we make it still a valid spot to move to.
And now the cat moves properly!
Leave a Reply