Wednesday, September 4, 2013

Now with click detection and screen -> tile math


In which we learn that math is hard, and going to sleep is good.

Hex grids are cool, and they give me a frisson of strategy-geeky joy when I look at them. I was just chatting with my sister about hex grids, and she reminded me that an early influence on me (before the wilderness rules of Expert Dungeons and Dragons) was the game "Outdoor Survival" by Avalon Hill.

I remember playing a variety of starship battle games on the living room table with large hex maps and 1/2" cardboard counters. A buddy of mine at the time, Nathan, complained that a flat map didn't capture the full three-dimensionality of true space combat. "Oh, come on", I said, "you can stack the counters, surely that's three dimensional enough".

Those old hex maps used a numbering system where each hex had a 4 digit number printed on the map, going from 0000 to 2245, maybe. The first two digits were the column, and then the second two digits were the hex within that column. That's all fine for pencil-and-paper reference, but it becomes cumbersome for algorithmic computation of adjacent hexes. Quick! What hexes are near 1327? Well, 1326 and 1328, sure. And then 1227 and 1427. Um, 1226 and 1428? or 1228 and 1426? Could be either, depending on how the map was laid out. Bah!

Last summer, I made a hex-based RPG using this "offset coordinate" system, and I managed to make it work with a little modular arithmetic and a fair amount of special-case code. I never managed to get a distance calculation working, just adjacency. More recently, I stumbled across the Q-Bert coordinate system also known as the Cubic coordinate system, in which you put x and y 60 degrees apart, which makes the numbering really simple, but then you introduce a z coordinate such that x + y + z = 0. This doesn't seem like it adds anything, but once you have well behaved x,y,z coordinates, calculating distances on that surface is simple. Click either of the links above to see the math.

Ok, so I've got distances now. The next tricky bit is converting a position in screen space back to a tile. In my offset coordinate game last year, that was some involved math, with three different regions, a rectangle, some triangles, bleh. With the new cubic coordinates, I just reverse the code that I use to figure out the tile-to-screen positions, which wasn't all that hard, and then I use the rounding technique to clamp to a set of integer tile coordinates.

Along the way (and not terribly late last night, just later than I intended to be up), I added some debug code to my hex maze display to highlight my x, y, and z axes. I did this by checking to see if the x-coordinate was 0, and if so, color the hex red. If the y-coordinate was 0, color it blue, and if the z-coordinate was 0, yellow. It took me maybe a half hour to figure out that the y-axis was the collection of points where x was 0, and the x-axis was the collection of points where y was 0, which was why the blue hexes were a horizontal line, instead of the red hexes, like I had been expecting. Part of me knew this already, but my sleepy brain wasn't listening.

I think I've worked out the difficult bits of the math now, and I can click on tiles, and my current debug code lets you turn path tiles green by clicking on them. Hey, that's almost like gameplay. Solve a maze by drawing a path from one side of the screen to the other. Ok, it's self-directed gameplay - the computer doesn't give you any goals, or enforce any rules.

Still, if you like clicking on hexagons, it's got that.

No comments:

Post a Comment