Projectile physics for dummies [WARNING: MATH!]

Posted by (twitter: @KatamoriENG)
April 23rd, 2014 2:02 am

I can still clearly remember, how many problem I had with making smooth-moving bodies  in my games back in the day, but I’ve improved a lot since, so I feel I have to share this knowledge.

The amazing fact that only midschool math needs for this stuff, so you are goddamn lucky, if you didn’t play Fruit Ninja or 2048 constantly during math classes. 😛

#1 the basic knowledge

Calculating the motion of any bodies needs to be able to calculate its positions in space. A coordinate-system is perfect for this, and you already get one all the time when you have a proper window on-screen. (my only experiences about it are Java and LÖVE2D, but I’m pretty sure it’s also true for every similar programming languages & environments)

In most cases, the (0,0) point on this is the upper left corner of that window.

#2 straight moving

So you have a window, and a body with some (x,y) coordinates. The texture that marks the body is displayed at (x,y) on the screen.

If you wanna move this body left, you have to substract a number (whatever you want) from X. To move right, you have to ADD a number  to X. Doing the same with Y makes the body move up (in case of substraction) or down (in case of addition).

It’s also the initial point of WASD moving in case of player characters: you have to give these commands to certain keys – giving special tasks for key-pressing actions vary on programming  languages & environments.

#3 straight moving, in any angles

Yeah, that’s fine yet, but if you want to move on a way that changes both X and Y, then you have to call the angles!

There’s a cool stuff that helps us called trigonometry. To use its rules, we need a triangle: the first one is (x,y), the second one is a random point that lies on that line your body will also lie while moving; the third one is that makes a right triangle from these points.

Let’s be more precise: make a body that follow the mouse cursor. Then you get (x,y) – the body – and (mouseX, mouseY) – the mouse. Two points CLEARLY defines a line; it’s gonna be the track of your body. To make it move, you have to know the slope of this line.

And THIS is where you need a triangle – the third point is (mouseX, y), and this with the line I mentioned forms a right triangle. And well, the slope of the line equals to the tangent of the angle at the body!

But hey, we have formulas to calculate it by division! It’s gonna be the Y distance between mouse and the body / the X distance between mouse and body. Okay, it’s a tangent value, but in the 21 century, you can easily calculate a tangent value back into degrees.

After that, moving the body on its track is not that hard – even understanding is kind of easy, but I suck at English, so I definitely wouldn’t try to explain it: add cos(slope) to body’s “x”, and also add sin(slope) to body’s “y” – I mention again, that the result of the division is NOT the slope itself, only its tangent. Theoretically, you can calculate sin and cos from tan without exchanging back into degrees, but I haven’t experimented with that.


A number in degrees/radian (I guess it matters only in LOVE2D) that has the next tangent: (mouseY – y) /( mouseX – x), assuming that all of them are positive numbers.


add the cosine of slope to “x” (body’s x coordinate)
add the sine of slope to “y” (body’s x coordinate)

#4 wind, gravity, and other vectors

I quickly realised that even without serious knowledge of linear algebra, you can simply use vectors. They are used in physics to show the amount and the direction of forces. They have 3 properties: an “x”, an “y”, and a “length”. x and y shows, where it pushes stuffs away, while length (which is calculated from x and y) shows, how strong it does that. in fact, I didn’t use it, because direction was more important for me.

Yeah, right, that’s fine, but how to use them? Well, it depends on that what do you want? In case of linear moving, without acceleration, just simply add VectorX to BodyX and also add VectorY to BodyX.

Example use: wind (though in my test I used acceleration for this, just for fun… :P), where WindVector has an y=0, and some x, that you have to add to or substract from BodyX. You already know the difference.

In case of acceleration, you have to store the increasing…ehm…”speed”. Well, yes, you actually store the speed.

Example use: gravity, where GravityVector has and x=0, and some y, and in every frame you have to do the next:

GravityAmount = GravityAmount + GravityVectorY
BodyY = BodyY + Gravity ( + sin(slope) of course)

In this case, there are two forces on your body: one that makes it move algonside a certain line, and one that does it in a straight down direction. The result is a parabola track and a mathematically (I guess?) precise implementation of vertical or oblique projection.

#5 endnote

I may be wrong in many aspects; one thing is sure: this method works amazingly well for me. I even hope that I used the right words; sadly I’m not familiar with “mathematical English”. Also, thanks for reading and have a successfull Ludum-ing!

– Katamori


Leave a Reply

You must be logged in to post a comment.

[cache: storing page]