• 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*mutli-switch locked door, need pointers!

EDIT: FOR CLARIFICATION: IM USING GAME MAKER 1.4 PRO

Hey all! Im making a re-imagining for a beloved PS1/Sega Saturn/3DO classic, "CASPER", and I have most everything figured out and working already (Item pickups, health, teleporting, basic switch and door functions, chests, locked key doors, etc) the only thing I'm trying to figure out, is re-creating the multi-switch puzzles found throughout the game!

EX; TO OPEN DOOR- THREE SWITCHES BEGIN IN THE "OFF" POSITION- YOU MUST FLIP THEM : ON, OFF, ON, -OR- 1,0,1 -OR- A+C (SINCE B IS "OFF") TO OPEN THE DOOR.

i figured out 1 switch per door, but I'm stumped on this. If I can solve this, I've got short work ahead. Mainly just graphics ripping and putting animations back together.

I think using an array might solve this? I'm kind of new to game maker, but have made incredible progress so far. This is one of the last really big hurdles. below is an idea of rough code I figure I might use to get this to work:

DOOR OBJECT CREATE EVENT:
open=false;
global.solution[0] = switcha (//these are the names of the 3 switches that need to be flipped)
global.solution[1] = switchb
global.solution[2] = switchc
global.current_button = 0;

STEP EVENT:
IF global.solution[0]=switcha on/true/1 ///so door checks if all 3 switches are in the correct position
global.solution[1]= off/false/0
etc. {
open=true; ///if all three match global solution; ex; on, off, on- then door opens
}
else {
open= false; ////otherwise- nothing. still locked///
}


SWITCH A/B/C CREATE CODE;
ON=FALSE

SWITCH ABC STEP:

IF- place meeting (x,y,player object) && K IS PRESSED- ON=TRUE(OR FALSE, DEPENDING ON NEEDS)-

(So- pressing 'k' "activates" and "turns off" switches. adding or subtracting from its value/ turning false to true and vice versa- every time it is pressed- this should effects door code- and when the correct solution is in effect- the door opens)


THEN- sound and animation plays for switch (i got this figured out)


PIC INCLUDED FOR REFERENCE! ANY HELP GREATLY APPRECIATED! IF AN ARRAY WOULD WORK- OR ANYTHING! PLEASE LET ME KNOW. I WILL TRY AS HARD AS I CAN TO REFRAIN FROM ASKING FOR FUTHER HELP!!! FOR A PERFECT EXAMPLE OF WHAT IM TRYING TO ACCOMPLISH- SIMPLY LOOK UP PS1/SEGA SATURN/3DO GAMEPLAY OF CASPER (1996)!!!
 

Attachments

Last edited:
I

immortalx

Guest
Having a set of booleans in an array sounds a good idea to me. What you can do for an easy, one-liner comparison, is have a "solution" array for each door, which has the booleans set to the correct values and another one that holds the"current" values. Then using the array_equals function you can compare the two.
 
So the solution array for each door in each doors' ?create code? Would look something like this? (Please correct me if I'm wrong and point me in the right direction!)

DOOR/CREATE:

Global.solution[0]=switcha
Global.solution[1]=switchb
Global.solution[2]=switchc
Global.currentbutton= (how do I set the current values for all three above switches in one line?)

DOOR/STEP:


Global.solution[0] = [true];
Global.solution[1] = [false];
Global.solution[2]= [true];
if array_equals {
Global.solution[0]==Global.solution[1]==global.solution[3]
{
Open=true
}
}

This is a new concept to me, so any help or point in the right direction would be lovely, i try to grasp things as fast and as best as I can!
 
Last edited:

Corey

Member
@retroactivegames

I have this set out for you if it helps. This only checks if switchA and switchB are equal to 1. I assume that the switches have their own code that animates to an on/off position. You'll have to set the switch if it's in the on position to increase global.swtich(A,B, or C) to 1, or if it's turned off to equal 0. If this is incorrect, does the player interact with the switches with the mouse x and y position, or do they walk to the switch to activate it? I also need to know where the player has to be in order to interact with these switches.

Create:
Code:
open = false;
global.switchA = 0;
global.switchB = 0;
global.switchC = 0;
Step:
Code:
if (place_meeting(x,y,obj_player)) //switch on/off state if pressing K
{
    if (keyboard_check_pressed(ord("K")))
    {
        switch.on = true;
    }
    if (on == true)
    {
        if (keyboard_check_pressed(ord("K")))
        {
            switch.on = false;
        }
    }
}
if (global.switchA == 1 && global.switchB == 1)
{
    open = true;
}
else
{
    open = false;
}
 
Last edited:
That looks correct- as the player approaches the switch and 'K' is the action button to press the switch and release the code- I'll try this as soon as I can and thank you very much- I will gladly give you credit! I'll post back as soon as I know if it works! Thanks so much!
 

Corey

Member
@retroactivegames
You are welcome. Keep in mind, that the above code checks if the player is touching the door collision mask, and if not, then it will not execute the code.

If the player is approaching the switches, then the code will have to be changed. There is a different type of logic behind interacting with more than one object of the same type called object oriented programming. This is where you'll have to get unique id's involved. If the switches are already placed in the room, they are given an instance identifier which you can use to define in your code.

