Here is the relevant function (called each frame):
void Missile::update() {
if (!active) {
return;
}
// 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.Normalize();
force *= -300.0f;
body->ApplyTorque(turnSpeedCorrection);
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));
#endif
// Check if we've reached our target
if (abs((pos - wp).Length()) < 5) {
if (currentWaypoint->next != NULL) {
currentWaypoint = currentWaypoint->next;
} else {
active = false;
}
graphics::textOutput(currentWaypoint->point);
}
}
Thanks for any help!