Episode 13: Movement

In episode 3 I gave an example of how the player might be moved around the screen, but this isn’t exactly what I ended up doing. While I initially had some directional movement functions, moveUp, moveDown, moveLeft, moveRight, I realized early on that this wasn’t really the best way to approach things. Before I explain why I had to change things, let’s take a look at how my moveUp function initially looked:

Now there’s nothing wrong with this code if you just want to have a sprite move around the screen. But what happens when you rotate the sprite?

The Rotation Problem

Think about it – when the player moves up, the player’s vessel is moving forward (because it’s facing up). But if enemy vessels are facing the opposite direction, then the moveUp function would move them backward.

One solution could have been to simply have the enemy moveUp and moveDown functions do the opposite of the player’s functions. I could have also just switched the calls to the moveUp and moveDown functions in the AI logic. But what if wanted to have a vessel that isn’t facing up or down? What if an enemy is flying in from the side?

If it hasn’t become obvious what needed to be done, think about this: does a car navigate using cardinal directions (north, south, east, and west)?

The answer could be yes, but it’s actually no. A car can’t really drive west. There’s no button or lever to pull that makes the car suddenly go west. The car does have a steering wheel and a gas pedal, which can be used to point the car west and then accelerate it, but the car’s actual functions in this case are turning and accelerating.

So this is what I needed to do to my vessels. I needed to give them functions that matched their actual abilities. A vessel doesn’t fly down, it flies forward. And when it flies left, it flies to its left, not to the left of a player overseeing its movements. Here’s what a moveForward function would look like (warning: math ahead):

You’re going to have to put your trigonometry hat on, but what we’re basically doing here is taking the sprite’s vector (direction and magnitude) and breaking it down into its x and y components, then applying those components to the sprite.

After I got this working I was super proud of myself for being smart, but this was followed by a lengthy period of feeling stupid. You see, there’s actually a problem with this code, but only because of the way I used engine stats to control the vessel’s maximum speeds.

Maximum Velocities

The problem is that there isn’t just one limit on how fast a vessel can travel, there’s two. Because engines have vertical and horizontal stats governing acceleration and max speed, vessels can actually max out their speed laterally without maxing out their vertical speed, which means each limit needs to be applied individually.

I have to admit, I was stumped. This is actually the first and only problem I ever posted on a forum (you can read the thread here)

Here’s how it ended up working (in general):

Now my vessels all moved properly no matter what direction they were facing! Hurray!

Leave a Reply