Hello-
First may I say that I really appreciate the guidance I've gotten so far in making my first game- this has been a very helpful resource. You have all been great about checking my code, holding my hand through my confusion, etc.
Now I have two bigger questions (or at least they seem that way to me the layman.) I'm designing a puzzle that requires me to learn two new programming mechanics.
1. The puzzle involves a keypad with a 3x3 button grid. Pushing one button causes other buttons to light up and some buttons to go off if already lit. The goal is to find the sequence of buttons that will cause all the buttons to become lit. To accomplish this I made a "lit" version of the buttons that serves as an object within the game. All 9 "lit button" objects start out as invisible and are made visible when clicked on. So the code, in essence, says "When button five is pushed, cause objects 2, 4, 6, and 8 to become visible."
So my question is this: how do I write code which causes the game to become aware when all of the buttons are lit so as to trigger the result of the puzzle?
2. The reward for the puzzle is to open a door that is on a different screen. The open door is an object that becomes visible. How do I trigger a result on a different room from the one I'm on?
Thank you so much for you help!
1. Whether the button is lit in this case is equivalent to "this object is visible." So you would write a check that is something like
if( oButton1.Visible
&& oButton2.Visible
&& oButton3.Visible
&& oButton4.Visible
&& oButton5.Visible
&& oButton6.Visible
&& oButton7.Visible
&& oButton8.Visible
&& oButton9.Visible)
{
// All buttons lit, so open door
doorIsOpen = true;
}
(I've split the test across multiple lines to make it easier to read—with this formatting you can see at a glance that it tests 9 buttons; you can do that but you don't have to.)
A good way to run this code would be to make a function that you call after each button is pressed.
2. In that case, you would make a global variable (for example using the Global Variables pane), for example bool doorIsOpen that is set to false at game start. As you can see, the code above sets it to true. Then in the "enter room" event of the other room, you check that variable and set the open door object to visible or not depending on whether it's true.
(A variable used in this way is often called a "flag.")
Regarding the puzzle you can probably shorten your code considerably if you use an array of bools, a single rectangular hotspot covering the entire keypad and nine non-clickable objects.
bool lit[9];
function hKeypad_Interact() {
int xo = 123, yo = 45; // coordinates of top left corner of top left button
int w = 20, h = 15; // width and height of a button
int xg = 5, yg = 5; // gap between buttons
int x = (mouse.x - xo);
int y = (mouse.y - yo);
if (x % (w + xg) > w || y % (h + yg) > h) return; // clicked in between buttons
int bi = (y / (h + yg)) * 3 + (x / (x + xg)); // should be 0-8
// flip clicked and neighboring bools
for (int i = 0; i < 9; i++) {
if (i == bi || i + 3 == bi || i - 3 == bi || i % 3 == 0 && i + 1 == bi || i % 3 == 2 && i - 1 == bi) lit[i] == !lit[i];
}
// update button objects visibility
for (int i = 0; i < 9; i++) object[i + 2].Visible == lit[i]; // first button object has ID 2, etc.
}
Awesome thanks- I'll start working with that! :)
Hope it's OK to respond in the thread rather than by PM,
@Jordanowen42:
Quote from: Jordanowen42 on Tue 28/05/2024 08:17:23You had written me this code and I was wondering if I'm supposed to put it in the global script. If so, where? Do I just drop it in at the bottom of the script?
You would set the flag when the player has made a change to the buttons. Since they are room objects, it probably goes in the room script. I don't know if you've already got the grid working so that you can click the buttons on and off? If not, I think one problem with your approach is that when you set the objects to not be visible, they will also not be clickable (I believe), so you won't be able to switch back and forth.
That's part of what Khris's code deals with. But if you find it hard to understand, or if the buttons are not arranged in a regular grid, you could instead do it by having two versions of the button graphic (lit and unlit) and switching back and forth instead of setting it visible and invisible:
// Room with buttons room script
// I don't like to use unexplained "magic numbers" in the code, so I give them names using #define
// (the values are just examples; you have to figure out what they should be in your case)
#define BUTTON_LIT 39 // Sprite number of the lit button sprite
#define BUTTON_UNLIT 40 // Sprite number of the unlit button sprite
#define FIRST_BUTTON 6 // Object number of the first button (assumes all the button objects have continuous numbering)
void flipButton(Object* theButton)
{
// Flip the state of the button between lit and unlit
if(theButton.Graphic == BUTTON_LIT) theButton.Graphic = BUTTON_UNLIT;
else theButton.Graphic = BUTTON_LIT;
// Door is open if all buttons are lit (if any button is unlit, door is not open)
doorIsOpen = true;
for(int i=FIRST_BUTTON; i<=FIRST_BUTTON+9; i++) // We have 9 buttons to check
if(object[i].Graphic == BUTTON_UNLIT) doorIsOpen = false;
}
// Remember to link this event handler using the event pane in the room editor!
oButton1_Interact()
{
flipButton(oButton1);
}
oButton2_Interact()
{
flipButton(oButton2);
}
// etc.
I changed the test for whether all buttons are lit (at the end of flipButton) to use a loop, because it's shorter. But you could also do:
// Door is open if all buttons are lit
doorIsOpen = ( oButton1.Graphic == BUTTON_LIT
&& oButton2.Graphic == BUTTON_LIT
&& oButton3.Graphic == BUTTON_LIT
&& oButton4.Graphic == BUTTON_LIT
&& oButton5.Graphic == BUTTON_LIT
&& oButton6.Graphic == BUTTON_LIT
&& oButton7.Graphic == BUTTON_LIT
&& oButton8.Graphic == BUTTON_LIT
&& oButton9.Graphic == BUTTON_LIT);
(The difference from what I suggested in my first post is that this will set the doorIsOpen value back to false if you turn off a light after having turned them all on.)
Quote from: Jordanowen42 on Tue 28/05/2024 08:17:23Also- I want to change the outcome to making some objects in the other room visible. Do I just use object.[?]visible = true? And if so, do I replace the object number with its name?
As for how to use the value, as already explained:
Quote from: Snarky on Tue 15/08/2023 06:22:16you would make a global variable (for example using the Global Variables pane), for example bool doorIsOpen that is set to false at game start. As you can see, the code above sets it to true. Then in the "enter room" event of the other room, you check that variable and set the open door object to visible or not depending on whether it's true.
So in the "enter room before fadein" event in the other room script, you would just write:
// Room with door room script
function room_Load()
{
oDoorOpen.Visible = doorIsOpen;
}
(This assumes that the open version of the door is an object called oDoorOpen.)
Okay cool- I really appreciate the help. I'll start trying this code out and see what happens! :)
Hey guys-
So I've been trying to apply this information and what I'm realizing is that I'm getting a little in over my head. When I say that I'm new at this, I mean I'm literally learning every step as I go. I'm literally asking myself questions like "what does the green text mean? How does the computer know what that means?" Hell- I just tonight learned "bool" is short for "boolean."
So rather than send you guys one request for code after another, I'm wondering if you can refer me to a good resource on understanding all the coding involved in this but worded specifically so that I understand it in light of what's happening in AGS. I'm finding all these tutorials on line but none of them go as deep as the questions I'm asking here.
Afaik there's no "Learn how to program - with AGScript" resource out there. Understanding the basics about how variables and arrays work, how to use custom functions, etc. can be learned with any programming language though.
A reasonably similar one is JS, so maybe take a look at this:
https://developer.mozilla.org/en-US/docs/Learn/Getting_started_with_the_web/JavaScript_basics