H
Heavenisreal777
Guest
Hi, GameMaker Community.
I'm making a top down game, but the enemies that are supposed to follow the player, sometimes run into walls and obstacles.
I've temporarily fixed this by doing the following:
// If player is near Enemy object then
target_x - is player postition x
target_y - is player postition y
// Otherwise
target_x_fr - is freeroam postition x
target_y_fr - is freeroam postition y
[ Enemy ] Step Event
[ Enemy ] End Step Event
Also, another problem. When an enemy is near another one, I want them to avoid each other but currently they don't do that.. Previously they just overlapped with each other.
I (kinda) got it working with the 'Enemy' object but sadly it just works with only other enemies that are not the same object as the one that is checking for nearby enemies (I think it's caused by the constant other enemy disabling, for example:
When Enemy 1 is near (Enemy 1 or Enemy 2 etc) then it works for only other Enemy 2. So if both (Enemy 1 and other Enemy 1) are checking for potential collision conflicts (running into each other) then they'll end up looping those checks forever because both are checking those simultaneously.. )
I don't really know how to exactly explain it more easily.
Here is the code I'm using to disable nearby other potential unwanted Enemy overlappings:
[ Grid ] Create Event ------------
[ Grid ] Step Event ------------
[ scr_reload_paths() ] Script ------------------
Here is the Enemy object's whole code:
[ Enemy ] Create Event ------------
[ Enemy ] Step Event ------------
[ Enemy ] End Step Event ------------
Sorry for such a long and messy code..
So, what could possibly be causing these problems?
I'm making a top down game, but the enemies that are supposed to follow the player, sometimes run into walls and obstacles.
I've temporarily fixed this by doing the following:
// If player is near Enemy object then
target_x - is player postition x
target_y - is player postition y
// Otherwise
target_x_fr - is freeroam postition x
target_y_fr - is freeroam postition y
[ Enemy ] Step Event
Code:
/// Stop from overlapping obstacles & walls
if !(mp_grid_path(grid, path, x, y, target_x, target_y, 1))
{
while (place_meeting(x, y, obj_obstacle))
{
target_x = x;
target_y = y;
target_x_fr = -32;
target_y_fr = -32;
x -= lengthdir_x(1, direction);
y -= lengthdir_y(1, direction);
}
}
Code:
if (collision_line(xprevious, yprevious, x, y, obj_obstacle, 1, 0))
{
event_perform(ev_collision, obj_obstacle);
}
I (kinda) got it working with the 'Enemy' object but sadly it just works with only other enemies that are not the same object as the one that is checking for nearby enemies (I think it's caused by the constant other enemy disabling, for example:
When Enemy 1 is near (Enemy 1 or Enemy 2 etc) then it works for only other Enemy 2. So if both (Enemy 1 and other Enemy 1) are checking for potential collision conflicts (running into each other) then they'll end up looping those checks forever because both are checking those simultaneously.. )
I don't really know how to exactly explain it more easily.
Here is the code I'm using to disable nearby other potential unwanted Enemy overlappings:
[ Grid ] Create Event ------------
Code:
var cell_w = cell_size;
var cell_h = cell_size;
var hcells = room_width div cell_w;
var vcells = room_height div cell_h;
/// Create the grid for all path functions using objects
global.grid = mp_grid_create(0, 0, hcells, vcells, cell_w, cell_h);
// List all OBJECTS to collide with
c_obj[0] = obj_enemy_01;
c_obj[1] = obj_enemy_02;
grid = global.grid;
Code:
checker = obj_enemy_01;
var i = 0;
if ( i < array_length_1d(c_obj) )
{
if (point_distance( checker.x, checker.y, c_obj.x, c_obj.y ) < 70) // if other enemy object is closer than 70 then reload all paths
{
scr_reload_paths(grid); // reload all objects on grid
if (checker.id != c_obj.id) // check if ID is not the same as other's
{ mp_grid_add_instances(grid, c_obj.id, 0); }
else i ++;
}
else
{
scr_reload_paths(grid); // reload all objects on grid
}
}
Code:
var path_grid = argument0;
mp_grid_clear_all(path_grid);
if (instance_exists(obj_obstacle)) mp_grid_add_instances(path_grid, obj_obstacle, 1);
if (instance_exists(obj_door)) mp_grid_add_instances(path_grid, obj_door, 1);
[ Enemy ] Create Event ------------
Code:
/// Create paths
path = undefined;
/// Setup MAIN freeroam coordinates
target_x_fr = x + irandom_range(-100,100);
target_y_fr = y + irandom_range(-100,100);
/// Setup target's coordinates
target_x = obj_player.x;
target_y = obj_player.y;
/// Setup speeds
spd_default = 18;
spd = spd_default;
/// Range from player
range_from_player = distance_to_object(obj_player); // get distance between Enemy and Player
follow_range = 320; // this is the max target following range
/// Setup FREE ROAM cooldown timers
fr_timer_max = 2;
fr_timer = fr_timer_max;
/// FREE ROAM coordinates - only used to give temporary coordinates to 'MAIN freeroam coordinates'
x_fr = -32;
y_fr = -32;
Code:
/// Setup grid and path for future reference
grid = global.grid;
path = path_add();
/// Setup Free Roam target
nearest_obstacle = obj_obstacle;
nearest_wall = instance_find(nearest_obstacle, random(instance_number(nearest_obstacle) - 1));
distance_wall = distance_to_object(nearest_wall);
if (fr_timer < 1)
{
if (path_index == -1)
{
// Reset free roam
x_fr = -32;
y_fr = -32;
while (x_fr == 0 and y_fr == 0) // While temporary free roam coordinates are not set yet
{
// Set temporary free roam coordinates to a random range
x_fr = irandom_range(-300,300);
y_fr = irandom_range(-300,300);
}
// Add new coordinates to x, y positions
target_x_fr = x + x_fr;
target_y_fr = y + y_fr;
// Reset free roam timer
fr_timer = fr_timer_max;
}
}
else
{
fr_timer -= 0.1;
}
/// Setup Player target
target_x = obj_player.x;
target_y = obj_player.y;
/// Follow target (Player)
if (mp_grid_path(grid, path, x, y, target_x, target_y, 1)) // if can reach Player on grid
{
if (distance_to_object(obj_player) <= follow_range*2)
{
path_start(path, spd+7, path_action_stop, 0);
}
}
else if (mp_grid_path(grid, path, x, y, target_x_fr, target_y_fr, 1)) // if can reach free roam coordinates on grid
{
if (distance_to_object(obj_player) > follow_range) // if Player is out of Enemy's range
{
path_start(path, spd/4, path_action_stop, 0);
}
else
{
path_start(path, spd, path_action_stop, 0);
}
}
else
{
path_end();
}
/// Set Enemy's angle to the direction it's moving towards
if (path_index != -1) angle = round(direction);
/// When Enemy reaches the Player, stop the movement and reset all coordinate variables
if ( place_meeting(x, y, obj_player) )
{
path_end();
target_x = x;
target_y = y;
target_x_fr = -32;
target_y_fr = -32;
}
Code:
if (collision_line(xprevious, yprevious, x, y, obj_obstacle, 1, 0))
{
event_perform(ev_collision, obj_obstacle);
}
So, what could possibly be causing these problems?
Last edited by a moderator: