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

Legacy GM Mouse interpolation

Mazey

Member
Hello
In the project I'm working on, I move my mouse over blocks, when my mouse is on a block the block's color changes, this is working fine. My issue is that the mouse 'skips' blocks when you move the mouse too fast, which shouldn't be possible, so I'm trying to interpolate the mouse movement.
Here is the code I'm using right now, but the game freezes as soon as the game starts (because of the while loop):
Code:
//create event obj_mouse
x = mouse_x;
y = mouse_y;
_x = x;
_y = y;

//step event obj_mouse
x = mouse_x;
y = mouse_y;

if (point_distance(_x,_y,mouse_x,mouse_y) > sprite_get_width(spr_block))
{
    x = _x;
    y = _y;
    while (x != mouse_x && y != mouse_y)
    {
        x += lengthdir_x(1,point_direction(x,y,mouse_x,mouse_y));
        y += lengthdir_y(1,point_direction(x,y,mouse_x,mouse_y));
    }
}

_x = x;
_y = y;
Am I missing something?
 

Alice

Darts addict
Forum Staff
Moderator
First of all, keep in mind that lengthdir_x/lengthdir_y will likely return a fractional number. It means that once the mouse closes onto the correct position, it might "jump" over the destination if it's a fraction away from that, and then keep jumping over it back and forth - causing the infinite "while" loop.

Second, you don't do anything inbetween the steps towards the mouse. It means that blocks won't ever register there was something hovering over them - they just don't have any opportunity. Merely changing x/y position doesn't mean all objects will acknowledge that immediately, and if the position changes shortly afterwards, they probably never will.

To address both issues, you might rework your code like below. I took the liberty of removing _x/_y, as they are not necessary to the proper working of the code. Also, I added temporary "precision" variable. The smaller it is, the lower is the chance of skipping the blocks, because the mouse movement will have smaller steps. However, smaller steps means more checks, and it can cause massive slowdowns, so be careful wth that.
Code:
//create event obj_mouse
x = mouse_x;
y = mouse_y;

//step event obj_mouse
var precision = 1;
while (point_distance(x,y,mouse_x,mouse_y) > precision)
{
    x += lengthdir_x(precision,point_direction(x,y,mouse_x,mouse_y));
    y += lengthdir_y(precision,point_direction(x,y,mouse_x,mouse_y));
    // check for blocks hovering here
    do_stuff_with_blocks_and_whatever(x,y);
}
// once the interpolated mouse is close enough, it jumps straight to the actual mouse position
x = mouse_x;
y = mouse_y;

_x = x;
_y = y;
By the way, how are the blocks arranged? Are they always snapped to a grid (e.g. 32x32), or can they have arbitrary positions? If the blocks are snapped to grid, then it might be possible to optimize the code considerably, so that all blocks crossing the mouse path will be highlighted and there's no precision variable shenanigans involved. Generally, the problem changes from "whether the interpolated mouse hovers over a block" to "whether the interpolated mouse crosses specific grid fields". If that's your case, I might think of some code to handle that case.
 

Mazey

Member
That makes sense, I adapted the code and it works like a charm, thanks!
By the way, how are the blocks arranged?
They're always in a square like this, but possibly different sizes. They're not in an actual grid though, just placed in a square position with a for loop (which I have to work on :p). The code you sent me is fine though!
 
Top