GUI-help: Book with multiple pages

Started by MistyShires, Sat 20/03/2021 20:50:34

Previous topic - Next topic

MistyShires

I feel like a complete idiot but I have to ask, otherwise I might end up tearing my own hair out...

I am in the progress of programming a book with multiple pages where there is a retrievable inventory-item at the end. I think that I understand how the item itself is going to be programmed but the problem is that I am trying to figure out the best way to program the changing of the pages. So far, I have been using simple buttons where the 'Next Page' button changes the background-graphic of the GUI to show the next two pages (who are on the same sprite) and a 'Last Page' button that changes the background graphic to what it used to be.

What I am currently trying to figure out is a way to make the 'Next Page'-button change the Graphic to not just one specific sprite (because there are a total of four sprites) but to change it to the next one in the order until its hits the last one in the series where the button stops being clickable. How would you do that? I am still new to this so I feel kind of lost.

While I am on a similar note, I also wonder if something similar could be done for a classic combination-lock. Like how the puzzle is solved if specific spites are aligned in the correct order. I have a feeling that this is going to be really useful going forward so any advice with this one is really appreciated.

Matti

If the sprite slots are consecutive, just do

Code: ags

if (GUI.BackgroundGraphic < x) GUI.BackgroundGraphic ++;  // x being the last book sprite

MistyShires

Maybe I don't understand coding at all, but when I try to use the suggested method with this variable (int GUI.BackGroundGraphic = 49), I just keep getting the error that the variable has already been defined. Even when I move it outside of the function itself. How can I  solve this error?

And on a somewhat related note, does anyone know where I can find some kind of error-glossary so that I can understand what the error-text is trying to tell me? As I said, completely new to coding.

arj0n

#3
Let's say that, for example,:

  • The GUI that represents the book is named Gbook
  • And the book has 6 pages.



Now do the following, if the sprite slots are consecutive:


  • Open Gbook
  • Double click the next-button, you'll end up in the global script,
  • place the code Matti provided:
Code: ags
if (Gbook.BackgroundGraphic < 6) Gbook.BackgroundGraphic ++;

  • Save and run to check if it works



Or do the following, if the sprite slots are NOT consecutive

In this example, the sprite slots are:
page 1: slot 1
page 2: slot 2
page 3: slot 11
page 4: slot 12
page 5: slot 20
page 6: slot 21


  • Open Gbook
  • Double click the next-button, you'll end up in the global script,
  • place this code:
Code: ags
if (Gbook.BackgroundGraphic == 1) Gbook.BackgroundGraphic = 2; //show page2 
else if (Gbook.BackgroundGraphic == 2) Gbook.BackgroundGraphic = 11; //show page3
else if (Gbook.BackgroundGraphic == 11) Gbook.BackgroundGraphic = 12; //show page4
else if (Gbook.BackgroundGraphic == 12) Gbook.BackgroundGraphic = 20; //show page5
else if (Gbook.BackgroundGraphic == 20) Gbook.BackgroundGraphic = 21; //show page6

    • Save and run to check if it works



or, some extra bits like changing the button label when opening the last page:

(let's assume the book's next-button is named btn_next)

  • use something like this code:
