1. Hey! Guest! The 36th GMC Jam will take place between February 27th, 12:00 UTC - March 2nd, 12:00 UTC. Why not join in! Click here to find out more!
    Dismiss Notice

Easy Enemy AI (Idle, Chase, Attack, and Flee)

Discussion in 'Tutorials' started by Alaska Minds, Feb 12, 2020.

Tags:
  1. Alaska Minds

    Alaska Minds Member

    Joined:
    Feb 11, 2020
    Posts:
    12
    GM Version: Studio (All)
    Target Platform: Any
    Download: None (Code below)
    Links: Example gif of the code below: https://alaskaminds.org/2020/02/11/game-maker-easy-enemy-ai-idle-chase-attack-and-flee/
    Summary:
    Hello All! I'm going to show you how to create an enemy object that will Idle, Chase, Attack, or Flee using one method (turns out there are many out there in programming).

    This is an instance contained state system (states being idle, chase, attack, flee) using if statements all written within the enemy object's code, opposed to the state system others use by using enum to create the different states and using switch to define and change behavior. I hope this helps.

    (Please note my grid is 32. You may need to adjust accordingly to your game's grid.)
    Legend:
    Main Character Object = char;
    Wall Object = object1;
    Enemy Object; obj_enemy;
    Bullet/Sword/Any Attack Object = Bullet in Collision Event on Step 5 below

    Steps to create an enemy object and write the AI logic:
    Further explanations within the comments ("// text") in the code.

    Step 1. Create object for enemy.
    Step 2. Add Create Event and add code below.
    Code:
    // Instance Creation Variable Sets
    
    healthenemy=100;
    invincible=false;
    chase=false;
    runaway=false;
    justrun=false;
    Step 3. Add Step Event and add code below.
    Code:
    // AI Movement Logic
    
    // Just Run
    if justrun=true {
        move_towards_point(char.x,char.y,5);
    } else {
    
    // Initial Proximity Trigger for Chase
    if runaway=false && chase=false && distance_to_object(char) < 200 {
        chase=true;
        runaway=false;
    }
    
    // New Proximity Trigger for Chase (Only one for life of instance)
    if chase=true && runaway=false && distance_to_object(char) < 400{
        move_towards_point(char.x,char.y,5);
    }
    
    // If Char is more than 400 pixels away, stop Chase
    if chase=true && runaway=false && distance_to_object(char) > 400 {
        move_towards_point(char.x,char.y,0);
    }
    
    // Flee in random direction away from Char after Collision Event with Char
    if chase=false && runaway=true {
        move_towards_point(char.x,char.y,5);
        playerdirection = point_direction(x,y,char.x,char.y);
        direction = (playerdirection + (180 + random(40)) );
    }
    }
    
    // Stop and Start Animation
    if speed = 0 {
        image_speed = 0;
    } else {
        image_speed = 2;
    }
    }
    Step 4. Add Alarm Event and add code below.
    Code:
    // Stops Flee and Continues Chase
    chase=true;
    runaway=false;
    invincible=false
    Step 5. Add Collision Bullet Event and add code below.
    Code:
    // Initiates Chase
    justrun=true;
    
    // Death or enemy HP loss
    if healthenemy <= 0 {
       instance_destroy(self);
       score += 100;
    }else{
    if invincible = false {
       healthenemy -= 30;
       invincible=true;
       alarm_set(0,20); // Set step value to length of Attack animation
    }
    }
    
    // Moves instance away from bullet  (Provides Object Overlap Protection)
    var dir;
    var move_dis = 32;  // pixels to move away from other object in collision
    
    // If both instances are in the same location, set direction random
    if (x == other.x && y == other.y)
        dir = random(360);
    
    // Move in opposite direction of object in collision
    else
        dir = point_direction(other.x,other.y,x,y);
    
    // Move to new location but away from char and other enemy
    
    var dx = lengthdir_x(move_dis,dir);
    var dy = lengthdir_y(move_dis,dir);
    
    if (!place_meeting(x+dx,y,char)) x += dx;
    if (!place_meeting(x,y+dy,char)) y += dy;
    if (!place_meeting(x+dx,y,obj_enemy)) x+=dx;
    if (!place_meeting(y,y+dy,obj_enemy)) y +=dy;
    
    [/CODE]
    Step 6. Add Collision Char Event and add code below.
    Code:
    // Sets variables to initiate Flee and an Alarm to begin Chase again
    chase=false;
    runaway=true;
    justrun=false;
    alarm_set(0,40);
    
    // Removes one health point after collision of enemy and char objects
    health -= 1;
    if health < 1 {
       room_restart();
    }
    
    // Moves instance away from char (Provides Object Overlap Protection)
    var dir;
    var move_dis = 32;  // pixels to move away from other object in collision
    
    // If both instances are in the same location, set direction random
    if (x == other.x && y == other.y)
        dir = random(360);
    
    // Move in opposite direction of object in collision
    else
        dir = point_direction(other.x,other.y,x,y);
    
    // Move to new location but away from wall and other enemy
    
    var dx = lengthdir_x(move_dis,dir);
    var dy = lengthdir_y(move_dis,dir);
    
    if (!place_meeting(x+dx,y,object1)) x += dx;
    if (!place_meeting(x,y+dy,object1)) y += dy;
    if (!place_meeting(x+dx,y,obj_enemy)) x+=dx;
    if (!place_meeting(y,y+dy,obj_enemy)) y +=dy;
    
    Step 7. Add Collision Enemy Object and add code below.
    Code:
    // Moves instance away from another enemy (Provides Object Overlap Protection)
    var dir;
    var move_dis = 32;  // pixels to move away from other object in collision
    
    // If both instances are in the same location, set direction random
    if (x == other.x && y == other.y)
        dir = random(360);
    
    // Move in opposite direction of object in collision
    else
        dir = point_direction(other.x,other.y,x,y);
    
    // Move to new location but away from wall and char
    
    var dx = lengthdir_x(move_dis,dir);
    var dy = lengthdir_y(move_dis,dir);
    
    if (!place_meeting(x+dx,y,object1)) x += dx;
    if (!place_meeting(x,y+dy,object1)) y += dy;
    if (!place_meeting(x+dx,y,char)) x +=dx;
    if (!place_meeting(x,y+dy,char)) y += dy;
    
    Step 8. Add Collision Wall Object and add code below.
    Code:
    // Moves instance away from wall  (Provides Object Overlap Protection)
    var dir;
    var move_dis = 32;  // pixels to move away from other object in collision
    
    // If both instances are in the same location, set direction random
    if (x == other.x && y == other.y)
        dir = random(360);
    
    // Move in opposite direction of object in collision
    else
        dir = point_direction(other.x,other.y,x,y);
    
    // Move to new location but away from char and other enemy
    
    var dx = lengthdir_x(move_dis,dir);
    var dy = lengthdir_y(move_dis,dir);
    
    if (!place_meeting(x+dx,y,char)) x += dx;
    if (!place_meeting(x,y+dy,char)) y += dy;
    if (!place_meeting(x+dx,y,obj_enemy)) x+=dx;
    if (!place_meeting(y,y+dy,obj_enemy)) y +=dy;
    
     
    Last edited: Feb 15, 2020 at 8:59 AM
    Amon likes this.

Share This Page