Legacy GM Hiding and revealing "Player" object when pressing "C" key

A

Agletsio

Guest
HI there,

I want my player to hide in closet (called "obj_door") when I press "C". So my reasoning at the moment is to check to see if Player and closet objects are touching, then change the closet sprite and "hide" the Player object until you release "C" where it will go back to functioning normally.

Now I have managed to make the Door sprite change back and forth and making the Player object stop (speed = 0) when pressing and releasing the "C" key. What I'm trying to achieve now is hiding the Player sprite/object when "C" is pressed and make it return when "C" is released.

How would I go about doing that? I've tried playing around with "instance_deactivate" but is doesn't seem to be the right route. Is there a simple "object hide function" or something that will work? Also let me know if I'm approaching this the wrong way.

This is my current code setup in Player object's step event:

//Player Hide

var touch = place_meeting (Player.x, Player.y, obj_door)

if touch and keyboard_check(ord("C"))
{
speed = 0;
//This is where I tried placing the instance_deactivate function
}

Any help would seriously be appreciated!
 
B

bojack29

Guest
Code:
if (place_meeting(x, y, obj_door)){
     visible = 1 - keyboard_check(ord('C'));
}
 
A

Agletsio

Guest
Code:
if (place_meeting(x, y, obj_door)){
     visible = 1 - keyboard_check(ord('C'));
}

Hi bojack29,

Thanks! This fix seems to work really well! Wasn't aware of the "visible" function.

Pretty new to Game Maker and coding in general so trying to understand the reasoning behind this is. If you wouldn't mind explaining a bit that would be great. Then I can better implement and tweak it in the future.

When you write "- keyboard_check(ord('C'));" what exactly is is saying in the code?

The way I read it is that "visibility is true except when you press C". Am I understanding that right?
 
B

bojack29

Guest
The code first checks to see of both the bounding box and the target objects bounding box collides. (place_meeting)

Then it ticks the visible flag (which disables / enables all drawing of an instance - but is still technically there). Keyboard_check will return either a 0 or a 1 when pressed or not pressed for that frame.

True and false work the same way. True is 1 and false is 0. So when you say visible = 1 minus key being held? (1) = 0. Or false. Visible = false. The opposite is true if keyboard check is (0) or not being pressed.

You can the status of a keyboard check like this
Code:
beingPressed = keyboard_check(ord('C'));
This will return either a 1 or a 0. Or true or false.
 

TheouAegis

Member
Make sure you also set it so the player can only move and interact with enemies if visible, otherwise while the player is in the closet he could move around the room and still interact.
 
A

Agletsio

Guest
The code first checks to see of both the bounding box and the target objects bounding box collides. (place_meeting)

Then it ticks the visible flag (which disables / enables all drawing of an instance - but is still technically there). Keyboard_check will return either a 0 or a 1 when pressed or not pressed for that frame.

True and false work the same way. True is 1 and false is 0. So when you say visible = 1 minus key being held? (1) = 0. Or false. Visible = false. The opposite is true if keyboard check is (0) or not being pressed.

You can the status of a keyboard check like this
Code:
beingPressed = keyboard_check(ord('C'));
This will return either a 1 or a 0. Or true or false.

Ahh awesome, many thanks for the explanation!! This knowledge will serve me well in the future.

Just also had to set the speed to 0 when key is being pressed. Otherwise, if the key was released but the objects weren't touching, the sprite didn't set to back visibility = true.
 
A

Agletsio

Guest
Make sure you also set it so the player can only move and interact with enemies if visible, otherwise while the player is in the closet he could move around the room and still interact.
I'm actually busy doing that now :)

Also having problem, so maybe you can help me (also let me know if you think I should start this as new thread. Pretty new to the Game Maker community but seems like best practice).

At the moment, when I hold both the arrow key ("Left" or "Right") and action key ("C") and then release the action key again (but still keeping the arrow key down), my object start moving again but it doesn't set back to "visibility = true".

Now, to play, you have to make sure to release the arrow key before releasing the action key, otherwise your object start running around invisible (if the collision between the two objects are false, of course). Ideally, I would want the visibility of the Player to return when releasing action key, even if movement key is still pressed.

Not sure how to approach this problem. Might my "vk_nokey" function in movement script be causing this problem?

Any info would be a great help!
 

TheouAegis

Member
Post your Object Info. I had issues before with GMS handling multiple keys, but your code may be at fault too.

FYI, the arrow keys tend to cause ghosting on most keyboards. Maybe your keyboard ghosts with arrow keys and C, but it worked just fine for me. I get ghosting with spacebar, though. However, I had to press 2 arrow keys at the same time to cause that to happen.
 
Last edited:
A

