This is an AI state machine prototype. The pathfinding is not the best, but I simply wanted to focus on the various detection zones and behaviour for an enemy.

CONTROLS

  • WASD = Control player.
  • Mouse / Left Click = Aim / Shoot.
  • Shift (hold) + WASD = Run.
  • + = Spawn more enemies.
  • T = toggle debug info on and off.
  • R = Reset room


BROAD DESIGN

  • Will patrol and occasionally change directions until detecting the player.
  • When detecting the player, will try to get within shooting range and shoot.
  • When losing sight of the player, will get to their last known position and return to patrol if it can't find the player.
  • If enemy health falls too low, the enemy will flee the player when detecting them.
  • Only one enemy is allowed to shoot at the player at once (token system).


MAIN BEHAVIOUR SCRIPT (sample)

#region // DETECTION LOOP

if !collision_line(x, y, oPlayer.x, oPlayer.y, oWall, true, true) {

lastknown_x = oPlayer.x;

lastknown_y = oPlayer.y;

// See when near

if point_in_triangle(oPlayer.x, oPlayer.y, x, y, sight_detect_near_cone_x1, sight_detect_near_cone_y1, sight_detect_near_cone_x2, sight_detect_near_cone_y2) {

player_is_detected = true;

}

// See from far when player is walking

else if point_in_triangle(oPlayer.x, oPlayer.y, x, y, sight_detect_far_cone_x1, sight_detect_far_cone_y1, sight_detect_far_cone_x2, sight_detect_far_cone_y2) and oPlayer.is_walking {

player_is_detected = true;

}

// Hear the player from really close

else if point_in_circle(oPlayer.x, oPlayer.y, x, y, hear_detect_near_radius) {

player_is_detected = true;

}

// Hear the player from near if player is walking

else if point_in_circle(oPlayer.x, oPlayer.y, x, y, hear_detect_walk_radius) and oPlayer.is_walking {

player_is_detected = true;

}

// Hear the player from far if player is running

else if point_in_circle(oPlayer.x, oPlayer.y, x, y, hear_detect_run_radius) and oPlayer.is_walking and oPlayer.is_running {

player_is_detected = true;

}

else {

player_is_detected = false;

}

}

else {

player_is_detected = false;

}

#endregion

#region // STATE LOOP

if (hp >= flee_theshold and player_is_detected) or (hp >= flee_theshold and alarm[1] > 0) {

state = "CHASE";

mp_potential_step_object(lastknown_x, lastknown_y, chase_speed, oWall);

if point_distance(x, y, oPlayer.x, oPlayer.y) < shoot_threshold and can_shoot and (global.token < global.maxtoken or is_shooting) {

if !is_shooting {

global.token = global.token + 1;

is_shooting = true;

}

can_shoot = false;

instance_create_depth(x, y, depth, oBulletEnemy);

alarm[2] = shoot_delay;

}

}

else if (hp < flee_theshold and player_is_detected) or (hp < flee_theshold and alarm[1] > 0) {

state = "FLEE";

if is_shooting {

is_shooting = false;

global.token = global.token - 1;

}

direction = point_direction(x, y, oPlayer.x, oPlayer.y) + 180;

speed = flee_speed;

}

else if !player_is_detected and state != "PATROL" {

state = "PATROL";

if is_shooting {

is_shooting = false;

global.token = global.token - 1;

}

direction = choose(0, 90, 180, 270);

speed = patrol_speed;

alarm[0] = change_direction;

}

#endregion

StatusPrototype
PlatformsHTML5
Rating
Rated 5.0 out of 5 stars
(1 total ratings)
AuthorSim Graveline
Made withGameMaker
Average sessionA few seconds
InputsKeyboard, Mouse