Jump to content


Photo

mp_grid_path() diagonal issues *solved*


  • Please log in to reply
13 replies to this topic

#1 G-Games

G-Games

    GMC Member

  • GMC Member
  • 524 posts
  • Version:GM8

Posted 20 May 2012 - 09:22 AM

Let's get straight to the point. Here's my code:

currentCount = instance_number(wallObj);

if((currentCount != lastCount || forcedToCalcPath))
{
forcedToCalcPath = false;
path_delete(myPath);
myPath = path_add();
mp_grid_clear_all(myGrid);
mp_grid_add_instances(myGrid, wallObj, true);
if(mp_grid_path(myGrid, myPath, x, y, xg, yg, false))
 {
 path_start(myPath, mySpeed, 0, false);
 }
}

lastCount = currentCount;

It's executed in a Step event from every single player. The currentCount and lastCount is meant to keep track of changes in the terrain. If there are changes, the instance recalculates it's path.

Goal: Calculating the path from x, y to a goal at xg, yg.

Issue: Although allowdiag is false, the instance still walks diagonally.

Please help me out, I have no idea what I'm doing wrong!

Edited by G-Games, 21 May 2012 - 05:03 PM.

  • 0

#2 C_Pike

C_Pike

    GMC Member

  • GMC Member
  • 565 posts
  • Version:GM8.1

Posted 20 May 2012 - 11:33 AM

Let's get straight to the point. Here's my code:

currentCount = instance_number(wallObj);

if((currentCount != lastCount || forcedToCalcPath))
{
forcedToCalcPath = false;
path_delete(myPath);
myPath = path_add();
mp_grid_clear_all(myGrid);
mp_grid_add_instances(myGrid, wallObj, true);
if(mp_grid_path(myGrid, myPath, x, y, xg, yg, false))
 {
 path_start(myPath, mySpeed, 0, false);
 }
}

lastCount = currentCount;

It's executed in a Step event from every single player. The currentCount and lastCount is meant to keep track of changes in the terrain. If there are changes, the instance recalculates it's path.

Goal: Calculating the path from x, y to a goal at xg, yg.

Issue: Although allowdiag is false, the instance still walks diagonally.

Please help me out, I have no idea what I'm doing wrong!


if(mp_grid_path(myGrid, myPath, x, y, xg, yg, false))
 {
 path_start(myPath, mySpeed, 0, false);
 }
should be:
mp_grid_path(myGrid, myPath, x, y, xg, yg, false)
path_start(myPath, mySpeed, 0, false);
You do not need an if statement, you just need to set the path.
  • 0

#3 Nocturne

Nocturne

    Nocturne Games

  • Administrators
  • 17017 posts
  • Version:GM:Studio

Posted 20 May 2012 - 11:39 AM

He DOES need the if statement, because it is possible that there is NO path between the points specified in which he will not want to start the path.

As for the problem, I assume it is going in diagonals when it either starts or finishes the path? Or when it is actually running the path?
  • 0

#4 C_Pike

C_Pike

    GMC Member

  • GMC Member
  • 565 posts
  • Version:GM8.1

Posted 20 May 2012 - 11:58 AM

He DOES need the if statement, because it is possible that there is NO path between the points specified in which he will not want to start the path.

As for the problem, I assume it is going in diagonals when it either starts or finishes the path? Or when it is actually running the path?


So, even though its in an if statement, it still re assigns the path? if not, the path re-assignment must be somewhere else not shown, and that re-assignment is where the problem is.
otherwise, sweet! I didn't know you could re-assign paths using an if statement.
  • 0

#5 Nocturne

Nocturne

    Nocturne Games

  • Administrators
  • 17017 posts
  • Version:GM:Studio

Posted 20 May 2012 - 12:16 PM

He isn't reassigning the path with the "if". he is deciding whether to make the object follow the path. It's not the same.

He deletes the old path, recreates the grid, then asks GM to calculate a new path using mp_grid_path. That function will ALWAYS create a path, but it returns true if the new path makes it to the goal x/y coords, and false if it does not (note, a path is still created up to the point it fails). So he is checking to see if the path has failed or not and then moving depending on that result.
  • 0

