• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Problem with mp_grid

C

cirin92

Guest
Hello, I've started with make a point and click game, but I have problem with code functions which allow the player to move avoiding objects as desks or walls.

I found topics with mp_grid but not sure how it works.

Below my code.

My objRay (main character)
Create event:
x = 1320;
y = 928;
target_x = 0;
target_y = 0;
move = false;

Step event:
Step
if (mouse_check_button_pressed(mb_left))
{
target_x = mouse_x;
target_y = mouse_y;
move = true;


if instance_exists(objMouseclick)
{
if mp_grid_path(grid, path0, x, y, objMouseclick.x, objMouseclick.y, 1)
{
path_start(path0, speed/2, path_action_stop, 0);
}

}
}

if (point_distance(x, y, target_x, target_y) > 2 && move == true) {
image_speed = 0.75;
//walkleft
if(objRay.xprevious > target_x){
speed = 2.5;
sprite_index = sprRayWalkLeft;
//walkright
}
if(objRay.xprevious < target_x){
speed = 2.5;
sprite_index = sprRayWalkRight;
}
//walkup
if (objRay.xprevious == objRay.x) and (objRay.yprevious > objRay.y)
{
sprite_index = sprRayWalkRight;
}
//walkdown
if (objRay.xprevious == objRay.x) and (objRay.yprevious < objRay.y)
{
sprite_index = sprRayWalkLeft;
}
}

if (point_distance(x, y, target_x, target_y) <= 2) || move == false {
speed = 0;
image_speed = 0;
}

direction = point_direction(x, y, target_x, target_y);​

And my objDesk, which I want to be avoided by my hero
Create event
globalvar grid;
grid = mp_grid_create(0, 0, floor(room_width/10), floor(room_height/10), 10, 10);
mp_grid_add_instances(grid, objPoliceOfficeDesk, true);
I also made code to set objMouseclick, which I would like to use to set a path coordinates:
Leftpressed
if (mouse_check_button_pressed(mb_left))
{

objMouseclick.x = mouse_x;
objMouseclick.y = mouse_y;

}
 
Sorry for a lot of text here, but there's a few things to suggest :)

If you make a parent object (that is empty of any code), and give it any object as children that you want characters to avoid, then you can just add that parent object to the grid, and manage all objects in one go. But the object creating the grid, which should be a separate object from the rest, needs to be created AFTER any of the objects it's going to add (if the grid won't change)

So this requires using instance ordering in the rooms properties. As the other instances have to already be created for them to be added by the object making the grid - that is, if you know the obstacles to be avoided are fixed.

If the obstacles are dynamic, and can change over time, then the grid would need updating. Otherwise: as long as the object creating the grid in it's create event is created last in the room, it will be able to "capture" all the necessary instances to add.

Code:
mp_grid_add_instances(grid, obj_obstacle_parent, true);
You might want to check first that where you click is an empty grid cell. Also, I don't think you need to create a mouse object for this, as you have the code running in the step event of objRay.

create event objRay:
Code:
path0 = noone; // path variable must exist to be used later. This is setting up the variable for that, but at this point it is set to noone.
Here is my set up that works:
create event objRay:
Code:
path0 = noone;
cell_width = 10;
cell_height = 10;
grid = mp_grid_create(0, 0, floor(room_width/ cell_width), floor(room_height/ cell_height), cell_width, cell_height);
mp_grid_add_instances(grid, object2, true); // object2 is just what I called the object I filled the grid with :)
spd = 2.5; // this variable is an alternative to 'speed' I will explain why below............
step event objRay:
Code:
if (mouse_check_button_released(mb_left))
{
var m_x = mouse_x;
var m_y = mouse_y;
if mp_grid_get_cell(grid, m_x / cell_width, m_y / cell_height) == 0 // mouse coordinates have to be turned into grid coordinates, so are divided by cell width / height
{
if path_exists(path0)
{
path_delete(path0);
}
path0 = path_add();
if mp_grid_path(grid, path0, x, y, m_x, m_y, 1)
{
path_start(path0, spd, path_action_stop, 0);
}
}
}

if path_exists(path0)
{
if path_position < 1
{
image_speed = 0.75;
//walkleft
if(objRay.xprevious > target_x)
{
if sprite_index != sprRayWalkLeft
{
sprite_index = sprRayWalkLeft;
} //walkright
}
if(objRay.xprevious < target_x)
{
if sprite_index != sprRayWalkRight
{
sprite_index = sprRayWalkRight;
}
}
//walkup
if (objRay.xprevious == objRay.x) and (objRay.yprevious > objRay.y)
{
if sprite_index != sprRayWalkRight
{
sprite_index = sprRayWalkRight;
}
}
//walkdown
if (objRay.xprevious == objRay.x) and (objRay.yprevious < objRay.y)
{
if sprite_index != sprRayWalkLeft
{
sprite_index = sprRayWalkLeft;
}
}
}
else
{
image_speed = 0;
path_delete(path0);
}
}
I changed the code above to use info about the path to set the image speed, and also the sprite index. The last bit is checking to see if the sprite is already set, as it would otherwise constantly be resetting it and interfere with any animation it has. When the path has finished it sets image_speed to 0, and deletes the path.

destroy event objRay:
Code:
if path_exists(path0)
{
path_delete(path0); // path must be cleaned up and deleted when instance is destroyed
}
REGARDING 'SPEED':
When this is not defined in the create event of an object it is given a value of 0. It seems that you are trying to path using 'speed', but are actually setting the value of 'speed' after the path has been made. The first path would end up with a speed of zero, although you are not setting the path properly to begin with (a path must exist before you can use the mp grid to pathfind with it)

However: you don't want 'speed' set in the create event, as it will start an instance moving even when it has no 'direction' set - as 'direction' has a value of 0 when not defined. Basically if 'speed' is set in the create event it will start moving right.

As soon as the path starts it sets 'speed' to zero anyway, so any further alteration of this variable has no effect.

REGARDING THE MP GRID:
Cell sizes must be the size of the instance you want to have travelling the path, although you might make an exception here - as you allow for "perspective". By that I mean when you walk in front of a desk the top half of the character passes over it, but the feet / legs etc are moving around the desk without clipping into it.

Your cells sizes of 10 width, and 10 height, will not suffice unless objRay only happens to be 10 pixels wide...which I doubt it is :)

If you want the character to pass around objects without walking through them, then the cells will have to be at least the width of the character. The height of the cells need not be the same size as objRay, but would probably want to be half the size of it - so that if they walk in "front" of an object they can appear over the top of it.

If you wanted the same thing to happen when they walk behind an object, then you wouldn't use mp_grid_add_instances - as that will fill in every part of the objects sprite into the grid. Use mp_grid_add_rectangle instead, and only do the size of the bottom half of the object. Leaving the top half free to be passed behind by objRay.

If you don't want that this "perspective" to happen, then the cells must be the exact width and height of objRay, or at least larger than those dimensions, for proper avoidance to happen.
grid.png
Full sized cells for no clipping ^^
 
Last edited:
C

cirin92

Guest
Wow, wow, and wow. I didn't expect that much help! Many thanks for your post which gave me a lot of knowledge about mp_grid. I've checked it using your advice and it works :) Thanks again.
 
Top