• Hey! Guest! The 40th (!!!) GMC Jam will take place between February 25th, 12:00 UTC to March 1st 12:00 UTC. Why not join in this very special anniversary jam! Click here to find out more!

Help giving an object that moves in a grid a maximum range

Lucretius

Member
I have this object that moves a 32x32 block every time it moves with a state machine. Now I want to limit it's range, let's say by 1 block in every direction (32x32). I have tried many things, but every time it moves away further away from it's spawn point. In hte create event, I have the spawn point saved as startX and startY, and the maximum range, which is 32, is set by the variable maxDistance. The movement is being triggered in the alarm event. This is my step event (the state machine):

GML:
/// @description stop and pick new direction
if (action == 0 && place_snapped(32,32)) {
    image_speed = 0;
    direction = 0;
    speed = 0;
}
if (action == 1 && place_snapped(32, 32)) {
    sprite_index = spr_chickenRight;
    image_speed = 0.5;
    direction = 0;
    speed = 0.5;
}
if (action == 2 && place_snapped(32, 32)) {
    sprite_index = spr_chickenUp;
    image_speed = 0.5;
    direction = 90;
    speed = 0.5;
}
if (action == 3 && place_snapped(32, 32)) {
    sprite_index = spr_chickenLeft;
    image_speed = 0.5;
    direction = 180;
    speed = 0.5;
}
if (action == 4 && place_snapped(32, 32)) {
    sprite_index = spr_chickenDown;
    image_speed = 0.5;
    direction = 270;
    speed = 0.5;
}
And this is my alarm event:

GML:
alarm[0] = 60;
if (x == startX-maxDistance) {
    if (y == startY-maxDistance) {
        action = choose(1,4);
    } else if (y == startY+maxDistance) {
        action = choose(1,2);
    } else if (y == startY) {
        action = choose(1,2,4);
    }
} else if (x == startX) {
    if (y == startY-maxDistance) {
        action = choose(1,3,4);
    } else if (y == startY+maxDistance) {
        action = choose(1,2,3);
    } else if (y == startY)  {
        action = choose(1,2,3,4);
    }
} else if (x == startX+maxDistance) {
    if (y == startY-maxDistance) {
        action = choose(3,4);
    } else if (y == startY+maxDistance) {
        action = choose(2,3);
    } else if (y == startY)  {
        action = choose(2,3,4);
    }
} else {
    action = 0;
}
Some people suggested me that my conditions may be too strict. So I changed x == and y == in to <=, but the same still happens. The object happily moves away further. Where am I making a mistake? Thank you!
 

Nidoking

Member
Are you rounding the actual x and y values at any point? place_snapped is probably giving false values if you're off by rounding error, and you're explicitly moving in half pixel increments. If the instance doesn't align EXACTLY with the 32,32 boundary, then your action check will never do anything. You might also consider checking the action value even if you're not aligned with the grid, as a sanity check, but that might require rethinking your entire movement system.
 

Lucretius

Member
Are you rounding the actual x and y values at any point? place_snapped is probably giving false values if you're off by rounding error, and you're explicitly moving in half pixel increments. If the instance doesn't align EXACTLY with the 32,32 boundary, then your action check will never do anything. You might also consider checking the action value even if you're not aligned with the grid, as a sanity check, but that might require rethinking your entire movement system.
Thank you. I added rounding to the snapped coordinates, but now the object stops after only moving once. I don't really get why. I am all up to completely rewrite this, but I have no idea where to start. Well, I can do hard checks for every cell, but I want npcs that have a wider range, and it will be a mess of if statements if I do it that way.
 

Nidoking

Member
One thing to consider is, instead of checking to see whether you're snapped, setting an alarm or using a counter variable to determine how many steps to take before reassessing movement. I assume that, since you're talking about NPCs, this is a system where they'd move a cell and then wait for some amount of time before moving again. I think you'd want to have timers in any case.
 
Top