#6 C_Pike

C_Pike

    GMC Member

  • GMC Member
  • 565 posts
  • Version:GM8.1

Posted 20 May 2012 - 12:36 PM

I meant, (mp_grid_path(myGrid, myPath, x, y, xg, yg, false) HAS to be declared somewhere, right? Its not being declared here, this is just a check. Maybe the declaration elsewhere in the code looks like (mp_grid_path(myGrid, myPath, x, y, xg, yg, true).
Maybe I am just missing the point :rolleyes:
sorry...
  • 0

#7 Nocturne

Nocturne

    Nocturne Games

  • Administrators
  • 17017 posts
  • Version:GM:Studio

Posted 20 May 2012 - 12:56 PM

No, by using it in this way you are declaring it. Think about it like this...

Do you do this?

keyboard_check(vk_left)
if keyboard_check(vk_left) {do something}

No! It is a function that does something (checks a key) and returns a boolean value (pressed=true, not pressed=false). The mp_grid_path function is the same. It is a function that assigns a path and returns a boolean value (path is complete=true, or not=false).
  • 0

#8 C_Pike

C_Pike

    GMC Member

  • GMC Member
  • 565 posts
  • Version:GM8.1

Posted 20 May 2012 - 01:26 PM

No, by using it in this way you are declaring it. Think about it like this...

Do you do this?

keyboard_check(vk_left)
if keyboard_check(vk_left) {do something}

No! It is a function that does something (checks a key) and returns a boolean value (pressed=true, not pressed=false). The mp_grid_path function is the same. It is a function that assigns a path and returns a boolean value (path is complete=true, or not=false).

Last post before I make a total ass out of myself....
I understand its a check, but where is the code that actually calculates and assigns the mp_path, that HAS to be where the issue is!

I swear! I read this over countless times! The OP code is just a couple of checks, and the removal and addition of object to the mp_grid. The assignment portion of the code that sets the path is not here!!
currentCount = instance_number(wallObj);

if((currentCount != lastCount || forcedToCalcPath))
{
forcedToCalcPath = false;
path_delete(myPath);
myPath = path_add();
mp_grid_clear_all(myGrid);
mp_grid_add_instances(myGrid, wallObj, true);
if(mp_grid_path(myGrid, myPath, x, y, xg, yg, false))
 {
 path_start(myPath, mySpeed, 0, false);
 }
}

lastCount = currentCount;
what does the other mp_grid_path(myGrid, myPath, x, y, xg, yg, false) that is not shown here look like? There must be another (in the create event, and/or in the step event) and it must be set to allow diag to be true)
last post, I swear!
  • 0

#9 G-Games

G-Games

    GMC Member

  • GMC Member
  • 524 posts
  • Version:GM8

Posted 20 May 2012 - 01:44 PM

Euhm... No. This is everything. No other coding or anything. mp_grid_path(...) does everything for me.

By the way, maybe you need to know that forcedToCalcPath is true. Continuesly. So it will keep updating every single time. Not sure if that changes anything in the situation, but just so you guys know.
  • 0

#10 Nocturne

Nocturne

    Nocturne Games

  • Administrators
  • 17017 posts
  • Version:GM:Studio

Posted 20 May 2012 - 02:22 PM

Yes it does change things. You should really not be checking and creating paths like that all the time. All that does is generate a new path from the CURRENT x/y position and force the instance to start it.So the instance starts the path, moves a few pixels, and then the next step it does it again, meaning that every step it moves a few pixels along a new path, which (of course) will not be a straightline as every step the path is being calculated form a point that is NOT aligned to the mp_grid.

You should really only do it every few steps or so, or when the previous path has been completed. Also you need to make sure that your instance with the code and that is going to follow the path, starts on the path start and ends on the path end. IE: If the end point of the path is NOT perfectly aligned with the mp_grid, a diagonal will be needed to get to it. This can be easily fixed by shifting the path after it has been defined by mp_grid_path.

@C_Pike: No! You have the wrong idea, I'm afraid. Look, you create an instance and assign it a path. That path is EMPTY and has no points on it yet. So, you then decide that you want the instance in (for example) an alarm event to go get the player. You would then have this (pseudo) code :

var xx, yy;
xx = obj_player.x;
yy = obj_player.y;
if mp_grid_path(grid, path, x, y, xx, yy) {start the path etc...} else alarm = 30;

The thing is that even though the path WAS empty, and even though the if may return false, a path WAS GENERATED and placed in the path that was created in the create event. Basically, everytime you run the mp_grid_path function it generates a new path (it will even wipe any previous paths first) and assigns that path to the one you specify in the code. It doesn't matter if the solution (x,y to xg,yg) has been found or not, a path is still generated and assigned!

Does that clear this up for you?
  • 0

#11 C_Pike

C_Pike

    GMC Member

  • GMC Member
  • 565 posts
  • Version:GM8.1

Posted 20 May 2012 - 02:46 PM

Yes it does change things. You should really not be checking and creating paths like that all the time. All that does is generate a new path from the CURRENT x/y position and force the instance to start it.So the instance starts the path, moves a few pixels, and then the next step it does it again, meaning that every step it moves a few pixels along a new path, which (of course) will not be a straightline as every step the path is being calculated form a point that is NOT aligned to the mp_grid.

You should really only do it every few steps or so, or when the previous path has been completed. Also you need to make sure that your instance with the code and that is going to follow the path, starts on the path start and ends on the path end. IE: If the end point of the path is NOT perfectly aligned with the mp_grid, a diagonal will be needed to get to it. This can be easily fixed by shifting the path after it has been defined by mp_grid_path.

@C_Pike: No! You have the wrong idea, I'm afraid. Look, you create an instance and assign it a path. That path is EMPTY and has no points on it yet. So, you then decide that you want the instance in (for example) an alarm event to go get the player. You would then have this (pseudo) code :

var xx, yy;
xx = obj_player.x;
yy = obj_player.y;
if mp_grid_path(grid, path, x, y, xx, yy) {start the path etc...} else alarm = 30;

The thing is that even though the path WAS empty, and even though the if may return false, a path WAS GENERATED and placed in the path that was created in the create event. Basically, everytime you run the mp_grid_path function it generates a new path (it will even wipe any previous paths first) and assigns that path to the one you specify in the code. It doesn't matter if the solution (x,y to xg,yg) has been found or not, a path is still generated and assigned!

Does that clear this up for you?

Actually, yes! :blush:
Thanks for the patience, as that is very useful information to finally grasp. Its going to cut piles of my code in half...
  • 0

#12 G-Games

G-Games

    GMC Member

  • GMC Member
  • 524 posts
  • Version:GM8

Posted 21 May 2012 - 04:45 PM

@Noctune: Thanks. But if I do that I've got the problem that whenever the terrain updates, there's a chance that the AI won't recognize the terrain change and for instance would just walk through a wall. Any ideas on how to fix that?
  • 0

#13 Nocturne

Nocturne

    Nocturne Games

  • Administrators
  • 17017 posts
  • Version:GM:Studio

Posted 21 May 2012 - 04:58 PM

Well, mp_grids and changing terrain are not a good mix... However, I have done similar stuff to this and what you should do is just recalculate the grid ONLY when the terrain changes> I think one of my examples does this (and doesn't permit diagonals)...

EDIT: yes, look at the "very basic" mp_grid example, as you can add to the terrain dynamically and the path is re-calculated... http://nocturnegames.../aiexamples.htm

Edited by Nocturne, 21 May 2012 - 05:00 PM.

  • 0

#14 G-Games

G-Games

    GMC Member

  • GMC Member
  • 524 posts
  • Version:GM8

Posted 21 May 2012 - 05:03 PM

Ah. I get it. Thanks!

P.S.: Maybe I should've just used mp_potential_step or something instead of this, but mp_grid_* allows me to get paths that are only horizontal and vertical. ;)
  • 0




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users