Player Detection by Enemy


(Froom7) #1

Hello fellow developers!

I’m making a minigame where your goal is to escape.
Guards will be standing around to keep watch.

So I now wrote a simple player detection if the player is in the range of the guards.
When it does, the guards will follow/chase the player.
My question now is: How do you check if the player is behind a wall? Either going to hide or just being in another room. Obviously you can’t see through walls.
So the chasing only needs to occur if the Enemy “sees” the player.

If someone can help me out, much appreciated.


(JP Mortiboys) #2

The easiest way is to use collideLine - like so:

class Guard extends Entity {
  var player:Player;
  private function canSeePlayer() {
    return world.collideLine('map', x, y, player.x, player.y, 1) === null;
  }
}

Note that this will just trace a line from the origin point of the guard to the origin point of the player. So if the player is poking out the end of a wall but his centre is still behind it (from the point of view of the guard) then he won’t be visible. (I’m assuming the origin points of guard and player are their centres; if not adjust as appropriate)

Lots of ways to handle this, a really simple way would be to check the centre and 4 corners of the bounding box of the player, like so:

  private function canSeePlayer():Boolean {
    if (world.collideLine('map', centerX, centerY, player.centerX, player.centerY, 1)) { return false; }
    if (world.collideLine('map', centerX, centerY, player.left, player.centerY, 1)) { return false; }
    if (world.collideLine('map', centerX, centerY, player.right, player.centerY, 1)) { return false; }
    if (world.collideLine('map', centerX, centerY, player.centerX, player.top, 1)) { return false; }
    if (world.collideLine('map', centerX, centerY, player.centerX, player.bottom, 1)) { return false; }
  }

Note the last parameter (1). It’s optional, and defaults to 1, but depending on your game you might want to increase it - it makes the searching quicker but less accurate. Generally, if your walls are going to be 8 pixels or wider you can set it to 8. Have a play.

You could make this more accurate (but slower) by checking more points. You could perform some complicated logic based on relative positions to choose which points to check. There are lots of ways to make it tailored to your application, but hopefully this will be a good starting point.

Cheers

NotARaptor


(Jean) #3

http://useflashpunk.net/docs/net/flashpunk/World.html#collideLine()

Just a quick search and I got there. You will probably want to try to ignore the guard itself, so make that X and Y is offset of it’s own collision mask. If the function returns something other than a Player, than it’s a wall. Just remember to give the right Type in the function.