Jump to content
  • Advertisement
Sign in to follow this  

"Realistic" 2d missile homing

This topic is 2566 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, I am working on a top-down game that has missiles in it. I am writing in c++ using the Box2d engine. I want the missiles to steer only by applying torque and forward force, hence "realistic." As it is I have it turning correctly only if it starts at certain angles, and at other angles it turns away from the target. A video might help demonstrate. There's two examples in the clip, one where the missile starts facing right and one where it starts facing left. As you will see, it hits the target (the red circle) perfectly when facing right, but when facing left it goes in the opposite direction. I hope the video is not too unclear. The thick, short white line is the missile, the long lines indicate direction and such.

Here is the relevant function (called each frame):

void Missile::update() {
if (!active) {

// Begin direction calculations
b2Vec2 pos = body->GetPosition();
b2Vec2 vel = body->GetLinearVelocity();
b2Vec2 wp = *currentWaypoint->point;

float currentAngle = body->GetAngle();
float turnSpeed = body->GetAngularVelocity();

float targetAngle = pointAngleR(pos, wp);

float driftCompensationAngle = targetAngle - (angleDifferenceR(vectorToAngleR(vel), targetAngle));

targetAngle = driftCompensationAngle;

float aDiff = angleDifferenceR(currentAngle, targetAngle);

float desiredTurnSpeed = -((aDiff) * maxTurnSpeed);

* The constant determines the time it takes for the missile to stabilize itself.
* A lower constant means it takes longer.

float turnSpeedCorrection = (desiredTurnSpeed - turnSpeed) * 20000;

// End direction calculations

b2Vec2 force = getDirectionVector();
force *= -300.0f;

body->ApplyForce(force, body->GetWorldCenter());

#ifdef DEBUG

// Draw lines for debugging
line(screen, pos.x, pos.y, pos.x+force.x, pos.y+force.y, makecol(255,255,255));

line(screen, pos.x, pos.y, pos.x + (vel.x * 10), pos.y + (vel.y * 10), makecol(255,0,0));

line(screen, pos.x, pos.y, pos.x + (getDirectionVector().x * 100), pos.y + getDirectionVector().y * 100, makecol(0,0,255));

line(screen, pos.x, pos.y, pos.x + (angleToVectorR(driftCompensationAngle).x * 100), pos.y + (angleToVectorR(driftCompensationAngle).y * 100), makecol(0,255,255));

b2Vec2 targetAngleVector = angleToVectorR(targetAngle);
targetAngleVector *= -500;

line(screen, pos.x, pos.y, pos.x + targetAngleVector.x, pos.y + targetAngleVector.y, makecol(0,255,0));


// Check if we've reached our target
if (abs((pos - wp).Length()) < 5) {
if (currentWaypoint->next != NULL) {
currentWaypoint = currentWaypoint->next;
} else {
active = false;


Thanks for any help!

Share this post

Link to post
Share on other sites
it would probably be very useful to start the simulation in a situation where the code does the wrong thing and look at variable values using a debugger. My guess is that some of the angle computations don't work well around the point where the angles change from 180 to -180 or from 360 to 0.
I would implement the whole thing without using angles. Thinking about these things in terms of angles might seem more intuitive at first, but it's easy to make mistakes. If you write the code using vectors, it generalizes to 3D naturally and it's easier to get right. Code that doesn't use angles even executes faster, although that should only be an argument if it matters.

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!