GameMaker Calculate Change On Angle To Reach Point

S

SeirLord Games

Guest
Hi community!

I've a problem, and... I don't know how to explain it in english, so I made an image so I hope you can understand.

Thanks

Problema.png
 

GMWolf

aka fel666
Assuming you want a realistic looking trajectory, then you won't have a change in direction per second, but use gravity instead.

To do this we need to use best one equations of motion.

S = ut + 1/2(at^2)
Where S is displacement u is initial velocity, a is acceleration and t is time.


Let's break this down into two parts. : vertical and horizontal.

Let's start with horizontal.
We have no horizontal acceleration, so our equation becomes S = ut.
Our target displacement is X.x - G.x.
Our initial velocity is u × cos(theta).
So we have
X.x - G.x = ut × cos(theta).

Let's find t:
(X.x - G.x)/ u cos(theta) = t

Ok, so now we need can calculate the time!

Let's move on to vertical axis.


We know our vertical velocity is u × sin(theta), where U is initial speed, and theta is angle of the gun.

X is our target position. So X.y is our target height.
The gun is at position G. G.y is the guns height.

Our target displacement is X.y - G.y.
So, let's substitute those values into our equation.
X.y - G.y = u×sin(theta) + 1/2(at^2).
We know t from the horizontal axis, now we need tol solve for the acceleration a.

Let's rearage to find a
a = 2((X.y - G.y) - u sin(theta)) / t^2

And there you have it!
By first calculating the time using the simple horizontal axis, we can use it to determine the acceleration needed in the vertical axis.
 
Last edited:
S

SeirLord Games

Guest
Assuming you want a realistic looking trajectory, then you won't have a change in direction per second, but use gravity instead.

To do this we need to use best one equations of motion.

S = ut + 1/2(at^2)
Where S is displacement u is initial velocity, a is acceleration and t is time.


Let's break this down into two parts. : vertical and horizontal.

Let's start with horizontal.
We have no horizontal acceleration, so our equation becomes S = ut.
Our target displacement is X.x - G.x.
Our initial velocity is u × cos(theta).
So we have
X.x - G.x = ut × cos(theta).

Let's find t:
(X.x - G.x)/ u cos(theta) = t

Ok, so now we need can calculate the time!

Let's move on to vertical axis.


We know our vertical velocity is u × sin(theta), where U is initial speed, and theta is angle of the gun.

X is our target position. So X.y is our target height.
The gun is at position G. G.y is the guns height.

Our target displacement is X.y - G.y.
So, let's substitute those values into our equation.
X.y - G.y = u×sin(theta) + 1/2(at^2).
We know t from the horizontal axis, now we need tol solve for the acceleration a.

Let's rearage to find a
a = 2((X.y - G.y) - u sin(theta)) / t^2

And there you have it!
By first calculating the time using the simple horizontal axis, we can use it to determine the acceleration needed in the vertical axis.
Wow, emmm, I will try it, but I'm not sure that I can use gravity.. The same de gun can shoot 45º(up-right), it can shoot -45º(bottom-right)
 

GMWolf

aka fel666
Yes, is in space also, so the can't be gravity
Ah, in that case, it's a totally different ordeal.

I don't think there is a particularly easy way to do it, since both x and y will give you quadratic equations.
It also depends on just how you want your missile to move and turn.
 

Bingdom

Googledom
A solution for the original post.
See this thread. It's pretty good. (Ignore my newbieness, lol)

On a more recent topic, you'd probably want to look at predictive aim if that's what you're trying to get at?
Here's a website about it.

Edit: If you're going for a homing missile, you should get the difference between the current angle and point_direction from missile to target. After that, clamp it using clamp() with your rotation speed values.
 
Last edited:
S

SeirLord Games

Guest
You could quite easily measure the time as distance/speed. So get the distance to your target x and target y and divide it by the speed at which your missile is going.
Yes, but I need that information on the CREATE of the object, and the direction of the bullet is not straight so distance/speed doesn't work
 

Simon Gust

Member
Yes, but I need that information on the CREATE of the object, and the direction of the bullet is not straight so distance/speed doesn't work
couldn't you simulate the flight via a while (true) or do-until loop and measure how many iterations it took to get to the target?
 
Yes, but I need that information on the CREATE of the object, and the direction of the bullet is not straight so distance/speed doesn't work
You have a point, if you shot in the opposite direction of the enemy then the distance is less, but the distance is going to become more after it when it launches.

