feared expected, getting our game done in time for the January 23rd deadline took precedence over writing about all the problems I ran into while making it. However, I will still record the experience here because keeping a record of my journey of discovery will help and inspire future generations of would-be game creators who already know how to program.
When I last left off, I had a cursor on screen, and a pandacat at a fixed location. My next step was to get the pandas to move. Since we knew a central part of gameplay was going to be coaxing animals around obstacles to a specific destination, Josh suggested I look into A* search. I vaguely recalled having studied A* in college and wound up following the excellent article A* Pathfinding for Beginners. The first hurdle I had to cross was deciding the level of detail for my A* grid: our game targets 720p and 1080p TV resolutions,1 but since this game has to run on a decent-but-not-amazing Android device which I have no way of testing with, I figured trying to search pixel-by-pixel was going to use more memory than we had available (not to mention time). I decided to pick an arbitrary reasonable size and landed on 160×90: I figured 10x the aspect ratio of 16:9 would probably give us enough detail.
So, uh, how do I keep track of where the animals can walk and where they can’t?
The LibGDX sample apps came to the rescue again: the Cuboc demo does something very clever to build its level map: it loads a PNG and builds its in-memory level information based on the color values of the pixels in the image. This is probably common practice for a lot of game-dev folks, but this was a new approach to me and struck me as very clever. So I copied it. I made a simple black-and-white image, 160×90 pixels, which showed roughly where the barriers were in our temporary game level. Then I just loaded it into a giant boolean array of arrays in memory (14,400 booleans doesn’t actually take up much memory, thankfully).
LibGDX by default counts Y values as increasing from the bottom, so (0, 0) is the bottom left corner, whereas in my image (0, 0) is the upper left, hence the weird Y subtraction.
Now that I knew which grid points where invalid, I could skip them when doing A* searching. Once I fixed a few2 bugs in my A* implementation, I could miraculously draw paths out of grid squares from an animal to an arbitrary location on screen, avoiding obstacles:
Now, I just had to figure out how to tell the animals to move along the path. This turned out to be quite a bit harder than expected, because as I soon learned, I couldn’t remember anything at all about geometry. Next time: VECTOR MATH.