Create Event in the Switch:
Code:
on = false;
Step Event in the Switch:
Code:
if (place_meeting(x,y,obj_player)) //switch on/off state if pressing K
{
    if (keyboard_check_pressed(ord("K")))
    {
        on = true;
        global.switch(A, B, or C) = 1; //this is where you'll be specifying the unique id of the switch
    }
    if (on == true)
    {
        if (keyboard_check_pressed(ord("K")))
        {
            on = false;
            global.switch(A, B, or C) = 0; //this is where you'll be specifying the unique id of the switch
        }
    }
}
------------------------------------
Create Event for the Door:
Code:
open = false;
global.switchA = 0;
global.switchB = 0;
global.switchC = 0;
Step Event for the Door:
Code:
if (global.switchA == 1 && global.switchB == 1)
{
    open = true;
}
else
{
    open = false;
}
 
Last edited:
I

immortalx

Guest
I was thinking something like this:
Code:
// pseudocode
correct_code = [true, false, false];
switches = [false, true, false]; // initial switch positions

if (clicked on first switch)
{
    switches[@ 0] = !switches[@ 0];     
}
else if (clicked on second switch)
{
    switches[@ 1] = !switches[@ 1];         
}
else if (clicked on third switch)
{
    // toggle the value
    switches[@ 2] = !switches[@ 2];     
}

// check for correctness
if (array_equals(correct_code, switches))
{
    door_open;   
}
 
thank you both so much for the replies and solutions this means a lot as I've been frustrated with this for about 4-5 days. As soon as I can get on my computer to try some of this stuff out- I'll let you guys know! Credit will be given where it is due- and when the game is done I'll gladly post it on here! It'll be free of course! (Also, if you've never played the original- I recommend it!, If you like puzzle games!)
 
@Corey ive got your method to work so far, except for one thing- which I think is a math problem- I'm trying to fix it. But what seems to happen is-

if you flip the switches in the correct order on the first try- the door opens. If you flip the wrong one first (the middle switch), and flip the other two on- the door wont open (which is as originally intended)- but (heres the problem) even if you switch the middle switch back to the correct "off" position. It seems to add 1 when the button is pressed- but wont take 1 away to get the switch back to zero. The order is (1-0-1) OR ON-OFF-ON- THEY ALL MUST START "DEACTIVATED"- EVEN IF INACTIVE IS THE CORRECT POSITION- I get animations to play- all that jazz. I'm still playing around with it- but here's what I have that works:

DOOR CREATE CODE:
open=false;
global.switchA=0;
global.switchB=0;
global.switchC=0;

DOOR STEP:

if (global.switchA == 1 && global.switchB==0 && global.switchC == 1)
{
audio_play_sound(baropen,0,0) instance_destroy()
}
else
{ ///NOTHING HAPPENS/// SHOULD THE CODE RESET HERE?

}


SWITCH A/B/C CREATE:

on=false;
image_index = 0
image_speed=0


SWITCH A/B/C STEP:

if keyboard_check_pressed (ord("F")) && place_meeting(x,y,player){
show_message ("Its a side to side switch!")
}
if (place_meeting(x,y,player)) && keyboard_check_pressed(ord("K"))
{
{
on = true;
global.switchA(B/C) += 1; audio_play_sound(switchside,0,0) image_index=1;
}
if (on == true)
{
if place_meeting(x,y,player)&& (keyboard_check_pressed(ord("K")))
{
on = false;
global.switchA -= 0;audio_play_sound(switchside,0,0) image_index=0;
}
}
}

 
Last edited:

Corey

Member
I think I may have a solution for you, but I am not 100% sure that it will work as I have not worked with specific instance id's that often (also I'm half asleep). It seems that the initialization of the global variables are not being defined for which switch is either on/off. I did some updates to the code so you will have to do some editing that I have commented in. You'll also need to remove the code from the switch object that deals with pressing the K button since it's being re-initialized in the door object instead. I am sorry that we are bouncing back and forth between codes, but I am learning as well with trial and error.

If this doesn't work then I am out of ideas. It's worth looking into @immortalx 's post above too. I hope others can be of better assistance. Good luck.

Code:
//door step event
//switchobject is the switch object name, you will have to edit this in the place_meeting function
var checkPos = place_meeting(switchobject.x,switchobject.y,player);
if (checkPos != noone)
{
    if (other.on == false)
    {
        if (keyboard_check_pressed(ord("K")))
        {
            other.on = true;
        }
        if (other.on == true)
        {
            if (keyboard_check_pressed(ord("K")))
            {
                other.on = false;
            }
        }
    }
    //check if on
    if (other.on == true && other.id == //instance id of switch A) **Get the instance id of switch A for this to work
    {
        setValA = 1;
    }
    if (other.on == true && other.id == //instance id of switch B) **Get the instance id of switch B for this to work
    {
        setValB = 1;
    }
    if (other.on == true && other.id == //instance id of switch C) **Get the instance id of switch C for this to work
    {
        setValC = 1;
    }
    //check if off
    if (other.on == false && other.id == //instance id of switch A)
    {
        setValA = 0;
    }
    if (other.on == false && other.id == //instance id of switch B)
    {
        setValB = 0;
    }
    if (other.on == false && other.id == //instance id of switch C)
    {
        setValC = 0;
    }
 
}
if (setValA == 1 && setValB == 0 && setValC == 1)
{
    open = true;
}
else
{
    open = false;
}

//door create event
setValA = 0;
setValB = 0;
setValC = 0;
open = false;
 
Thank you! I've been doing this for like 6 hours today trying to solve it. Ill have to try what you recommended ASAP. A tedious solution is to have the switches add +1 to the global.switch variables when the switch is flipped and to have a sub-button for each (switcha has switcha1) when switcha is pressed its adds 1 to the global string- creates the new instance of switcha1, then destroys itself. vice versa for the new switcha1. except that it subtracts 1 as it is supposed to. I dont want to mark this as solved just yet- but i will wthin the next two or three days. Cuz i technically have a solution.
 
Top