Legacy GM Acceleration and deceleration.

D

dcamod

Guest
Hello! I am trying to program a steering behavior with more control over acceleration and deceleration.
The issue I am having is the object will act erratically. It will not start motion without getting close first and if I circle the mouse around it will shoot itself off the screen while trying to correct its direction.

Here is all the code I have running in the room and on the object.

Code:
///sb_seek(x,y,_weight)

var _target = vect2(argument[0],argument[1]);
var _weight = argument[2];

var _desired = vect_subtract(_target,position);
var _desired_mult = maxSpeed/_weight;
_desired = vect_multr(_desired,_desired_mult)
if point_distance(x,y,argument[0],argument[1]) > slow_radius
{vect_add(_desired,velocity);}
if point_distance(x,y,argument[0],argument[1]) <= slow_radius
{_force = vect_subtract(_desired,velocity);}
var _force_mult = (maxForce/maxSpeed)
_force = vect_multr(_force,_force_mult)
return _force;

Code:
position = vect2(x,y);

velocity =  vect2(0,0)

steering =  vect2(0,0)

maxSpeed = .5
maxForce = .5

_force = vect2(0,0)

slow_radius = 256

Code:
///steer
image_angle = point_direction(x,y,mouse_x,mouse_y)
if point_distance(x,y,mouse_x,mouse_y) > 64
{
steering = vect2(0,0)

steering = vect_add(steering,sb_seek_debug(mouse_x,mouse_y,20))

velocity = vect_add(velocity,steering)

position = vect_add(position,velocity)

x = position[1]
y = position[2]
}

Any help is appreciated. Thank you :)
 
1)
steering = vect_add(steering,sb_seek_debug(mouse_x,mouse_y,20))

only that part should be in the if clause

2)
your code commented
Code:
var _target = scr_vect2(argument[0],argument[1]);
var _weight = argument[2];

var _desired = scr_vect2_subtract(_target,position);

var _desired_mult = maxSpeed/_weight; // thats always 0.5 / 20 = 0.025

_desired = scr_vect2_multr(_desired,_desired_mult) //vector to target multiplied by 0.025

if point_distance(x,y,argument[0],argument[1]) > slow_radius  //results  ->  _desired > 6.4 lineary increasing
{scr_vect2_add(_desired,velocity);} //no variable assigned (_force = ....) but would result in exploding velocity if distance is high
if point_distance(x,y,argument[0],argument[1]) <= slow_radius  //results  -> _desired <= 6.4 lineary decreasing
{_force = scr_vect2_subtract(_desired,velocity);} // [target_vector * (<6.4)] - [velocity] , is strange, the other way around

var _force_mult = (maxForce/maxSpeed) //always the same 0.25
_force = scr_vect2_multr(_force,_force_mult) // _force * 0.25
return _force;
EDIT:
Problem is, that you add/subtract your vectors strangely and use unncessary multiplicators, if you want to go faster/slower based on distance, just multiply the velocity vector based on distance and add a failsafe to set values under a certain threshold to 0
 
Last edited:
D

dcamod

Guest
When I place the if statement where you suggested the object does not stop moving. It continuously moves back and forth over the target within in a radius of 64 pixels. I have it placed there to prevent that. How do I get the object to stop 64 pixels away?

Maxforce/maxspeed will not always be the same for every object all the time and neither will maxspeed/weight. Just for this scenario to keep it simple.

I do not understand how you are getting the value 6.4. I am definitely experiencing the exploding velocity you described.

What is strangely being subtracted and what is strange about it? What multiplier is unnecessary and why?

I assigned force to the if statement where it was missing . That's what was preventing motion without getting close first.

Here is the code before I started trying to add acceleration. It is an arrival behavior I believe because it decelerates after given an initial velocity.
Code:
var _target = vect2(argument[0],argument[1]);
var _weight = argument[2];

var _desired = vect_subtract(_target,position);
var _desired_mult = maxSpeed/_weight;
_desired = vect_multr(_desired,_desired_mult)
var _force = vect_subtract(_desired,velocity);
var _force_mult = (maxForce/maxSpeed)
_force = vect_multr(_force,_force_mult)
return _force;

Thanks for the reply by the way. I appreciate it very much.

Edit: The reason I am adding and subtracting instead of multiplying is due to a talk I watched on context steering. The speaker Andrew Fray said it was a common mistake to multiply instead of subtracting the way I have. It has been a while so I will have to watch it again to elaborate on why.
 
Last edited by a moderator:
if your distance is greater than the slow radius (256), you are adding 1/40th of said distance to the speed
acceleration/tick = distance * 0.025, as slow radius is >256
>256 * 0.025 = >6.4 px/tick acceleration (which could be to big)
 
D

dcamod

Guest
I thought distance was separate from the slow radius. If my distance from mouse_x and mouse_y is 278 then it would be 278 * .025 which is 6.95. Slow radius is not my target. Why would I use that to multiply by .025? I am so confused now. Perhaps I have been staring at it too long. What about the rest of my questions though?

Edit:
When I run the software in debug with the target being 512,512 and initial position 992,32 the first frame the position changes to 980,44 a change of -12,12. A 16.97 pixel distance. The second frame goes to 944.3,79.7 from 980,44. A change of -35.7,35.7. A 50.487 pixel distance. And it continues on from there increasing in speed.
 
Last edited by a moderator:
D

dcamod

Guest
I am working on changing it all entirely but I would really still like some answers. I am totally confused.
 
D

dcamod

Guest
Okay, it has been a while. I reworked the code and have tried several alternatives at this point. I am still totally lost. Can anyone please help?
 
D

dcamod

Guest
Still trying to solve this. I have come to realize I do not understand how the math underlying it all works. I multiplied the vector by a real number and it would always end up on one side or the other. I really need a detailed dummies explaination of this please. I multiplied the velocity vector based on distance and it gave me the result I already had before I started peeling apart the code and frankenstiening it into something different. I want specific control over acceleration and deceleration as well as a limit on steering force applied per turn.
 
Top