• 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!

GameMaker Better collions with mouse control

Sawyer

Member
Hello everyone,

I work on a little RTS.
Actually i move my unit with my mouse (right click). If my unit meet a wall it stop moving. i wrote a simple piece of code to do that.

In global right pressed :

Code:
if (selected == true)
{
   
    if (place_free(mouse_x, mouse_y))//if there are no obstacles at this point
    {
        xx = mouse_x;//get x
        yy = mouse_y;//get y
       
        moving = true;//start moving
       
        instance_create(xx, yy, obj_goto);//create animation
    }
}
In an event collision with obj_wall :

Code:
moving = false
However this code it too basic, i will need to find a better way to have collisions beacause i will work with more than 50 units further my collisions aren't good enough, sometimes i have a space between my obj_wall and my unit.
And also when i click many time on the other side of the wall my unit cross the wall step by step.

I tryed to create a script, but everytime my unit crossing my wall without stop.

Any ideas to please?
 
Last edited:
H

hunijkah

Guest
Have you looked into mp_grids ?

https://docs.yoyogames.com/source/dadiospice/002_reference/movement and collisions/motion planning/index.html

Pretty much, you create a grid like so:
grid_cell_width = 32; //the width of each square in the grid
grid_cell_height = 32; //the height of each square in the grid

grid_width = floor(room_width/grid_cell_width); //You want to know how many cells will be in the room total so we take the room width and divide by grid_cell_width
grid_height = floor(room_height/grid_cell_height);

//Then create a grid
globalvar grid;
grid = mp_grid_create(0, 0, grid_width, grid_height, 32, 32);

Then you add on the objects that are occupying spaces on the grid. You can either mark spaces as occupied manually by doing:
mp_grid_add_cell( grid, X_POS_IN_GRID, Y_POS_IN_GRID)

Or you could use the mp_grid_add_instances to occupy all spaces of the grid where a specific instance is. For example anything in the room that should occupy space should have the same parent object and you could add all instances of that parent to the grid.

Every time an object moves, you could remove it's space on the grid with mp_grid_clear_cell and then use mp_grid_add_cell to occupy the space they will end up at.

For debugging you can see what the grid looks like by drawing it transparently onto the board:
MUST BE IN DRAW EVENT:
draw_set_alpha(0.3);
mp_grid_draw(grid);
draw_set_alpha(1);

The cool thing about this too is that you can use path finding with it. So say you want to find the best route to move a character from their current x,y coordinates to the mouse x, y coordinates you could do something like:
with (obj_hero)
{
path = path_add();
if mp_grid_path(grid, path, x, y, mouse_x, mouse_y, 1)
{
path_start(path, 0, 3, 0);
} else }
//No path could be found.
}
}

This will set the obj_hero on a path to the mouse_x & mouse_y avoiding occupied spaces on the grid.

Hope this helps!
 

bbbower

Member
In an event collision with obj_wall :

Code:
moving = false
x=xprevious;
y=yprevious;
There are a thousand tutorials on making your own collision system and that would be the more efficient way. But here is just a little tid bit that helps with that step by step crossover with gamemakers built in stuff. Just add this to the collision event. I've used this method before with some of my first prototypes it should still work.
 

Sawyer

Member
I tried to make better collisions again and i used this code in a step event :

Code:
if place_meeting (x , y, obj_wall)
{
   
   movementSpeed = 0;
}
My collisions seems correct, but if my player touch the wall he can't move...He stay blocked on the wall....
 
Last edited:

Sawyer

Member
I'm near to have it, this is my new code, collisions are perfect i have just 1 last problem

My script for my collisions :
Code:
/// @description collisions(hspd,vspd);
/// @function collisions
/// @param hspd
/// @param vspd
/// Move (hspd , vspd)
var hspd = argument[0];
var vspd = argument [1];

// Horizontal collisions
if (place_meeting(x+hspd, y,obj_wall)) {
    while (!place_meeting(x+sign(hspd), y,obj_wall)) {
        x+=sign(hspd);
    }
    hspd = 0;
}

// Move horizontally
x+=hspd;

//Vertical collisions
if (place_meeting(x, y+vspd,obj_wall)) {
    while (!place_meeting(x,y+sign(vspd),obj_wall)) {
        y+=sign(vspd);
    }
    vspd = 0;
}

// Move vertically
y+=vspd;
A step event for my player

Code:
depth = y*-1;
var pdir = point_direction(x,y,mouse_x,mouse_y);//face the mouse

if (!mouse_check_button(mb_right)) {
 
    mspd = 0;///not moving
} else{
    mspd=3;//moving
}

var hspd = lengthdir_x(mspd,pdir);
var vspd = lengthdir_y(mspd,pdir);

collisions(hspd,vspd); //script
My last problem is that actually i need to keep the right button of my mouse pressed if i want to move.

Everytime i try to find a way to just press 1 time the right button of my mouse to have a movement towards the place of my click, i FAIL.

I used : move_towards_point( x, y, sp ); but with this code my collisions works bad.
 
Last edited:

Sawyer

Member
I have heard of these but with my system I have the impression that I could have correct collisions, I just need to find a way for my object to move to the point where I clicked, respecting the collisions.
 

Sawyer

Member
I don't know if it's possible but maybe i can create a path between my player position and the place where i click?
 

Sawyer

Member
I tried something else :

Code:
var pdir = point_direction(x,y,mouse_x,mouse_y);//face the mouse

mspd=3;

var hspd = lengthdir_x(mspd,pdir);
var vspd = lengthdir_y(mspd,pdir);

collisions(hspd,vspd);//rename this to his script name
With this code, collisions are respected but my object follow my cursor every time without any click on my mouse...
 
Top