GML - Enemy AI moving erractically

  • Thread starter Shariku Onikage
  • Start date
S

Shariku Onikage

Guest
I'm trying to create an enemy patrol route with multiple states (wandering, alerted, chasing, searching, returning to start point and wandering again). Wandering, detecting the player and chasing him appear to work fine, but when the enemy object tries to run to the player's last known point, the object behaves erratically, flickering on the spot and not moving in any direction (as if speed was zero and direction was constantly switching +180 degrees each time).

My code is below. I get the feeling that it's the lastKnownPositionX and lastKnownPositionY that's causing the issues. Can anyone help in seeing any obvious mistakes that i've made?

Thanks in advance.

oEnemy object - Step:

Code:
if status = "Wander" {


    speed = patrolSpeed;
    testForAlert();  //test to see if enemy can see player, works as expected

} else if status = "Alert" {

    if ableToSee(oPlayer) {   //if still able to see player, will run towards player, works as expected
    
        speed = chaseSpeed;
        direction = point_direction(x,y,oPlayer.x,oPlayer.y);
    
    } else {  //will stop running towards player
        lastKnownPositionX = oPlayer.x;
        lastKnownPositionY = oPlayer.y;  //notes the x and y of the last spot the player was seen by the enemy, testing shows that this gets noted down kind of as expected (e.g. x = 120.45)
        status = "RuntoLastPoint"; //no longer chasing player, now trying to find player
        doIActivate=1000;  //for testing, yes it does
    }
    
}

if status = "RuntoLastPoint" {
        testForAlert(); //test to see if enemy can see player
        if (x ==lastKnownPositionX && y ==lastKnownPositionY) {
                status = "Searching";
                doIActivate=1; //for testing, can't tell if this works as it switches to 2 too quickly
        } else {
                alarm[2]=room_speed*2; //will switch status to "Searching" if unable to reach player's last point in two seconds, this doesn't appear to happen
                speed = chaseSpeed;
                direction = point_direction(x,y,lastKnownPositionX,lastKnownPositionY); //run towards the last point the player was seen at - this doesn't happen, the enemy object just shakes on the spot instead
                doIActivate=2; //for testing, yes it does, and it stays there too
            }
            }
 
W

wagyu_so_gud

Guest
It looks like alarm[2] will not count down correctly. The else statement keeps the alarm[2] at room_speed*2. One suggestion is to set the alarm[2] when it changes status to "RuntoLastPoint". Or alternatively, you could do something like this:

Code:
if status = "RuntoLastPoint" {
          if alarm[2] == -1 //alarm is not active
          {
          alarm[2] = room_speed*2; alarm is activated, counts down
          }
}


if distance_to_point(lastKnownPositionX, lastKnownPositionY) < 10 {         //(x ==lastKnownPositionX && y ==lastKnownPositionY) {
                status = "Searching";
                doIActivate=1; //for testing, can't tell if this works as it switches to 2 too quickly
}
In the above, I suggest trying out distance_to_point because x/y will not be exactly at lastKnownPositionX/lastKnownPositionY, respectively.

Alarm[2] counts down and executed:

Code:
///alarm[2]
         if (distance_to_point((lastKnownPositionX, lastKnownPositionY)  > 10 {
         speed = chaseSpeed;
         direction = point_direction(x,y,lastKnownPositionX,lastKnownPositionY);
         doIActivate=2; //for testing, yes it does, and it stays there too
}
 
S

Shariku Onikage

Guest
Thanks Wagyu. I got it working with your suggestions. Final code below:

Code:
if status= "RuntoLastPoint" {
        if alarm[2]==-1{
            alarm[2]=room_speed*2;
        }
        testForAlert();
        if (distance_to_point(lastKnownPositionX, lastKnownPositionY) < 10) {
                status = "Searching";
                } else {               
                speed = chaseSpeed;
                direction = point_direction(x,y,lastKnownPositionX,lastKnownPositionY);
            }
            }
I think in the end it's more the alarm triggering straightaway that prevents any issues occurring (the enemy still vibrates against the wall but i think that's more due to collision issues), but this particular status doesn't need to be around long enough for it to matter.
 
Top