diff --git a/src/common/Shot.cc b/src/common/Shot.cc index d7b82f2..5aac8df 100644 --- a/src/common/Shot.cc +++ b/src/common/Shot.cc @@ -12,14 +12,17 @@ using namespace sf; /* GRAVITY can really be any arbitrary value that makes the shot's speed * feel right. Increasing the gravity will decrease the amount of time * it takes the shot to hit its target. */ -#define GRAVITY 30 +#define GRAVITY 100 + +#define SHOT_ANGLE 30 /* We model the shot's position using a parametric equation based on time. - * Assuming a constant 45° shot angle simplifies the equations. - * x = vt - * y = h + vt - gt²/2 - * = (-g/2)t² + vt + h + * x = vct + * y = h + vst - gt²/2 + * = (-g/2)t² + vst + h * where + * s = sin(shot angle) + * c = cos(shot angle) * v = shot speed * t = time * g = gravity @@ -28,36 +31,40 @@ using namespace sf; * Given a target distance of d, we want to figure out a speed that makes * (x, y) = (d, 0) a valid point on the trajectory. * Then: - * d = vt - * 0 = (-g/2)t² + vt + h + * d = vct + * 0 = (-g/2)t² + vst + h * So: - * v = d/t - * 0 = (-g/2)t² + (d/t)t + h - * 0 = (-g/2)t² + d + h + * v = d/ct + * 0 = (-g/2)t² + (d/ct)st + h + * 0 = (-g/2)t² + ds/c + h * According to the quadratic formula (x = (-b ± sqrt(b² - 4ac))/2a), - * t = ±sqrt(-4(-g/2)(d+h)) / 2(-g/2) - * -tg = ±sqrt(2g(d+h)) - * t²g² = 2g(d+h) - * t² = 2(d+h)/g - * t = sqrt(2(d+h)/g) + * t = ±sqrt(-4(-g/2)(ds/c+h)) / 2(-g/2) + * -tg = ±sqrt(2g(ds/c+h)) + * t²g² = 2g(ds/c+h) + * t² = 2(ds/c+h)/g + * t = sqrt(2(ds/c+h)/g) * Now that we know the time at which this point occurs, we can solve for * the shot speed (v) - * v = d/t - * v = d / sqrt(2(d+h)/g) + * v = d/ct + * v = d / c / sqrt(2(ds/c+h)/g) */ Shot::Shot(const Vector2f & origin, double direction, double target_dist) { m_direction = Vector2f(cos(direction), sin(direction)); m_origin = origin; - m_speed = target_dist / - sqrt(2 * (target_dist + INITIAL_SHOT_HEIGHT) / GRAVITY); + m_cos_a = cos(SHOT_ANGLE * M_PI / 180.0); + m_sin_a = sin(SHOT_ANGLE * M_PI / 180.0); + m_speed = target_dist / m_cos_a / + sqrt(2 * (target_dist * m_sin_a / m_cos_a + INITIAL_SHOT_HEIGHT) / + GRAVITY); } Vector3f Shot::get_position() { float time = m_clock.getElapsedTime().asSeconds(); - float horiz_dist = m_speed * time; - float z = INITIAL_SHOT_HEIGHT + m_speed * time - GRAVITY * time * time / 2.0; + float horiz_dist = m_speed * m_cos_a * time; + float z = INITIAL_SHOT_HEIGHT + m_speed * m_sin_a * time - + GRAVITY * time * time / 2.0; Vector2f xy = m_origin + m_direction * horiz_dist; return Vector3f(xy.x, xy.y, z); } diff --git a/src/common/Shot.h b/src/common/Shot.h index f70dbc7..7f22fb6 100644 --- a/src/common/Shot.h +++ b/src/common/Shot.h @@ -13,6 +13,8 @@ class Shot sf::Vector2f m_origin; sf::Vector2f m_direction; double m_speed; + double m_cos_a; + double m_sin_a; sf::Clock m_clock; };