How to detect if a entity see player[SOLVED]


(billy2000) #1

Hello guys.So i have a enemy that walks around.When he see player from a however range he should jump and run after him.The game is a platformer. Also there can be walls or other things that will not let enemy see the player(doesn’t mather if player is in his sight range) What i was thinking to do is something like this: Because this entity has 2 hitboxes,and the other hitbox is a entity that just follow the enemy i thought of this:

public function iSeePlayer():void
	{
		if (myParent.whatDo == "stay" || myParent.whatDo == "think" || myParent.whatDo == "walk") {
			
			var counter:int = 1;
			var myWidth:int;
			var collideWith:Array = ["solid", "crate", "powerDoor", "Door", "player"];
			collidedSomething = false;
			saveX = x;
			saveY = y;
			
			if (myParent.flippedImg) {
				myWidth = 22;
			}
			else {
				myWidth = -22;
			}
			
			while (!collidedSomething && counter <= 4) {
				moveBy(myWidth, 0, collideWith, true);
			}
			
			x = saveX;
			y = saveY;
		}
	}
	override public function moveCollideX(e:Entity):Boolean 
	{
                collidedSomething = true;
		if (e.type == "player") {
			//make my parent run
		}
		return true;
         }

I feel like this is a bit ineficient so im asking you guys if you know a more efficient way of doing this.Thx :smiley:


(Bora Kasap) #2

i think you should use “FP.world.collideLine” as a line of sight


(billy2000) #3

Ty. So i made this piece of code:

private function seePlayer():void
	{
		var iCanSee:Array = ["solid", "crate", "powerDoor", "Door"];
		var howFar:int=60;
		var sign_:int;
		if (!flippedImg){
			sign_ = 1;
		}
		else {
			sign_ = -1;
		}
		
		if (FP.world.collideLine("player", x, y + 10, x + howFar*sign_, y + 10, 5)) {
			
			//calculate if he collides with something between him and player
			var distanceBetween:int = FP.distance(x, y + 10, G.pX + 5 * ( -sign_), y + 10);
			for each(var s:String in iCanSee) {
				
				if (FP.world.collideLine(s, x, y + 10, x + distanceBetween * sign_, y + 10)) {
					return;
				}
			}
			//do something
		}
	}

He see the player no problem ,but if i put something between him and player it still see player.In this case the problem seems to be in this piece of code:

//calculate if he collides with something between him and player
			var distanceBetween:int = FP.distance(x, y + 10, G.pX + 5 * ( -sign_), y + 10);
			for each(var s:String in iCanSee) {
				
				if (FP.world.collideLine(s, x, y + 10, x + distanceBetween * sign_, y + 10)) {
					return;
				}
			}

But idk what it should be the problem so far…do you guys see anything wrong? ty


(JP Mortiboys) #4

From what I can see it looks like you’re overcomplicating things.

First, check if the entity is facing the correct left/right direction to see the player - if he’s not then exit quickly; no collision is possible.

Next, check the rectangle (x,y+eye_offset)-(player_x,y+eye_offset) for the blocking entities with a normal world.collideRect call - no need for a scanning collideLine. If there is a blocking entity, of whatever type, then the entity can’t see the player. Otherwise, it can.

// Using this helper function to get the player entity
// other ways might include storing a world-level variable or using getInstance
private function getPlayer():Entity {
  var e:Array = [];
  world.getType("player", e);
  if (e.length) return e[0];
}

// Simple boolean function - can the entity see the player?
public function canSeePlayer():Boolean {
  var player:Entity = getPlayer();

  // Check facing
  var facing:Number = flippedImg ? -1 : 1;
  var offsetX:Number = (player.x - x) * facing;
  if (offsetX < 0) {
    return false;
  }

  // Check collision box
  var originX:Number = (x + player.x) / 2 - offsetX / 2;
  var iCanSee:Array = ["solid", "crate", "powerDoor", "Door"];
  for each (var checkType:String in iCanSee) {
    if (world.collideRect(checkType, originX, y + 10, offsetX, 1)) {
      return false;
    }
  }

  // Nothing collided, so we can see the player
  return true;
}

(billy2000) #5

O: ty awesome code and ill look very closely on it to see how can i improve! Also i found why my code was not woking.I was testing with “crate” but that was the name …the type was “unstable”.(silly me xD) Thx a bunch for the help guys!