5SD033 Missile Tracking and Rotation
|
This week’s post will detail how I, with the help of Adrian Hedqvist, created a new projectile that tracks enemies and changes rotation based on target position. To get an idea of how positions work in our game, read http://tollyx.net/game/2016/02/10/moving-in-circles.html for details on player position. Problem Tracking One of the game’s powerups is a heat-seeking missile, intended to track the nearest enemy and strike them without any need for aiming from the player, beyond positioning. Current projectile objects are created by taking the player’s current position and rotation of their firing barrel in degrees, with 90 degrees added to the projectile’s rotation so the projectile does not appear on its side when fired. It would then move each time the game updated in the direction it had been rotated, until it either hit an enemy or moved offscreen. To create a tracking missile, I would need to make a new object that inherited the properties of said projectile (a rotation, a speed, an effect when hit) and locate which enemy is the closest to the firing position. It would also need to properly rotate the new projectile’s sprite to “aim” towards the enemy. Missile Commands Adrian had already created a function within our enemy manager that tracked the nearest enemy, by utilizing trigonometry. Specifically, finding the distance between two positions drawn directly between the two points, via tangents (and utilizing functions within the math.h library).
Where 1 is the length between the x positions, x is the length between the y, and the square root of the two positions multiplied then added to each other is the distance. We have vectors holding each current object of enemy ships, which we iterate through checking these distances.
auto it = vecPtrEnemyShip.begin();
while (it != vecPtrEnemyShip.end())
{
sf::Vector2f enPos = (*it)->getPosition();
sf::Vector2f deltaPos = pos - enPos;
float distance = sqrt(deltaPos.x * deltaPos.x + deltaPos.y * deltaPos.y);
if (closestDist >= distance)
{
closestDist = distance;
closest = (*it);
}
++it;
Angle tangle But now that we knew what the closest ship was, how did I aim the already fired projectiles towards them, have them move where they needed to, and continue updating that direction when the enemy ship moved? The answer was simple (after some more hints by Adrian). He had already created a turret class that needed to rotate as it fired towards targets, though their projectiles did not track the enemy. All that was needed was to continue using tangents, though specifically the inverse arctan, to acquire the angle from the last positions we had checked between the projectile and the enemy. float deltaX = getPosition().x - enemyship->getPosition().x; float deltaY = getPosition().y - enemyship->getPosition().y; setRotation(atan2(deltaY, deltaX) * 180 / M_PI +180); projectileSprite.setRotation(getRotation() + 90);
The new rotation of the sprite is updated every time the missile is, ensuring the missile always points towards its target.
|
