3. Math considerations
Math road to nowhere
I was trying to figure out the maths behind keeping track of speed and direction of a shot fired in an arbitrary direction. The shot would be fired by an enemy into the direction of the center of the player ship. I though I might go about it like this:
- keep track of the initial x and y positions of the bullet
- keep track of the x and y positions of the initial target of the bullet
- keep track of the angle the bullet's direction in relation to it's origin
If we think of the line between enemy and player as the long side of a triangle, and the x and y distances as the short sides, we could try to apply trigonometry to find the angle the shot was fired at.
- `x_dist` and `y_dist` are known, these are the short sides of the triangle
- we do not know the length of the long side of the triangle
- the angle `β` between the short sides is 90 deg. (or PI / 2 in radians)
- we do not know the any of the other angles
- we need to find the angle of `γ`, which is the angle of the origin where the shot was fired from
The math would look like this:
γ = asin( (sin(β) / b) * y_dist )
The only unknown here is `b`, which is the long side of the triangle aka the distance between enemy and player. But we can calculate it like this:
b = sqrt(x_dist^2 + y_dist^2 - 2 * x_dist * y_dist * cos(β))
Combining the two formulas we get:
γ = asin( (sin(β) / (sqrt(x_dist^2 + y_dist^2 - 2 * x_dist * y_dist * cos(β)))) * y_dist)
That unfortunately looks computationally expensive, let's see if we can simplify it now that we know that `β = PI/2` (or 90 degrees):
b = sqrt(x_dist^2 + y_dist^2 - 2 * x_dist * y_dist * cos(pi/2)) γ = asin(y_dist / b)
And combined:
γ = asin(y_dist / (sqrt(x_dist^2 + y_dist^2 - 2 * x_dist * y_dist * cos(pi/2))))
That is still way to computationally expensive and overkill for our purpose, let's think about something way simpler.
Simpler approach
Thinking about this a little more I could probably just do this:
- record the horizontal and vertical distances between bullet origin and target
- at each game update multiply both distances with a `speed` variable, which is a float between 0 and 1
This should result in the same movement, but with almost no effort. Some pseudo code:
speed = 0.05 bullet_x = enemy.x bullet_y = enemy.y dist_x = enemy.x - player.x dist_y = enemy.y - player.y while true do bullet.x = bullet.x + dist_x * speed bullet.y = bullet.y + dist_y * speed end
That should work in theory, will test this soon.
Created: 25/Jan/2024
Modified: 5/Feb/2024