How to Curve your Bullets In 3 Easy Steps (Using JavaScript)

Adam Emrich
5 min readFeb 2, 2017

In our second week of JavaScript here at the Flatiron School, the instructors sorted us into pairs and told us to spend a couple days creating a JavaScript game. After some brainstorming, we settled on the perfect game to make — a simple version of Gunbound, the popular 2D tank battle game:

Gunbound Highlight Reel

We set out to create our game — and quickly ran into a roadblock. In our class, we had created simple games where projectiles moved in straight lines, but we had never made a game where the projectile path curved. How could we make this happen in our game?

After some trial-and-error, we came up with an easy, 3-step process for implementing curved projectiles:

First, figure out the firing angle of the projectile

Second, separate out the projectile’s velocity into horizontal and vertical velocities (using the projectile’s firing angle)

Third, make “gravity” act on the projectile as it flies across the screen

Here are more details on the steps.

1. Figure Out Your Projectile’s Firing Angle

Your projectile’s firing angle determines its path. Determining its angle depends on how you fire projectiles in your game, but in our game our projectile angle was determined by our gun angle, so we pulled it from there, like so:

So, we passed the firing angle from the gun onto the projectile, giving us something like this:

From here, we should figure out our projectile’s flight path by separating it into horizontal and vertical velocities.

2. Separate the Projectile’s Velocity into Horizontal and Vertical Elements

This part takes a bit of math. But don’t be scared! It’s just some simple high school trigonometry.

So, what we have so far is our projectile’s firing angle. With the use of Sine and Cosine (hello, high school math!) and the projectile’s velocity, we can plot out the projectile’s flight path.

Luckily, in our program we already pass the projectile velocity into our projectile (from the gun class). So, all we have to do is plug our projectile’s firing angle and velocity into some simple equations in order to separate them into horizontal and vertical velocities.

Note: We have to convert the angle from degrees to Radians for Math.sin. We do that in this.angleInRadians with the pi*angle/180. The 90-angle is to match our gun’s x-y grid to our window’s x-y.

What this has done is separate our overall velocity into its horizontal and vertical velocities, giving us a way to represent its path pixel by pixel in HTML.

So, with these horizontal and vertical velocities, we can create a moveProjectile() function for plotting how our projectile moves across our space:

With this moveProjectile() function, our projectile moves like this:

This is great! It’s not quite the nice curve we wanted, but we can take care of that in the next step.

3. Make “gravity” act on the projectile as it flies across the screen

Now we’re in the final step — making gravity act on the projectile as it flies across the screen.

In order to do this, we have to do two things: (a) we need to keep track of how long the projectile has been in the air, and (b) we have to change the vertical velocity because of gravity.

Here’s how we did it

#1: Instantiating the Projectile with timeInAir = 0
#2: Changing vertical velocity with gravity
#3: Incrementing timeInAir as our projectile flies

That’s it! That’s all we need to add a curve to our projectile’s flight.

One thing to note here: we chose to increment our timeInAir by 1/60 because requestAnimationFrame refreshes 60 times per second in Chrome, but you could choose any number you want here, as long as you adjust the gravity variable in order to make it look realistic in your game.

Here’s how our game looks now:

It’s no match for Gunbound, but it could maybe give Tank Wars (from 1990) a run for its money:

Tank Wars (1990)

So, now you know how to add a curve to your projectile’s path in a simple JavaScript game! Congrats.

One potentially major note: if you’re appending your projectile onto your gun, and then firing it from there you might see a projectile path that looks a little bit like this:

Not only is this an ugly path (that doesn’t fly the way projectiles really do), it also doesn’t register as a hit on the enemy tank. This happens because the program determines the projectile’s angle relative to the gun div. If the gun div is rotated when the projectile fires the program essentially double counts the angle, leading to the weird result we saw above. To get rid of this, reset the gun’s angle before you fire the projectile, like so:

Alternatively, you can fix this more elegantly by doing something like appending the projectile onto the tank, rather than the gun div. Up to you.

If you want to check out more, check out our repo at https://github.com/jkhoang313/gunbound.

Play our game! Visit https://jkhoang313.github.io/gunbound/.

--

--