You would have to predict the path somehow and measure it according to that...
 
S

SeirLord Games

Guest
You have a point, if you shot in the opposite direction of the enemy then the distance is less, but the distance is going to become more after it when it launches.

You would have to predict the path somehow and measure it according to that...
couldn't you simulate the flight via a while (true) or do-until loop and measure how many iterations it took to get to the target?
The target is not moving
 

GMWolf

aka fel666
Give us more info as to how exactly your missiles move.
Do they accelerate? To they only change direction, at a constant rate?
Do they have momentum, like an asteroids rocket?
 

samspade

Member
You can use the original math if you rotate the 'x' axis to be a line between the object starting position and it's target. You then apply 'gravity' towards that line and set it's image angle based upon movement.
 
If your projectile's only constraint is their speed, and you want them to turn at a constant rate until they hit a stationary target, then you can get almost exact solutions like this.

This is pretty different from the behavoir you'd probably like in a homing missile though. Homing missiles are pretty interesting. Proportional, (or constant bearing) navigation gives very good results. It's fun to make a homing missile that doesn't break any of the rules of the game, but which is still hard to dodge.

Code:
    var _projectile_speed = 8; //any value should work (larger values will result in some loss of accuracy if projectile turns in discrete steps
    var _A = angle_difference(point_direction( x, y, target.x, target.y ),image_angle);
    var _d = point_distance( x, y, target.x, target.y );
    var _B = 90 - _A;
    var _C = 180 - 2 * _B;
    var _radius = _d / 2 / dcos( _B );
    var _circumference = 2 * pi * _radius;
    var _arc_length = _C / 360 * _circumference;
    var _time = _arc_length / _projectile_speed;
    var _turn_rate = _C / _time;
 
    with (instance_create(x,y,obj_projectile)) {
        turn_rate = _turn_rate;  //add to direction each step.
        lifetime = _time;  //in case you want projectile to know how long until it reaches the point it was fired at
        speed = _projectile_speed;
        direction = other.image_angle;
    }
upload_2018-3-24_12-48-32.png
 
Last edited:

GMWolf

aka fel666
If your projectile's only constraint is their speed, and you want them to turn at a constant rate until they hit a stationary target, then you can get almost exact solutions like this.

This is pretty different from the behavoir you'd probably like in a homing missile though. Homing missiles are pretty interesting. Proportional, (or constant bearing) navigation gives very good results.

Code:
    var _projectile_speed = 8; //any value should work (larger values will result in some loss of accuracy if projectile turns in discrete steps
    var _A = angle_difference(point_direction( x, y, target.x, target.y ),image_angle);
    var _d = point_distance( x, y, target.x, target.y );
    var _B = 90 - _A;
    var _C = 180 - 2 * _B;
    var _radius = _d / 2 / dcos( _B );  //r in diagram below
    var _circumference = 2 * pi * _radius;
    var _arc_length = _C / 360 * _circumference;
    var _time = _arc_length / _projectile_speed;
    var _turn_rate = _C / _time;
 
    with (instance_create(x,y,obj_projectile)) {
        turn_rate = _turn_rate;  //add to direction each step.
        lifetime = _time;  //in case you want projectile to know how long until it reaches the point it was fired at
        speed = _projectile_speed;
        direction = other.image_angle;
    }
View attachment 17236
Nice diagram, Good code! Do you mind walking us trough it?
 
@GMWolf ok.

The first thing to note is that the direction the shooter is facing is always tangent to the circle, meaning it forms a right angle with a line pointing from the shooter to the circle's center.

That means that we can find the angle B by taking a right angle (90) and subtracting A. A is the difference in between the shooter's facing angle, and the angle from the shooter to the target.

d is just the distance between the shooter and the target.

the triangle is isosceles. Both angles marked B are the same. Meaning we can cut the line d in half and get right triangles.

We know the side adjacent to B has a length of d/2. To get the length of the radius (hypotenuse of the right triangle) we can use cosine.

cosine = adj/hyp, therefore hyp = adj/cosine

I think the rest is pretty obvious. It is just using the radius and angle C to compute the length of the arc between the shooter and the target. And then dividing that distance by the projectile speed to determine how long it will take the projectile to get there. Again, this is not a homing missile, the projectile will just turn to the point it was fired at, without tracking a moving target.

I was surprised to find out that it still works even when the difference between the shooter's facing angle and the angle from the shooter to the target was more than 90 degrees. I'll let someone else work out why it still works though.
 
Last edited:
Top