Agletsio

Guest
Post your Object Info. I had issues before with GMS handling multiple keys, but your code may be at fault too.
Ok, hope this is what you meant.

This is my movement script:

image_speed = speed/8

if keyboard_check(vk_right) {
direction = 0;
speed = 5;
sprite_index = Walk_Right;
}

if keyboard_check(vk_left) {
direction = 180;
speed = 5;
sprite_index = Walk_Left;
}

if keyboard_check(vk_nokey) {
speed = 0;
sprite_index = Idle_Right;
}



And this is code in Player step event ("noplay_script" is movement script) :

//General Controls

script_execute(noplay_script)

//Player Hide

if (place_meeting(x, y, obj_door)) and keyboard_check(ord('C')) {
visible = false;
speed = 0;
}

if (place_meeting(x, y, obj_door)) and keyboard_check(vk_nokey) {
visible = true;
}
 

TheouAegis

Member
Code:
if keyboard_check(vk_right) {
direction = 0;
speed = 5;
sprite_index = Walk_Right;
}

if keyboard_check(vk_left) {
direction = 180;
speed = 5;
sprite_index = Walk_Left;
}

if keyboard_check(vk_nokey) {
speed = 0;
sprite_index = Idle_Right;
}
First off, that code has 2 major flaws.
  1. If the player presses right and left at the same time, the player will always move left. Minor issue, but when you're using the keyboard for moving, it can be crippling for some players.
  2. The player will continue to move as long as any key is pressed. So if the player isn't pressing left or right but is pressing A or B or C or D or 1 or 2 or CTRL or ALT or whatever, then the player will keep moving.
Code:
if (place_meeting(x, y, obj_door)) and keyboard_check(ord('C')) {
visible = false;
speed = 0;
}

if (place_meeting(x, y, obj_door)) and keyboard_check(vk_nokey) {
visible = true;
}
Same issues here. If the player isn't pressing C but is pressing any other key such as A, B, D, 1, 2, 3, CTRL, ALT, left, right, up, or whatever, then the player will never be visible. Your code here should just simply be:
Code:
if (place_meeting(x, y, obj_door)) and keyboard_check(ord('C')) {
visible = false;
speed = 0;
}
else visible = true;
 
A

Agletsio

Guest
Code:
if keyboard_check(vk_right) {
direction = 0;
speed = 5;
sprite_index = Walk_Right;
}

if keyboard_check(vk_left) {
direction = 180;
speed = 5;
sprite_index = Walk_Left;
}

if keyboard_check(vk_nokey) {
speed = 0;
sprite_index = Idle_Right;
}
First off, that code has 2 major flaws.
  1. If the player presses right and left at the same time, the player will always move left. Minor issue, but when you're using the keyboard for moving, it can be crippling for some players.
  2. The player will continue to move as long as any key is pressed. So if the player isn't pressing left or right but is pressing A or B or C or D or 1 or 2 or CTRL or ALT or whatever, then the player will keep moving.
Code:
if (place_meeting(x, y, obj_door)) and keyboard_check(ord('C')) {
visible = false;
speed = 0;
}

if (place_meeting(x, y, obj_door)) and keyboard_check(vk_nokey) {
visible = true;
}
Same issues here. If the player isn't pressing C but is pressing any other key such as A, B, D, 1, 2, 3, CTRL, ALT, left, right, up, or whatever, then the player will never be visible. Your code here should just simply be:
Code:
if (place_meeting(x, y, obj_door)) and keyboard_check(ord('C')) {
visible = false;
speed = 0;
}
else visible = true;

Ah yes I see, I can pick this problem up in quite a few places because I keep using the vk_nokey function.

I tried this code now but it seems to just imitate the vk_nokey fucntion (as I understand it, "!" means "not" right? Also, could a "keyboard_check_direct()" approach work better?

if keyboard_check(vk_right) {
direction = 0;
speed = 5;
sprite_index = Walk_Right;
}

if keyboard_check(vk_left) {
direction = 180;
speed = 5;
sprite_index = Walk_Left;
}

else

if keyboard_check (!vk_left) or (!vk_right) or (!ord("C")) {
speed = 0;
sprite_index = Idle_Right;
}
 

TheouAegis

Member
if keyboard_check(vk_right) {
direction = 0;
speed = 5;
sprite_index = Walk_Right;
}
else
if keyboard_check(vk_left) {
direction = 180;
speed = 5;
sprite_index = Walk_Left;
}
else
{
speed = 0;
sprite_index = Idle_Right;
}

You don't need to worry about any other keys for the movement.


Oh, also your code's error was you put keyboard_check(!vk_left). What you need is !keyboard_check(vk_left).
 
Top