Missile Pathing for 2D game

Started by
26 comments, last by FLeBlanc 11 years, 3 months ago
I am creating a 2D game, that use the same coordinate system like any other images or 2D games(top-left corner is 0,0. Moving to the right and x increases, moving down and y increases).

I have created a homing/heat seeking missile for my game and I am very dissatisfied with the results. Since the missile is heat seeking, it must update its target position every X amount of frames. When it have updated its target, it could do an ugly 90 degree turn, if necessary. This effect is unwanted. Instead, I want it to move in a curve. I cant figure out how to accomplish this.

Please note that I have low math skills.
Advertisement

Basically, when your missile updates it's target position(it's not necessary to do every single frame) find target angle of rotation, so that missile points in right direction (with the help of atan2 function).

And than update missile rotation as you update its position. Here is an example:


 missile.angularAcceleration = targetOrientation - missile.orientation;
 if (missile.angularAcceleration < 0)
   missile.angularAcceleration = -maxAngularAcceleration;
 else
   missile.angularAcceleration = maxAngularAcceleration;

 missile.orientation += missile.rotation * time;
 missile.rotation += missile.angularAcceleration * time;

 if (missile.rotation > maxRotation) missile.rotation = maxRotation;


It's far not ideal implementation, just to give you an idea. Actually, you can make your rotation even smoother with the use of slow down radius for example(when angle to rotate remains small it starts to slow down a little bit). Also, maybe you fill need some radius of satisfaction(it's doubtful that your object will rotate EXACTLY at the angle you need and it will end up in flickering).

Thank you. I will definitely try that out.

Some variable names and the usage is a bit confusing.

find target angle of rotation

Find the angle between the two points(target and missile)?
If yes, would something like this work?


float deltaX = x2 - x1;
float deltaY = y2 - y1;

return Math.atan2(deltaX, deltaY);

Finally, what do the orientation variables represent?

Yep, atan2 function will work, perhaps you have to swap deltaX and deltaY arguments to get an angle from X axis.

Orientation - is a desired angle or current angle ( position for movement )

Rotation - is a speed orientation is changed (velocity for movement )

angularAcceleration - is a speed rotation is changed (acceleration for movement)

I hope everything is clear now:)

Still confused. Sorry for being dull.

Could you make a quick example, that contains the missiles and the targets coordinates(missileX, missileY, targetX, targetY)?

Okay. Imagine you missile is going to the right (1, 0) - x and y coordinates accordingly. Currently it has position (200, 200). It's target lies in the point (300, 200), so target angle between missile direction and X axis is zero(targetOrientation = 0) and current angle of missile direction and X axis is zero(missile.orientation = 0)

Next frame your target moves to the position (200, 100), probably you won't have such a huge jumps in just a single frame, but i try to show you an idea. So your desired direction for a missile is (0,1) now which make angle of Pi/2 (90 degrees) with X axis. So you start to rotate your missile. Your maxAngularAcceleration value should be already is defined for each missile, so you increase its rotation :missile.rotation += missile.angularAcceleration * time and than orientation (or angle between direction and X axis) : missile.orientation += missile.rotation * time.

Than you use current angle to get movement direction. Start with creating Z axis rotation matrix (Z axis goes into your screen or out of your screen) and multiply vector (1, 0) with this matrix. As a result you will get rotated vector. That you can multiply it by speed scalar. You can read this small tutorial if you still have some questions regarding retrieving direction from current angle.

I hope it helps ;) Let me know if you still have some questions :)

I dont know if this is compatible with my game mechanics.

The missile use its x and y coordinates to move towards the target every frame. Your example dont even touch such variables.

Should I add missile.orientation to the missiles x coordinate every frame?

Should I add missile.rotation to the missiles y coordinate every frame?

How often should I recalculate these variables?

Formula to calculate the orientations?

I wouldn't use atan2 or angles at all. Your missile has a position and a velocity. Each frame, you look at your target position and apply some acceleration to try to get you there, as if the missile and the target were joined by a spring.

vector_to_target = target - position; acceleration = spring_constant * vector_to_target - damping_constant * velocity; velocity = velocity + delta_t * acceleration; position = position + delta_t * velocity;

I don't use the coordinates (x,y) because I am using vector notation. If you want to express the code above using coordinates, each line becomes two lines: One for the x value of each vector and one for the y value. delta_t is the time elapsed since the previous frame (you can make it a constant).

By playing a little bit with the constants, you should be able to get the behavior you want.

Thanks. I am getting there now.

Can you recommend constant values for damping, spring and delta_t?

delta_t is the length of a frame in seconds, so something like 1/60, if your game runs at 60 FPS. For the other two, I would have to do some fiddling around myself.

I was just going over my previous post and I think you may want to normalize vector_to_target, so your missile accelerates equally regardless of how far away the target is.

This topic is closed to new replies.

Advertisement