When I went to college to study computer programming, it was not with the intent of making video games. The school I attended required that you have a minor, and since computer programming was all I wanted to do at the time, I chose the one that required the least classes, Math.
Fast forward a couple years and I am sitting at my computer trying to think of how to handle getting an object to move to where it gets clicked. Little did I know how useful that math minor would be in tackling the problem.
The solution I have currently implemented relies on 2 things, the Euclidean Distance and the vector needed to move in the right direction.
Euclidean distance is a fancy way of saying distance between 2 things on a flat surface. The world is round so it is usually only accurate over small distances, but for a 2D video game, the world is completely flat so it works perfectly.
Don’t let this statement scare you, but it is basic trigonometry. As long as you know the X and Y coordinates of your 2 points, it is surprisingly simple to calculate.
You need the hypotenuse of a right triangle where the difference between the X coordinates of the 2 points is 1 side, and the difference between the Y coordinates of the 2 points is the other side.
The distance is then the square root of these sides squared and added together. You might know this formula by its more common name, the Pythagorean Theorem.
The Monkey code to calculate the distance between 2 points looks something like this:
Function Distance(point1:Point, point2:Point) Local xdelta:Float = point1.x - point2.x Local ydelta:Float = point1.y - point2.y Return Sqrt(xdelta * xdelta + ydelta * ydelta) End
So now that we know how far away our object is from its target point, how do we move it there?
This is actually a little bit simpler.
So lets assume our object has some speed that we want it to move at, for example I will use 4 pixels per update. So now when we touch or click on the screen, we want the object to start moving at 4 pixels per update towards the point we touched.
Determining what part of the speed is in the X direction and what part is in the Y direction is done by finding what part X and Y have in the distance.
Now we don’t want our Euclidean distance from before. Now we just want the X and Y distances. So our X portion of our speed would be:
speed * X-distance / (X-distance + Y-distance)
and our Y portion of our speed would be:
speed * Y-distance / (X-distance + Y-distance)
I couldn’t find a nice place that spells this out without being too formal so my simplified version will have to do.
The Monkey code for this would look something like this:
Local deltax:Float = Abs(target.x - position.x) Local deltay:Float = Abs(target.y - position.y) Local sum_delta:Float = deltax + deltay If (target.x > position.x) velocity.x = speed * (deltax / sum_delta) Else If (target.x < position.x) velocity.x = -speed * (deltax / sum_delta) End If (target.y > position.y) velocity.y = speed * (deltay / sum_delta) Else If (target.y < position.y) velocity.y = -speed * (deltay / sum_delta) End
If the X difference was 12 and the Y difference was 23 then the resulting velocity in the X direction would be:
1.37 = 4 (our speed) * 12 (our X-distance) / 35 (our X-distance + Y-distance)
and our Y direction would be:
2.63 = 4 (our speed) * 23 (our Y-distance) / 35 (our X-distance + Y-distance)
Giving us a nice straight line towards our target point.
Simple 2D Movement
Combining the velocity equation with the distance lets us move our object toward the target, checking the distance as we go.
As long as the distance is decreasing, we are heading in the right direction. But when the distance is 0 or when it starts to increase, it is time to stop because we have arrived or passed our target.
I hope this helps jumpstart some simple 2D movement for you. I will release a full working example in game #3 (coming soon) in my 11 games in 11 months series. Until then, keep making awesome things.