// note: uses image_index to make globalvars for this demo so you can simply
// paste everything into a draw event of an object in a new project for test
if (image_index != -1)
{
image_index = -1; // so it won't overwrite @next step
image_speed = 0;
globalvar enemy_x, enemy_y;
globalvar enemy_a, enemy_v;
globalvar enemy_flee_dist;
globalvar enemy_target_a;
globalvar enemy_angular_v;
globalvar enemy_ai_stage;
globalvar enemy_ai_timer;
enemy_x = room_width/2; // start position
enemy_y = room_height/2;
enemy_a = 90; // start angle
enemy_v = 5; // velocity
enemy_angular_v = 5;
enemy_flee_dist = 100; // distance from player when enemy flee
enemy_ai_stage = 0; // 0: move to player
// 1: flee from player
// 2: wait for orders
enemy_ai_timer = 0; // amount of steps spent waiting
globalvar player_x, player_y;
globalvar player_old_x;
globalvar player_old_y;
globalvar player_old_d;
globalvar player_move_d;
player_x = mouse_x;
player_y = mouse_y;
player_old_d = 0;
player_old_x = 0;
player_old_y = 0;
player_move_d = 0;
}
// -------------------------------------------------------------------------
// simple player movement
var player_move_d_old = player_move_d;
player_old_x = player_x; player_old_y = player_y;
player_x = mouse_x; player_y = mouse_y;
var player_move_x = player_x - player_old_x;
var player_move_y = player_y - player_old_y;
var player_move = (player_move_x<>0) || (player_move_y<>0);
if (player_move)
{
player_move_d = point_direction( player_old_x, player_old_y, player_x, player_y );
}else{
player_move_d = player_move_d_old;
}
// simple enemy movement
var enemy_hunt = 0; // ai stages
var enemy_flee = 1;
var enemy_wait = 2;
// towards the player
if (enemy_ai_stage == enemy_hunt)
{
enemy_target_a = point_direction( enemy_x, enemy_y, player_x, player_y );
if (point_distance( enemy_x, enemy_y, player_x, player_y ) <= enemy_flee_dist)
enemy_ai_stage = enemy_flee;
}
// away from player
if (enemy_ai_stage == enemy_flee)
{
// player is moving
if (!player_move == 0)
{
// where is the safest route - behind, right, or left of player?
var behind_x = player_x-lengthdir_x( enemy_flee_dist, player_move_d ); // get behind info
var behind_y = player_y-lengthdir_y( enemy_flee_dist, player_move_d );
var check_behind = point_distance( enemy_x, enemy_y, behind_x, behind_y );
var left_x = player_x-lengthdir_x( enemy_flee_dist, player_move_d-90 ); // get left info
var left_y = player_y-lengthdir_y( enemy_flee_dist, player_move_d-90 );
var check_left = point_distance( enemy_x, enemy_y, left_x, left_y );
var right_x = player_x-lengthdir_x( enemy_flee_dist, player_move_d+90 ); // get right info
var right_y = player_y-lengthdir_y( enemy_flee_dist, player_move_d+90 );
var check_right = point_distance( enemy_x, enemy_y, right_x, right_y );
// try to avoid collision with player using shortest route
if (check_behind < check_left) && (check_behind < check_right) // target is behind player
{
enemy_target_a = point_direction( enemy_x, enemy_y, behind_x, behind_y );
}
if (check_left < check_behind) && (check_left < check_right) // target os tp tje ;eft
{
enemy_target_a = point_direction( enemy_x, enemy_y, left_x, left_y );
}
if (check_right < check_behind) && (check_right < check_left) // target is to the right
{
enemy_target_a = point_direction( enemy_x, enemy_y, right_x, right_y );
}
// player is not moving
}else{
// choose random side of player (at 45 degree interval)
var player_direction = point_direction( enemy_x, enemy_y, player_x, player_y );
enemy_target_a = player_direction + choose( -45, 45 );
}
enemy_ai_stage = enemy_wait;
}
// flee for 30 steps
if (enemy_ai_stage == enemy_wait)
{
if (enemy_ai_timer == 1) enemy_ai_stage = enemy_hunt;
enemy_ai_timer = (enemy_ai_timer+1)%31
}
// update enemy
var aDiff = angle_difference( enemy_a, enemy_target_a );
enemy_a -= min( abs(aDiff), enemy_angular_v ) * sign(aDiff);
enemy_x += (lengthdir_x( enemy_v, enemy_a ));
enemy_y += (lengthdir_y( enemy_v, enemy_a ));
// Draw..
// draw backdrop
draw_set_colour( c_black );
draw_rectangle( 0, 0, room_width, room_height, 0 );
// draw enemy
var enemy_size = 20;
var eX1 = enemy_x - (lengthdir_x( enemy_size/2, enemy_a+90 ));
var eY1 = enemy_y - (lengthdir_y( enemy_size/2, enemy_a+90 ));
var eX2 = enemy_x + (lengthdir_x( enemy_size/2, enemy_a+90 ));
var eY2 = enemy_y + (lengthdir_y( enemy_size/2, enemy_a+90 ));
var eX3 = enemy_x + (lengthdir_x( enemy_size, enemy_a ));
var eY3 = enemy_y + (lengthdir_y( enemy_size, enemy_a ));
if( enemy_ai_stage == enemy_hunt ) draw_set_colour( c_red );
else draw_set_colour( c_yellow );
draw_triangle( eX1, eY1, eX2, eY2, eX3, eY3, 0 );
// debug enemy
var temp_xlen = lengthdir_x( 50, enemy_target_a );
var temp_ylen = lengthdir_y( 50, enemy_target_a );
var eX4 = eX3+temp_xlen;
var eY4 = eY3+temp_ylen;
draw_set_colour( c_teal );
draw_line( eX3, eY3, eX4, eY4 );
draw_circle( eX4, eY4, 2, 0 );
// draw player
var player_size = 20;
var pX1 = player_x - (lengthdir_x( player_size/2, player_move_d+90 ));
var pY1 = player_y - (lengthdir_y( player_size/2, player_move_d+90 ));
var pX2 = player_x + (lengthdir_x( player_size/2, player_move_d+90 ));
var pY2 = player_y + (lengthdir_y( player_size/2, player_move_d+90 ));
var pX3 = player_x + (lengthdir_x( player_size, player_move_d ));
var pY3 = player_y + (lengthdir_y( player_size, player_move_d ));
draw_set_colour( c_white );
draw_triangle( pX1, pY1, pX2, pY2, pX3, pY3, 0 );
// debug player
if (player_move)
{
var temp_xlen = lengthdir_x( 50, player_move_d );
var temp_ylen = lengthdir_y( 50, player_move_d );
var pX4 = pX3+temp_xlen;
var pY4 = pY3+temp_ylen;
draw_set_colour( c_teal );
draw_line( pX3, pY3, pX4, pY4 );
draw_circle( pX4, pY4, 2, 0 );
}