PDA

View Full Version : 2D Overhead Pedestrian Direction



Colin
04-07-2009, 02:19 PM
Currently my game re-angles the peds to point directly to their destination, however i'd like them to have a max turning angle. i have no idea how todo that. my current code.


Player.Direction := ArcTan2( (DestinationY - Player.Y), (DestinationX - Player.X) );
Speed := 72;
Player.X := Player.X + cos( Player.Direction ) * (Speed * delta);
Player.Y := Player.Y + sin( Player.Direction ) * (Speed * delta);


http://www.overhertz.com/downloads/corpseration/shot2.JPG

any ideas how i can accomplish this?

-Colin

chronozphere
04-07-2009, 07:26 PM
This topic about bezier splines might be usefull for you. :)

http://www.pascalgamedevelopment.com/forum/index.php?topic=5833.0

"Maximum angle" is a bit unclear to me. I can see you want to constrain the rotation to some degree because it's unrealistic to turn at once. But do you want a maximum rotation per frame, or per second?

This is what I would do (for each frame):



Check where the target is with respect to the pedestrian's position using arcTan2().
If this angle is different from the orientation of the pedestrian?
Add MaxRotate to the current angle of your pedestrian (or subtract, depending on what is faster to reach the perfect approach angle)
else
Leave the angle alone, we are approaching our target in the right direction

Now just move one step with current angle and speed.


Hope this makes sense to you. :)

Colin
04-07-2009, 08:16 PM
hi, thanks,

so i am trying as you said, but fail miserably, been trying to solve this for hoursssss lol

so anyways i did not add check to see which way to turn is faster as for now more important to get it to work.


newDir := ArcTan2( (DestinationY - Sprite.Y), (DestinationX - Sprite.X) );

if Sprite.Direction <> newDir then begin
//we need to turn.
Sprite.Direction := Sprite.Direction + (3 * delta);
end;


by doing this, the peds just go round and round....

noeska
04-07-2009, 08:39 PM
Maybe this is a interesting read: http://en.wikipedia.org/wiki/B%C3%A9zier_curve
Especialy take a look at the Quadratic curves with animation.
Also do take a look at the thread mentioned by chronozphere.

User137
04-07-2009, 09:30 PM
I use this function to first get difference between the current angle and wanted angle:
(If you use radians just change all 180 to PI and 360 to 2*PI)
function Angle3(src,dest: double): double;
begin
result:=src-dest;
while result<-180 do result:=result+360;
while result>180 do result:=result-360;
end;
This is because if your current angle is towards 45 degrees and you want to turn to 350 the shortest way is to negative side. This function always returns -180 to 180 that is directly the amount that you have to add to your current angle to end up to destination.

So if you want to turn slowly, just multiply result from this function by 0.1 or something and add it to current angle. There are different ways to use result from this...
...or if result is negative you want to turn left, and if its positive then turn right.

Colin
05-07-2009, 10:55 AM
hi User137

thank you very much, after trying your method a few differ ways i have put together the following:


newDir := ArcTan2( DestinationY - Sprite.Y, DestinationX - Sprite.X );
Sprite.Direction := Sprite.Direction - ((1 * delta) * Angle3(Sprite.Direction, newDir));


the character automatically turns the shortest angle.... thanks again :)

-Colin

JernejL
05-07-2009, 04:23 PM
Colin: it's simple, just detect the new angle you calculated, and clip it to maximum angle change you want per frame.