SOLVED Chase State

ERK

Member
I could use some help with my chase state.

Here's what I'm trying to get this code to do:
A: Chase the player (which is working)
B: When the enemy is within range (enemyAttackRadius), it will stop moving and change to the attack state (which is working)
C: If the player moves too close to the enemy, I want the enemy to back up and position itself back to that range (enemyAttackRadius). This way, the player and enemy are always kept apart and can't stack on one another, by having the enemy reposition itself. (this is sort of working)

The enemyAttackRadius = 32

The idea is to always keep the skeleton at 32 pixels from the player, no matter where the player moves.


GML:
// Exit Script if Player Doesn't Exist
    if !instance_exists(oPlayer) exit;
 
    var _distanceToPlayer = point_distance(x, y, oPlayer.x, oPlayer.y);
    if (_distanceToPlayer <= enemyAttackRadius) && (_distanceToPlayer > enemyAttackRadius)
    {
        // Change to Attack State
        state = attack;

    }
 
    if (_distanceToPlayer > enemyAttackRadius)
    {
        // Move and Face Forward
        xTo = oPlayer.x;
        yTo = oPlayer.y;
 
        var _distanceToGo = point_distance(x,y,xTo,yTo);
        dir = point_direction(x,y,xTo,yTo);
        if (_distanceToGo > speedWalk)
        {
            hSpeed = lengthdir_x(speedWalk, dir);
            vSpeed = lengthdir_y(speedWalk, dir);
        }
        else
        {
            hSpeed = lengthdir_x(_distanceToGo, dir);
            vSpeed = lengthdir_y(_distanceToGo, dir);
        }
     
        // Sprite Directions
        if (dir > 45 && dir < 135)
        {
            sprite_index = sSkeleton_Walk_U;
        }
        if (dir >= 135 && dir <= 225)
        {
            sprite_index = sSkeleton_Walk_L;
        }
        if (dir > 225 && dir < 315)
        {
            sprite_index = sSkeleton_Walk_D;
        }
        if ((dir >= 315 && dir < 360) || (dir >= 0 && dir <= 45))
        {
            sprite_index = sSkeleton_Walk_R;
        }
 
        // Collision
        Skeleton_Collision();
    }
 
    if (_distanceToPlayer <= enemyAttackRadius)
    {
        // Move and Face Backward
        xTo = -oPlayer.x;
        yTo = -oPlayer.y;
 
        var _distanceToGo = point_distance(x,y,xTo,yTo);
        dir = point_direction(x,y,xTo,yTo);
        if (_distanceToGo > speedWalk)
        {
            hSpeed = lengthdir_x(speedWalk, dir);
            vSpeed = lengthdir_y(speedWalk, dir);
        }
        else
        {
            hSpeed = lengthdir_x(_distanceToGo, dir);
            vSpeed = lengthdir_y(_distanceToGo, dir);
        }
     
        // Sprite Directions
        if (dir > 45 && dir < 135)
        {
            sprite_index = sSkeleton_Walk_D;
        }
        if (dir >= 135 && dir <= 225)
        {
            sprite_index = sSkeleton_Walk_R;
        }
        if (dir > 225 && dir < 315)
        {
            sprite_index = sSkeleton_Walk_U;
        }
        if ((dir >= 315 && dir < 360) || (dir >= 0 && dir <= 45))
        {
            sprite_index = sSkeleton_Walk_L;
        }
 
        // Collision
        Skeleton_Collision();
    }
 
Last edited:

Nidoking

Member
Do you have a specific question?

The answer is probably going to be "learn to use else", but I don't know what's wrong to tell you anything specific based on this post.
 

ERK

Member
Do you have a specific question?

The answer is probably going to be "learn to use else", but I don't know what's wrong to tell you anything specific based on this post.
Yes, how can I adjust that code to get my enemy to move within 32 pixels of the player, attack, if the player moves further than 32 pixels the enemy chases, and if the player is closer than 32 pixels, the enemy backs up to attack again?

The code above is close, but the enemy tends to circle the player and not just back up.
 

ERK

Member
why not use point_in_circle(px, py, x1, y1, rad);
its great for radius zones
Thanks! I'd like to give this a shot.
px and py would be the player position?
x1 and y1 are the enemy position?
rad is the 32 pixels?
 

Nidoking

Member
xTo = -oPlayer.x; yTo = -oPlayer.y;
I don't think this is what you want. You're taking the negative of the player's coordinates. That's always going to be off the top-left of the room. You should probably calculate the direction normally and then add 180.
 
  • Like
Reactions: ERK

Tyg

Member
if point_in_circle(Player.x,Player.y,32); // Ok you know your player has entered the zone
{
state = attack; // he enters attack state
direction = Player.direction + 180; // skelly will move opposite of player
speed = speedwalk; //run away
}
else
{
state = chase;
direction = point_direction(x, y, Player.x, Player.y);
}

Well something like that ...lol
 
  • Like
Reactions: ERK

ERK

Member
Got everything working, I just decided to break them into smaller parts as their own states.
 
  • Like
Reactions: Tyg
Top