[/list]
Code: ags
if (Gbook.BackgroundGraphic == 1) Gbook.BackgroundGraphic = 2; //show page2 
else if (Gbook.BackgroundGraphic == 2) Gbook.BackgroundGraphic = 11; //show page3
else if (Gbook.BackgroundGraphic == 11) Gbook.BackgroundGraphic = 12; //show page4
else if (Gbook.BackgroundGraphic == 12) Gbook.BackgroundGraphic = 20; //show page5
else if (Gbook.BackgroundGraphic == 20) 
{
  Gbook.BackgroundGraphic = 21; //show page6
  btn_Next.text = "close"; //change button label from 'next' to 'close'
}
else if (Gbook.BackgroundGraphic == 21) 
{
  Gbook.Visible = false; //close the book GUI
  BackgroundGraphic = 1; //set start page to be page 1 again for when you re-open the book
  btn_Next.text = "next"; //change book's button label back from 'close' to 'next', for when you re-open the book
}

    Khris

    When you see
    int GUI.BackgroundGraphic

    in the manual, you're not supposed to use that as-is. The  int  tells you the type of the property (as in, you can set it to an integer), and the GUI part tells you that it's a property of the GUI class, meaning you need to put the actual instance's name of the GUI there, not literally "GUI".

    Here's another example:
    static FontType Game.NormalFont

    This tells you that the property contains a FontType, and that you should set it to a FontType to change it. However here, you're indeed supposed to literally write
    Code: ags
      Game.NormalFont = eFontCursive;

    That's because of the  static  keyword at the start, which means that  Game  is the one actual Game, and you can use that in fact as-is.

    Getting the whole class vs. instance / static vs. dynamic thing can be tough for beginners (I know it was for me), so as a rule of thumb, just think about whether you're dealing with something that exists only once (Game, System, Viewport) or something that exists a bunch of times, at least in theory (Character, InventoryItem, Object). Of course there's an exception to the rule: Room. There's only one room loaded at a time though, so despite there usually being multiple rooms in a game, room commands often start with literally Room.

    Finally, note that a single  =  is used for assignments, while a double  ==  is used for comparisons.

    MistyShires

    Thank you all so much!

    I finally realized where my error was. I kept taking the instructions way too literally (something that happens more often than it probably should) and used GUI.BackgroundGraphic all the time instead of defining exactly which GUI-background I was actually changing. I sure feel like a dingus...

    Now I am almost done but I have run into a bit of a problem with the last button, which is the one that is going to add the inventory item to the player’s inventory. Considering that I only want the button to appear on the last page on the journal, I added a code that looks like this:

    Code: ags
    
    if (gJournal.BackgroundGraphic = 52) bScissors.Visible = true;
    
    else bScissors.Visible = false;
    


    The problem is that I keep getting an error that tells me to ‘Parse error in expr near gJournal’. This doesn’t really tell me anything about what I need to fix so I would really appreciate if anyone could help me understand what I am doing wrong.

    I also wonder where I should put the string that gives the character the item: before or after this if/else-statement?

    eri0o

    You need to use two equal signs for comparison , a single equal sign means assignment, which are not allowed inside an if in AGS Script.

    MistyShires

    I tried using two equals-signs and it didn't change anything, I still got the same error. Besides, using one equal-sign has worked fine every other time I've used if/else-statements...

    Matti

    #8
    Make sure you only change the equal sign in the comparison, not the other ones:

    Code: ags
    if (gJournal.BackgroundGraphic == 52) bScissors.Visible = true;
     
    else bScissors.Visible = false;


    Edit:
    QuoteI also wonder where I should put the string that gives the character the item: before or after this if/else-statement?

    Do you want the player to get the item as soon as they open the last page of the book or is the player supposed to click on the button?

    eri0o

    Quote from: MistyShires on Tue 30/03/2021 21:04:38
    I tried using two equals-signs and it didn't change anything, I still got the same error. Besides, using one equal-sign has worked fine every other time I've used if/else-statements...

    I am pretty sure using a single equal sign in an if will make the compiler spit an error. Assign and evaluate is not allowed in AGS Script - for good reason, the only use case it has (pointer assignment and null check) while useful, isn't worth for the confusing non-error that are typing error it won't catch if it was allowed.

    Also, prefer using code blocks instead of naked ifs since they are bound to give wrong behavior once you need to add an additional line and forget them. Using code blocks will make the code easier to read and you also can use them online if it's just a single line in the if content.

    MistyShires

    Okay, I finally got it. I will admit that it is a bit of a headache for me to figure out how the code is meant to be structured sometimes (even with tutorials). I will try to keep that in mind for the future.

    Now my only problem is that the button never actually shows up when I reach the intended page. Its visibility is set to false in the beginning of the game since it isn't meant to show up until the GUI-background is changed to the correct one but it never appears when I run the game, even though AGS doesn't detect anything wrong with my code. Could it be the order of the code strings?

    And the player is supposed to get the item once they click the button, kind of like those browser point-and-click games (especially room escape-games) that used to be popular until Flash was discontinued.

    Khris

    Can you post relevant code / functions? The part that turns the button visible is supposed to go immediately after the lines that change the background image.

    MistyShires

    No need, I got it to work as intended. I couldn't be happier  :grin:

    The last thing I might need some quick advice, then I am going to leave you guys be for hopefully a little while. Seriously, thank you for all your help!

    Now, my NextPage-button works like it should except for the fact that it doesn't disappear automatically once the book reaches the last page (presumably because it lies under the 'On Click-function'). Instead, it disappears when clicked one last time, which wouldn't be so bad if it wasn't for the fact that it screws up the scissors-button by making it reappear for some reason.

    Is there a better place to put that line of code so that it disappears automatically? Currently the code for that button looks like this (and yes, putting the code for the visibility off the scissor-button in that specific function solved the issue I had earlier):

    Code: ags
    
    function bNextPage_OnClick(GUIControl *control, MouseButton button)//Changes page forward//
    {
      
    if (gJournal.BackgroundGraphic < 52) gJournal.BackgroundGraphic ++;
    else bNextPage.Visible = false;
    
    if (gJournal.BackgroundGraphic == 52)bScissors.Visible = true;
    else bScissors.Visible = false; 
    }
    

    Matti

    The problem is that in your code the button won't be disabled if the background changes from sprite 51 to 52. To elaborate: In line 4, if the sprite number is 51 the sprite number will increase by one, but line 5 won't be called, because the sprite number was < 52 in line 4.

    It should look like this:
    Code: ags
    
    if (gJournal.BackgroundGraphic < 52) gJournal.BackgroundGraphic ++;
     
    if (gJournal.BackgroundGraphic == 52)
    {
      bScissors.Visible = true;
      bNextPage.Visible = false;
    }
    else bScissors.Visible = false;

    SMF spam blocked by CleanTalk