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

GML [SOLVED] Avoiding a non-solid object? (place_free)

Dr_Nomz

Member
I have a game where zombies are supposed to move through a barricade when it breaks, but the player can't move through it at all. (In either state)

Problem is, I can't have the broken barricade be solid or the zombie AI won't work right, so what can I do?

My walking code:
Code:
if keyboard_check(ord("W")) { var i=run_speed; while !place_free(x,y-i) i--; y-=i; }
if keyboard_check(ord("S")) { var i=run_speed; while !place_free(x,y+i) i--; y+=i; }
if keyboard_check(ord("A")) { var i=run_speed; while !place_free(x-i,y) i--; x-=i; }
if keyboard_check(ord("D")) { var i=run_speed; while !place_free(x+i,y) i--; x+=i; }
Basically I need it so it won't move if the barricade is about to be ran into, without it being solid. Also could that work with Parent objects?
 

Baldi

Member
Instead of asking for a "free place" you can ask for the barricade itself. For that I would recommend "place_meeting()" but there is also "instance_place()"
And yes, you probably want to check for some sort of "collision parent", so you check for that instead and make all objects that the player should collide with it's children.
 

Dr_Nomz

Member
Minor problem: Barricades and walls are different, and the NPCs behave differently to them, so they can't ALL have the same parent, meaning I can't just use one. Any chance there's a way to just "add on" the object to my code?
 

Dr_Nomz

Member
Well, the barricade can still be walked through, and so can any wall near it for some reason:
Code:
if keyboard_check(ord("W")){
var i=run_speed; while !place_free(x,y-i) && !place_meeting(x,y-i,par_Barricade) i--; y-=i; }
if keyboard_check(ord("S")){
var i=run_speed; while !place_free(x,y+i) && !place_meeting(x,y+i,par_Barricade) i--; y+=i; }
if keyboard_check(ord("A")){
var i=run_speed; while !place_free(x-i,y) && !place_meeting(x-i,y,par_Barricade) i--; x-=i; }
if keyboard_check(ord("D")){
var i=run_speed; while !place_free(x+i,y) && !place_meeting(x+i,y,par_Barricade) i--; x+=i; }
Tried replacing && with || but it froze the game...
 

TheouAegis

Member
You don't want !place_meeting(). Remove the ! if you want the barricade to stop the zombie. Right now you're saying if there IS a barricade, walk at your normal speed.
 

Baldi

Member
Minor problem: Barricades and walls are different, and the NPCs behave differently to them, so they can't ALL have the same parent, meaning I can't just use one. Any chance there's a way to just "add on" the object to my code?
But you are writing it in the movement code of the player, so the NPCs or zombies have nothing to do with that parent, you could say it would be the players collision parent only.
But theres nothing wrong with writing it like you did (apart from the ! that you confused, as TheouAegis pointed out)
Also, I'm not sure what the "i--" are for, but maybe you don't want those there.
 

Dr_Nomz

Member
Yeah but I need the !place_meeting to prevent the player from colliding with the walls.
Code:
if keyboard_check(ord("W")){
var i=run_speed; while !place_free(x,y-i) && place_meeting(x,y-i,par_Barricade) i--; y-=i; }
Now this works without the && place_meeting just fine, but add that, and now I can walk through walls, except for the barricades.

EDIT: More importantly, place_free checks if I'm at a wall, and if not, I move. (i-- and all that.)
I don't get how place_meeting is working here. It's like, if place_meeting, and it's at a barricade, then it moves. But it stops. Isn't that like really backwards?
 

TheouAegis

Member
Actually I think we need ||, not &&, now that I look at it again.

Code:
if keyboard_check(ord("W")){
var i=run_speed;
while !place_free(x,y-i) || place_meeting(x,y-i,par_Barricade)
    i--;
y-=i;
}
So I broke it down into lines here for readability for the time being.

So when you had !place_free(x,y-1) && !place_meeting(x,y-i,par_Barricade), it was saying "if there IS a solid object in the way AND there is not a barricade in the way, reduce speed by 1." Now removing the ! before place_meeting, it was saying, "if there is a solid object in the way AND there is a barricade in the way, reduce speed." However, as I now corrected myself at the start of this post, we should have used ||, not &&. So now the code above is saying, "if there is a solid in the way OR there is a barricade in the way, reduce speed."

Think of place_free() as a negation. There is NOT a solid instance there. So !place_free() is a double-negative, like saying, "I don't not like Backstreet Boys, I just don't want to spend $160 for concert tickets;" or like the word irregardless. On the other hand, place_meeting() is a postive check. There IS a barricade there.
 
Top