projectile->Set_Direction(Movement::get_dir_towards( projectile->Get_Position(), target->Get_Position()));PointF movement(projectile->Get_Direction() * proj_speed * delta);projectile->Set_Position(projectile->Get_Position() + movement);projectile->Set_Dist_Travelled(projectile->Get_Dist_Travelled() + delta * proj_speed);
PointF Movement::get_dir_towards(const PointF& source, const PointF& target){ const float cos_a = (target.y - source.y) / sqrt(pow(target.x - source.x, 2) + pow(target.y - source.y, 2)); const float sin_a = (target.x - source.x) / sqrt(pow(target.x - source.x, 2) + pow(target.y - source.y, 2)); return PointF(sin_a, cos_a);}
void Rotatable_Sprite::Calculate_Y_Clip(float angle){ // Frame is based on the angle. int angle_frame = static_cast<int>(Maths::increment_closest_to( degree_increment_size, angle) / degree_increment_size); clip.y = angle_frame * Get_Frame_Height();}
float Maths::increment_closest_to(float increment, float angle){ // How many times does the increment go into the angle? float times_into = angle / increment; // The decimal part of times_into (e.g. if times_into = 1.56, will be .56). float decimal_part = times_into - floor(times_into); // If the part is bigger than 0.5, round up to the larger increment, vice versa. return increment * (decimal_part >= 0.5f ? ceil(times_into) : floor(times_into));}
int Rotatable_Sprite::Get_Frame_Width() const{ return surface.Width() / animator.Get_Qty_Frames();}int Rotatable_Sprite::Get_Frame_Height() const{ return static_cast<int>(surface.Height() / (360.0 / degree_increment_size));}
This class seems to work fine - I've debugged it and it is setting the correct increment (I've done the artwork for the missile in rotation increments of 22.5 degrees to save time) and the correct clipping in the sprite sheet. However, the code I'm using to get the angle between the missile and its target seems to be a bit dodgy, as the missile sometimes faces the wrong way, etc.:
float angle = 0;const Unit* target(map.Unit_At(projectile->Get_Target_ID()));if(target && target->Is_Alive()){ PointF proj_pos = projectile->Get_Position(); PointF target_pos = target->Get_Position(); angle = abs(Maths::angle_between(proj_pos, target_pos));}projectile->Get_Sprite()->Set_Angle(angle);projectile->Get_Sprite()->Update(delta);
float Maths::angle_between(const PointF& p1, const PointF& p2){ return rad_to_deg(atan2(p2.y - p1.y, p2.x - p1.x));}
Can anyone see anything wrong with Maths::angle_between? I tried using Movement::get_dir_towards (the same function that determines the direction the missile should move in) but it seems to have much the same result.
Cheers.
[Edited by - Mybowlcut on July 13, 2010 4:05:40 AM]