Making a platformer with a basic hide/layer mechanic

Gleb

Member
Making a game where the player can hide behind things. There's two layers, Active1 and Active2.

The objects you can hide behind are on Active1, as well as the player. When the player hides, they'll be moved to Active2, behind the hideable objects.


I originally intended for this to work as such, the player presses E when colliding with a hideable object, then moves to Active2. When the player walks out from behind the object (stops colliding) they are automatically moved to Active1 again.

I couldn't make this work because i was using !place_meeting in the step event, which meant i couldn't re-use the hideable object instance. (The player would never be hidden unless colliding with every instance which is impossible)

If somebody here knows how i could achieve the above that would be amazing.



Perhaps my understanding of depth is off. The below code is flawed. Now hiding works like a toggle. The player had to press E again to come out of hiding. The only issue is, with the current code once they come out of hiding they can't go back in.
I'm not sure why. The cooldown function makes sure the input is only read once.

In the key up (E) event of the object the player hides behind:
GML:
if cooldown <= 0 && place_meeting(x,y,P_Player){
    cooldown = 10;

    if P_Player.layer == layer_get_id("Active1") {

        P_Player.layer = layer_get_id("Active2") ;
        P_Player.hidden = true;
       P_Player.depth = self.depth + 1;
       
    }else if P_Player.layer == layer_get_id("Active2") {
       
        P_Player.layer = layer_get_id("Active1") ;
        P_Player.hidden = false;
        P_Player.depth = self.depth - 1;
    }
   
}
Any thoughts help, thanks in advance.
 

Nidoking

Member
Why are you doing this processing in the hideable object and not in the player?

Also, it's a toggle because the code that moves the player back to Active1 is in the key E event. You probably want something like if the player is not meeting a hideable object in the step event.
 

Gleb

Member
You probably want something like if the player is not meeting a hideable object in the step event
The issue with putting it in the step event with Place_meeting is that it will not function if i place more than 1 instance of the hideable object. I want one that can be re-used across the map.

I put this code in the hideable object because I thought it was neater. Not sure how putting it in the player would benefit me, if you're onto something please lmk
 

Gleb

Member
Here's something to help articulate how it should function: (hopefully)

hiding.png
(Movement is handled via the arrow keys)

A: The player approaches the hideable object.

B:The player can walk over the hideable object without anything happening. The player remains front of it, as well as all other hideable objects.

C: Upon pressing E the player hides, illustrated by the player's sprite appearing behind the hideable object.

D:The player moves to the right, simultaneously moving out from behind the hideable object. This places the player back in front of all hideable objects again.

E:The player walks back over the hideable object, illustrating that they are in front of the hideable objects/not hiding

Any contributions help, thanks in advance
 

Nidoking

Member
The issue with putting it in the step event with Place_meeting is that it will not function if i place more than 1 instance of the hideable object
You'll have to attempt to explain why it wouldn't work, because it works. It can be reused wherever. Perhaps you need to learn the difference between instances and objects?
 

Gleb

Member
You'll have to attempt to explain why it wouldn't work, because it works. It can be reused wherever. Perhaps you need to learn the difference between instances and objects?
Let's just say:

if place_meeting(x,y,P_Player){

hidden = true;

}else{

hidden = false;

}

Due to the presence of the else statement, the player would have to be colliding with every instance of the hideable object simultaneously in order for hidden to be true.

Can you attempt to assist my search for alternatives? Perhaps this is why it would be better to have this code handled in the player object as there's only one instance. :^)
 

Kyon

Member
Ahh yeah,
for stuff like this I play around with step begin and step end events.

For example, what you can do is that your overall controller, or maybe player has in his step begin event:
GML:
global.hidden = false;
So that always is set to false when a frame starts basicly.
But in his step end event it says:
GML:
if (global.hidden = true){
   //code for when he is hiding behind something, probably changing his depth or something idk
}
And then in your Hideable object step event
you have that code like, when place meeting, global.hidden = true.
Don't set it to false, that already happens automaticly at the start of each frame in the player/controller object.


So now what happens is

PLAYER STEP BEGIN (hidden = false) >>> HIDEOBJECT STEP (if colliding, hidden is true) >>> PLAYER STEP END (if hidden = true, actually hide)


Does that make sense? :)
 

Nidoking

Member
if place_meeting(x,y,P_Player){
This is clearly not in the player object, where it shoul- oh, you said more stuff.

Perhaps this is why it would be better to have this code handled in the player object as there's only one instance.
Not perhaps. Definitely. place_meeting(x,y,P_Hideable) is a single check that will match all instances of hideable objects (assuming you've created a parent for them, which you also should) and I really can't see why you keep trying to take the long way around.

In the player E key press event, check if there's a hideable object there and if so, hide the player. In the End Step event or so, check if the player is hidden and if so, if there is not a hideable object there, unhide the player. The Hideable object doesn't need to DO anything. It just needs to BE there.
 

Gleb

Member
Here's how I handled it:
I ended up doing away with the instance layers entierly.


Begin step:
GML:
hidden = false;

E Released:

GML:
if place_meeting(x,y,E_hide){

depth = 110;

}

END STEP:
GML:
if place_meeting(x,y,E_hide) && (depth == 110){

hidden = true;

}

if !place_meeting(x,y,E_hide){

depth = 90;

}
 
Top