Yet another Random Movement thread. [solved]

Started by DrewCCU, Thu 24/06/2010 19:24:54

Previous topic - Next topic

DrewCCU

-So having an NPC move in a random patern in a given area is pretty easy.
-Having an NPC follow the Player is pretty easy also.

However, I am trying to figure out a way to combine the two.  I want the NPC to move at random inside a circle with a radius of (lets say) 100 pixels.  But that's not all, I also want the center point of that circle to move (in actuality, the center point of the circle is going to be the Player).

So imagine it this way:

Lets say your walking your dog on a leash.  The leash is a length of 100. And your dog is wild so he's running randomly and crazily all around you ... up to you ... back away from you, to the other side of you ... so on and so forth ... but he can never go more than a distance of 100 away from you (in any and every possible direction aka-a circle).

For some reason i can't wrap my head around how to effectively do this one.  A little push in the right direction could help.
"So much of what we do is ephemeral and quickly forgotten, even by ourselves, so it's gratifying to have something you have done linger in people's memories."
-John Williams

Ryan Timothy B

#1
One way to do this would be to use cosine and sine, radius and degrees (converted to radians).
Code: ags

  x = FloatToInt(Maths.Cos(Maths.DegreesToRadians(degrees))*radius); //x
  y = FloatToInt(Maths.Sin(Maths.DegreesToRadians(degrees))*radius); //y


Where radius would be 100, and degrees could be a random number from 0-360.  You could also randomize the radius from 0-100 if you wanted the dog to not only randomize it's movement to the outer edges.
Then for the dog's location you do this:
Code: ags

cDog.Walk(player.x+x, player.y+y, eNoBlock);


Obviously, if the character is walking around at the same time as dog, you'll have to use your own custom walking function instead of AGS's, because it can cause issues.  Or you could just check if the character and dog is not within 100 distance anymore and have the dog start following the character as if the leash got tight and it's being led along.

Khris

Did you read the manual entry for Character.FollowCharacter?

It even mentions a dog as an example:
QuoteAs a special case, setting DIST=0 and EAGERNESS=0 makes CHARID behave as if it is chasing CHARTOFOLLOW - it will try and get there as quickly as possible. Setting EAGERNESS=0 also tells the character not to stop when they reach CHARTOFOLLOW, but instead to randomly wander around the character - useful perhaps for a very energetic dog or something.

DrewCCU

Quote from: Khris on Thu 24/06/2010 23:01:25
Did you read the manual entry for Character.FollowCharacter?

It even mentions a dog as an example:
QuoteAs a special case, setting DIST=0 and EAGERNESS=0 makes CHARID behave as if it is chasing CHARTOFOLLOW - it will try and get there as quickly as possible. Setting EAGERNESS=0 also tells the character not to stop when they reach CHARTOFOLLOW, but instead to randomly wander around the character - useful perhaps for a very energetic dog or something.

yes i have read the manual and i meant to mention that in my original post.  So allow me to do it now:  the follow character command is great but it's not exactly what i need in this case - close, but not close enough.
"So much of what we do is ephemeral and quickly forgotten, even by ourselves, so it's gratifying to have something you have done linger in people's memories."
-John Williams

DrewCCU

Ryan Timothy,

So to make sure i get this:

In order for the "dog" to appear as those he's moving in a random pattern inside this invisible circle around the player i need to randomize the degrees value and the radius value; otherwise, the "dog" will just be in one place at all times (in relation to the player)?

So in order to randomize the degrees and radius i would have something like:
int degrees = Random(360);
int radius = Random(100); (or whatever the radius will end up being)

then to plug them into the x and y like so:

int x = FloatToInt(Maths.Cos(Maths.DegreesToRadians(IntToFloat(degrees)))*IntToFloat(radius));
int y = FloatToInt(Maths.Sin(Maths.DegreesToRadians(IntToFloat(degrees)))*IntToFloat(radius));

is this correct?
"So much of what we do is ephemeral and quickly forgotten, even by ourselves, so it's gratifying to have something you have done linger in people's memories."
-John Williams

Ryan Timothy B

#5
Yep.  Just first check to see if the dog isn't moving then you apply it.

But like I said earlier, if the Player that the dog is revolving around is moving, you won't be able to rely on Character.Walk since it'll cause a whole heap load of crap.  Unless the rope can stretch quite a bit but still having the dog constantly randomize in that radius around the character whenever it stops walking.
As for the math and radius, if you wanted a min and max radius you could always do something like this:
Code: ags

int radius = 50 + Random(50); //which would make the radius 50-100


Also with this, a Degree of 0 is the same as 360.  Just so ya know. :P


Oh, and if this is for a typical adventure game background with perspective, you'll know that the radius shouldn't appear on screen as a circle, more like an oval.  So depending on your perspective, something like this would work:
Code: ags

int x = FloatToInt(Maths.Cos(Maths.DegreesToRadians(IntToFloat(degrees)))*IntToFloat(radius));
int y = FloatToInt(Maths.Sin(Maths.DegreesToRadians(IntToFloat(degrees)))*IntToFloat(radius)) * 0.5;  //multiply by more or less


Multiply the Y by 0.5 (or whatever) to make the vertical height of the circle half or less/more depending on what you multiply it by.  Depending on your perspective.

DrewCCU

Quote from: Ryan Timothy on Fri 25/06/2010 04:55:14
Also with this, a Degree of 0 is the same as 360.  Just so ya know. :P

Yeah but if i'm using the random function then i would need to use 360 because then i would get random numbers between 0 and 360 ... if i used 0 then ... well im not sure what would happen - or if the function would even run properly ... but properly it would act as if there was no line of code at all or as if degrees=0.

anyway. thanks for your help. :)
"So much of what we do is ephemeral and quickly forgotten, even by ourselves, so it's gratifying to have something you have done linger in people's memories."
-John Williams

Ryan Timothy B

#7
Sorry, I guess I explained that badly.  I meant that if the random degree ends up with 0 or 360, that would be the same degree (same x and y).  Not that I see this being a problem with whatever you have planned for this, I just figured I'd mention it.

But if you wanted the random degree to not land on 0 and 360, for some reason, you simply do this:
Code: ags

degree = Random(359)+1;  //1 to 360
//or
degree = Random(359);  //0 to 359

SMF spam blocked by CleanTalk