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

SOLVED Path finding with state machine?

ww_y

Member
Hey all,

So I have based a lot of my code on Shaun Spalding's RPG Tutorial video series.
Specifically, in this case, I have an enemy state machine that my enemy will have access to outlining an Idle state, an aggro radius, and a chase state.

I also have a tutorial up by heartbeat outlining how to make a basic pathfinding system where the enemy follows your mouse clicks.

My questions are two-fold I suppose:
1. using mp_grid_instances or mp_grid_cell is there anyway to have a specific tile layer be considered when deciding which cells are occupied when the enemy moves.
2. Does anyone see a good way to reconcile these two movement codes. I need to be able to regulate my enemy's state through a state machine, but im having a hard time wrapping my head around doing a pathfinding system that chases the player with a state machine in mind. Maybe I'm just dumb idk.
 

Nidoking

Member
I need to be able to regulate my enemy's state through a state machine, but im having a hard time wrapping my head around doing a pathfinding system that chases the player with a state machine in mind.
What are the states, and what do you want the enemy to do when it's in each of those states?

But don't tell me. Put that in your game.
 

TheouAegis

Member
Unless you are moving layers around, each cell in the tilemap can be mapped to each cell in the mp_grid. Just loop through your tilemap and for every impassable tile, add it to the mp_grid cell.

Code:
for(var ylim = tilemap_get_height(tilemap), yy = 0; yy < ylim; yy++;)
    for(var xlim = tilemap_get_width(tilemap), xx = 0; xx < xlim; xx++;) 
        if tilemap_get(tilemap,xx,yy) == solid.tiles
            mp_grid_add_cell(grid, xx, yy);
(disclaimer, I didn't test that for bugs, it's just pseudocode)

States have nothing to do with using motion-planning. If the enemy changes from an idle state to a chase state, plot out the path to the player and then start the path. When the enemy needs to stop the chase state, set the path_speed to 0 or stop the path. If you can't figure out how to use states with motion-planning functions, then you haven't figured out how to use states at all.
 

ww_y

Member
What are the states, and what do you want the enemy to do when it's in each of those states?

But don't tell me. Put that in your game.
Fair enough, I think as a newbie I just saw the task of learning how to integrate pathfinding in with the tutorials I already had done and got scared o_O

Unless you are moving layers around, each cell in the tilemap can be mapped to each cell in the mp_grid. Just loop through your tilemap and for every impassable tile, add it to the mp_grid cell.

Code:
for(var ylim = tilemap_get_height(tilemap), yy = 0; yy < ylim; yy++;)
    for(var xlim = tilemap_get_width(tilemap), xx = 0; xx < xlim; xx++;)
        if tilemap_get(tilemap,xx,yy) == solid.tiles
            mp_grid_add_cell(grid, xx, yy);
(disclaimer, I didn't test that for bugs, it's just pseudocode)

States have nothing to do with using motion-planning. If the enemy changes from an idle state to a chase state, plot out the path to the player and then start the path. When the enemy needs to stop the chase state, set the path_speed to 0 or stop the path. If you can't figure out how to use states with motion-planning functions, then you haven't figured out how to use states at all.
Fair point on the state machine bit. I see now that obviously there's no problem integrating a pathfinding system with a state machine, however, I am having a hard time wrapping my head around this for loop. I've scoured what I could from other forum posts on here and now understand the outline of code you shared. I've applied it, and I do believe I've written it well enough to work, however it doesn't. Instead of the enemy going towards the player, the enemy does nothing. This is a new problem, as before this line of code the enemy just went straight to the player in an almost straight line (ignoring the collision tiles that I wished would keep it from reaching the player). I have attached screenshots of the code I've written.

If anyone has any pointers as to whats going on I'd very much appreciate it
 

Attachments

Slyddar

Member
For the enemy, you are starting the path every step. To ensure the pathing is working, does it at least move towards the player if you place it in the create event instead?
Also look into mp_grid_draw to show if the grid is actually set. This blog is on dynamic walls, but may be of help for showing the path and grid at least - https://www.yoyogames.com/en/blog/dynamic-mp-grids
 

ww_y

Member
For the enemy, you are starting the path every step. To ensure the pathing is working, does it at least move towards the player if you place it in the create event instead?
Also look into mp_grid_draw to show if the grid is actually set. This blog is on dynamic walls, but may be of help for showing the path and grid at least - https://www.yoyogames.com/en/blog/dynamic-mp-grids
I'll look into the mp_grid_draw

Yes, I put the pathing in the create event and it did move to the player. It seems like the moment where everything doesnt work is when I put the for loops into the oGrid object, then the enemy sits there and does not move.


GML:
for (var i = 0; i < hCells; i++)
    {
        for (var j = 0; j < vCells; j++)
        {
            if (tilemap_get_at_pixel(collisionLayerID, i ,j))
            {
                mp_grid_add_cell(global.grid, i, j);
            }
        }
    }
 

Slyddar

Member
As mentioned above, you are dealing with tilemap grid locations, not pixel positions, with the loops. You are iterating through the horizontal cells and the vertical cells of the grid. Therefore you just need tilemap_get(), not tilemap_get_at_pixel()
 

ww_y

Member
Because you are using tilemap_get_at_pixel().
As mentioned above, you are dealing with tilemap grid locations, not pixel positions, with the loops. You are iterating through the horizontal cells and the vertical cells of the grid. Therefore you just need tilemap_get(), not tilemap_get_at_pixel()
This was indeed it my friends.


I was also having a weird issue where my enemy was doing odd movements to get to my player object. After an hour of banging my head on a table I realized it was because I had the cell_width and cell_height set to the wrong values. My grid is 16x16 and I had it set to a different number.

Thank you all for your help!
 
Top