0 Favourites

How do I Pathfind away from the player?

  • I'm currently in the works of a dream game of mine, but the AI will be the hardest aspect and I need some of your help for it.

    Q: Is there a way to make a certain object use the pathfinding behavior to create a path AWAY from said specified item? For example: A deer running away from a wolf, avoiding solid trees.

    I really need this, and if it isn't possible to do so with pathfinding, is there any other method? I'll take any other method I can get considering this outcome.

    A Contruct 2 cap.x would be very useful, but text is fine too!

    • Thanks in advance.
  • Pathfinding only needs a start location and a destination to work... so yes this should be possible.

    What you need to do is pick a destination which is directly away from the danger and a distance proportional to how much danger the deer is feeling.

    So if your deer is at dx,dy and your wolf is at wx,wy then you want to pick a destination zx,zy as:

    closeness = distance(dx, dy, wx, wy)

    if closeness <= maximumVisionOfDeer

    howFarToRun = maximumFarToRun / closeness

    dangerAngle = angle(dx, dy, wx, wy)

    safeAngle = dangerAngle + 180

    zx = dx + cos(safeAngle) * howFarToRun

    zy = dy + sin(safeAngle) * howFarToRun

    endif

    Then you can pathfind from dx,dy to zx,zy.

    Note: maximumFarToRun is the maximum distance the deer will run if the wolf is right next to it (closeness = 1), if your wolf can get even closer than 1 (e.g. 0.1) then this won't work the same and you might want to limit the values into the equation.

    Note: if zx,zy is inside a tree, you either need a pathfinding algorithm that will go as close as it can (and not just fail), or you should jiggle the destination a bit with a random offset until it is not in a tree.

    There are tons of other things you could add, but this will work to get you started I think.

  • Pathfinding only needs a start location and a destination to work... so yes this should be possible.

    What you need to do is pick a destination which is directly away from the danger and a distance proportional to how much danger the deer is feeling.

    So if your deer is at dx,dy and your wolf is at wx,wy then you want to pick a destination zx,zy as:

    closeness = distance(dx, dy, wx, wy)

    if closeness <= maximumVisionOfDeer

    howFarToRun = maximumFarToRun / closeness

    dangerAngle = angle(dx, dy, wx, wy)

    safeAngle = dangerAngle + 180

    zx = dx + cos(safeAngle) * howFarToRun

    zy = dy + sin(safeAngle) * howFarToRun

    endif

    Then you can pathfind from dx,dy to zx,zy.

    Note: maximumFarToRun is the maximum distance the deer will run if the wolf is right next to it (closeness = 1), if your wolf can get even closer than 1 (e.g. 0.1) then this won't work the same and you might want to limit the values into the equation.

    Note: if zx,zy is inside a tree, you either need a pathfinding algorithm that will go as close as it can (and not just fail), or you should jiggle the destination a bit with a random offset until it is not in a tree.

    There are tons of other things you could add, but this will work to get you started I think.

    This is very hard for me to understand, do you think a cap.x would be possible?

  • Im very confused and frustrated! Someone please help me!!!

  • Give the deer the bullet behavior and a text instance variable that we'll call brain. Then do events like this. 64 is the look ahead.

    Every tick

    --- deer: set angle to (player.x, player.y)

    --- deer: rotate clockwise 180 degrees

    --- deer: set brain to "run!"

    --- deer: move forward 64 pixels

    Deer is overlapping tree

    --- deer: set brain to "tree!"

    Every tick

    --- deer: move forward -64 pixels

    Deer: brain = "tree!"

    Deer: is clockwise of angle(deer.x,deer.y,tree.x,tree.y)

    --- deer: rotate clockwise 45 degrees

    --- deer: set brain to "run!"

    Deer: brain = "tree!"

    Deer: is counter-clockwise of angle(deer.x,deer.y,tree.x,tree.y)

    --- deer: rotate counter-clockwise 45 degrees

    --- deer: set brain to "run!"

    EDIT:

    Just realized this will only work with one deer and one tree as is.

    To make it work with more than one deer put everything as subevents of a "for each deer" event.

    More importantly to make it work with more than one tree we need to pick the same tree the deer overlapped in the last two events. You can do this by setting a global variable to the tree's uid in the overlap condition. Then use pick by uid in the last two events to pick it again.

  • i was trying this lots last night.

    simply, giving the deer bullet and rebound behavoir will automaticly bump off trees.

    then give everything physics, and when distance(deer.x,deer.y,player.x,player.y) <200 apply a force at the deer from player angle -180

    (i would have posted that yesterday, but if u have walls, it can get trapped quite easily and predictably)

    remember world gravity must be made 0.

    think there is a sin calculation to make the angle the force is applied at more realistic.

    just have bullet is overlapping flowers, play deer eating animation, set speed to 0 if you want it to chill occasionally. wait x seconds pick random angle, set speed 100

  • Pathfind is not a good way to do something such as dynamic movement that needs to be constantly updated. The reason is each time you set a new destination, there's a delay, and it also is very costly to constantly update pathfind, especially if you have lots of deers.

    So the bullet suggestions from the above or other ways is better.

  • Construct 3

    Buy Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Buy Now Construct 3 users don't see these ads
  • A simpler way would be to have different sprites that the deer could run to if it is lower , higher or further along from a certain position. This way it could dodge trees rather than bouncing off them.

  • Thanks to everyone I've got it working! But I have one problem. When a wall is in the way (For example: A mountain or border) It turns and runs along side the wall, and because it is running beside the wall it is constantly turning, and whenever it is next to a wall it spazzes out while running away because it is changing it's angle constantly to face away from the player, but turn from the wall. I've tried multiple solutions and It's come down to making another instance variable. Every tick I have an invisible line spawn infront of the animals that detect you (through line of sight, a timer, and another instance variable). If it collides with a solid (I use invisible collision boxes overlapping objects in the background to simulate this, it's top down) it turns 45 degrees clockwise (still have to add randomization to clockwise or counterclockwise). Then I have another collision box that is spawned ontop of the running away animal that is a box 3x it's size. When this box comes in contact with a solid It turns off the instance variable that allows it to turn away from the player. The big problem I'm having is that collision has no invert or way to attach else onto so when it sets the instance variable to 0 to stop the turning away from the player to stop the spazzing, it stays at 0 and I have no way to turn it back to 1 again when it is away from a solid object. I've tried making it wait a second or less until activating it again, but it just keeps spazzing. I've also tried making it spawn another colision box ontop of the running away animal that has it's collisions rap around the other and having it so if this second one comes in contact with a solid it turns the instance variable to 1, but if it is close to the wall then the both are colliding and it defeats the whole purpose.

    Sorry for the long paragraph, it's hard to explain. Can someone please help me with the spazzing?

    Also, I used R0J0hound's idea of turning away, as it was easiest to understand and perfom. The problem with that is that occassionally you will see the animal turn back around at the player for less then a second due to it turning towards and away from the player at the same time. Any fixes for this too?

    Thank you so much!

  • Bump!

  • I don't quite follow the issue you're having.

    When I tried out my idea it came out different than my post above after I tweaked it for a bit. Here it is:

    https://dl.dropboxusercontent.com/u/542 ... trees.capx

    It's still not perfect as the deer can run through the trees, especially when being chased.

    The perfect solution would utilize this I guess:

    http://gamedevelopment.tutsplus.com/ser ... edev-12732

    http://www.red3d.com/cwr/steer/gdc99/

  • My problem is that I simply use this:

    Every tick

    --- deer: set angle to (player.x, player.y)

    --- deer: rotate clockwise 180 degrees

    And use a collision box that turns the object when it collides, so it looks like it turns away from it.

    The problem I'm having though is that when the object is moving away with the bullet movement every second you will see it turn backwards towards the player for a split second due to setting the angle to the player constantly and setting it away. I make it change it's angle -180 degrees towards the player, basically turning away. It looks like it's spazzing occassionally due to this. Another big problem is that when it runs into a wall it turns, and runs along the wall. Because of it constantly turning away from the wall and the player at the same time it is very spazzy and I need a way to stop it from turning away from the player while next to a solid.

    What i'm using to alleviate this right now is a large collision box that constantly spawns around the running away object when it has detected you. When it comes in contact with a solid I set the instance variable for it's turning away from the player 'off'. The big annoyance is that there isn't else or an invert option for collision events so I can't simply make it turn the turning away from the player back on when it's away from the wall. Each object that is running away has everything tied to instance variables so they work seperately.

    Any way to fix this spazzing out? Thanks.

  • Those two actions are run before everything is rendered. The spazzing is probably turning to abruptly.

    Making the turning smoother can help. Instead of rotating by 45 rotate by a smaller value. And instead of setting the angle away from the player, use the the rotate towards action with a negative value.

    The last issue you mentioned about it spazzing against walls will require another method than what I posted. I just handled single trees where it chose left or right of the tree depending on what was closer.

    I only have a rough idea how walls could be handled. However I don't have any easy solutions at hand.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)
Similar Topics Posts Views Last Post
Unread hot topic
0 Favourites
[plugin] Youtube player
175 20,544
rexrainbow's avatar
rexrainbow
Unread hot topic
99 10,139
karshinkoff's avatar
karshinkoff
Unread hot topic
105 16,951
Magistross's avatar
Magistross