Fusion - lots of math learning going on here

It's been 8 weeks since I announced Fusion. I really need to blog more. Maybe I should start to follow Chris Shiflett's Ideas of March blogging revival and dedicate this month to keeping up to date with this blog.

Anyway, in the past 8 weeks, Fusion has seen a lot of changes. The biggest change is dealing with ship rotation. The alpha-1 milestone of Fusion was almost exactly a Space Invaders clone, down to the pure up-down-left-right movement with no regards to rotation. While this works for the time being, I really needed to learn how to rotate objects.

The first part of this was the canvas element itself. I retooled Fusion to have objects and sprites be a little more loosely coupled, and gave more functionality to the sprites - animations, rotation, scaling, reflecting, etc. The rotation function was very simple to do using canvas.rotate, but the math turned out to be a lot harder to figure out.

I had to figure out a lot of calculations to align elements properly. Take for instance invader4 - it has three guns that fire simultaneously at the target; it has the main gun on the nose, and the two outermost wings have guns. I  had to calculate the following:

  • When spawning, use the pythagorean theorem to calculate distances from the center of the ship to the center of the three generators. Find the closest one. Then use Math.atan2() to calculate the angle, in radians, and rotate the ship to point in that direction.
  • Use Math.sin() and Math.cos() to figure out how far to move in the x-axis and y-axis so that the ship appears to be moving in a straight line towards its target.
  • Use pythagorean theorem again to determine when the target is in firing range.
  • Use Math.atan2() and pythagorean theorem to convert the weapon coordinates from cartesian to polar. Each invader contains an array of guns, with the coordinates stored as an x/y pair indicating where the gun is positioned on the sprite. But if a ship has been rotated, those cartesian coordinates are hard to work with, so I need to have them stored as polar coordinates.
  • Use Math.sin() and Math.cos() to figure out the actual location of the gun barrel using the polar coordinates and ship angle.
  • Use Math.atan2() to figure out the angle of the bullet. This was problematic with invader5 in particular because the wingspan is sometimes wider than the generator's profile, relative to the invader. This meant that at times, only the center bullet would hit. So I  had to adjust the bullet angles so that each gun fired directly at the target, rather than straight ahead. As a Tower Defense game, all AI controlled weapons should never miss their target.
  • Repeat all of the above in various ways to figure out the exact location and angle of the bullets and muzzle flashes so everything works smoothly together and has the appearance of a single gunshot.

It is very fun using trig again, even if sometimes I feel like I'm just changing numbers at random until it works. Since I've been purely a LAMP developer for 6  years (and a graphic artist prior to that), my math skills have gotten very rusty. I knew I needed to use fairly basic trigonometry to figure out coordinates, angles and distances, but I had a lot of work to do to remember exactly how to pull it off.

I managed to figure it out by creating a small tech demo as a tag in Fusion and the reincorporated it into the actual game. The tech demo turned out to be one of the better approaches in this project. By isolating the game down to the smallest components possible, I was able to reduce the amount of confusion and figure out the math properly. Once I figured it out in the tech demo, patching the actual game was trivial.

My current focus on Fusion is allowing the player to place turrets wherever they desire within a designated area. This will give a more Tower Defense style feel to the game, where the placement of turrets is a strategic decision left in the hands of the player. The next step is to have different kinds of turrets. George has already done some wonderful artwork for a variety of turrets, I just need to code them in. Hopefully it won't take 8 more weeks before I post again talking about it.