Switching between scenes with buttons as choices

Hi! I am sooo new to coding, I got to where I am through my friends and jumping around a lot

but I am basically trying to make an interactive story and I found out how to make the text bubbles and to go to the next scene! but… I am now trying to figure out how to make buttons and make those buttons go to specific scenes (so basically the player can make choices and depending on those choices they go to a different scene)

I apologize if this is too much or if I’m in the wrong place… but I’m really stuck and don’t know where/how to do this ,

please simple words!! thank you for reading this ^^

https://pastebin.com/JKWGhMtm
^here is my code, its pretty biggg, so i put it in pastebin instead of here

Hello,

and welcome to the forum!

Yeah, you can make a new variable state before setup ():

int state = 0;

0 is your start screen.

Each number state gets represents a different screen in your story.

Upon a click on a button the button tells the state which number it must take.

state = btnNumber. This depends a bit on how your buttons are made, I didn’t look.

Now in draw() evaluate state with if(state==...) (or with switch(state) {)

if (state==0) {

}
else if (state==1) {

}

else if (state==2) {

}

Nothing is allowed outside this if…else if…-clause in draw().

Between the {…} the screen for that number is shown. You can also write functions there like showScreen0, showScreen1 etc.

mousePressed()

Also in the function mousePressed() you can evaluate only the buttons visible in the current screen. Use the same if-clause like in draw() (without calling the screens, just the if... else if....-bits) and check in each screen only the appropriate buttons.

Warm regards,

Chrisir

Ah, I just looked at your Sketch, you have all this already

Apologies.

haha yeah, i wanna make an interactive story so idk how to make it branch off :frowning:

i know how to make it linear tho!

OK, do you want a branch between screen A and screen B ?

Do yo want this when he clicks a different button b1 or b2?

Hello,

I made an example sketch for you.

It holds the buttons in an array (a list). See https://www.processing.org/tutorials/arrays

Each button has a position, a state (in which it is shown), a text, and a target (the state it leads to).

All these properties are bundled.

This concept is called objects. See https://www.processing.org/tutorials/objects

The objects have the following main properties

#      Text     state    target
-----------------------------------------
0	b10	0	1
1	b11	0	2
2	b12	1	3
3	#+	2	0
4	b14	3	5
5	b15	4	6

Come back when you have any questions please.

Chrisir


// Naming conventions; I use this throughout :  
//   class = UpperCase and singular (contains only ONE circle) - CircleButton
//   array = lowerCase and plural (contains many circles)      - myCircleButtons 
//   object / variable = lowerCase and singular                - button / myCircleSize 

CircleButton[] myCircleButtons = new CircleButton[6]; // 

// we define on Which State Is This Button Visible for each button separately 
int[] onWhichStateIsThisButtonVisible = 
  {
  0, 
  0, 
  1, 
  2, 
  3, 
  4
}; 

int state; 

void setup() {
  size(1290, 790);
  background(120);  // new

  if (myCircleButtons.length!=onWhichStateIsThisButtonVisible.length) {
    println("Error 7846: length different: myCircleButtons vs. onWhichStateIsThisButtonVisible. \n       onWhichStateIsThisButtonVisible.length = " 
      +onWhichStateIsThisButtonVisible.length);
    exit();
    return;
  }

  int myCircleSize = 100; // 
  for (int i = 0; i < myCircleButtons.length; i++) {
    // random color - color when mouse is NOT over this botton 
    color myColor = color(0, random(255), random(255));  //  
    // define button and put it into the array 
    myCircleButtons[i] = new CircleButton(
      110 + i*(myCircleSize+14), // x-value 
      110, // y-value
      myCircleSize, // size 
      myColor, // color
      "b"+str(i+10), // its text  
      onWhichStateIsThisButtonVisible [i], 
      i+1     // the state it leads to when clicked !!!!! 
      );
  }//for

  // change buttons individually: 
  myCircleButtons[3].text = "#+";
  myCircleButtons[3].stateToGoTo = 0;

  // show properties of all buttons 
  int i=0;
  println("#         Text     state    target"); 
  println("-----------------------------------------");
  for (CircleButton button : myCircleButtons) {    // cool way of a for-loop (for **each** button (of type CircleButton) in the array myCircleButtons do the following)
    print(i+"\t");
    button.printlnProperties();
    i++;
  }//for

  println("\nEnd of setup()");
}//function 

void draw() {
  background(120); // the image is more crisp with background 
  fill(255);

  switch (state) {
  case 0: 
    text ("page 0", 111, 311); 
    break; 

  case 1: 
    text ("page 1", 111, 311); 
    break; 

  case 2: 
    text ("page 2", 111, 311); 
    break; 

  case 3: 
    text ("page 3", 111, 311); 
    break;

  case 4: 
    background(0);
    text ("page 4", 111, 311); 
    break;

  default:
    println("Error 3459: Unknown state error " 
      + state);  
    state = 0; 
    break;
  }//switch 

  for (CircleButton button : myCircleButtons) {    // cool way of a for-loop (for **each** button (of type CircleButton) in the array myCircleButtons do the following)
    if (state == button.shownInWhichState) {
      button.update();
    }
  }//for
}//function 

// -------------------------------------------------------------------------
// Input functions 

void mousePressed() {
  for (CircleButton button : myCircleButtons) {    // cool way of a for-loop (for **each** button (of type CircleButton) in the array myCircleButtons do the following)
    if (state == button.shownInWhichState) {
      if (button.overCircle()) {
        state=button.stateToGoTo;
        return;
      }//if
    }//if
  }//for
}

// ======================================================================== // line to show: here starts a class

class CircleButton {

  int circleX, circleY;  // Position of circle button
  int circleSize;     // Diameter of circle

  color circleColor = color(255, 0, 0);  // RED when over!!!!!!!!!!!!!!!
  color baseColor;  // when not over - gets defined in the constructor

  boolean circleOver = false; // not really in use, never mind 

  int shownInWhichState; 
  int stateToGoTo;

  String text; 

  // constructor
  CircleButton(int posX_, int posY_, // linebreaks for better readability. Marking parameters with a _ sign. 
    int theSize_, 
    color baseColor_, 
    String text_, 
    int shownInWhichState_, 
    int stateToGoTo_) { 
    // constructor 
    circleX = posX_;
    circleY = posY_;
    circleSize = theSize_;
    baseColor = baseColor_;
    shownInWhichState=shownInWhichState_;
    stateToGoTo=stateToGoTo_;
    text=text_;

    ellipseMode(CENTER);
  }// constructor

  void update() {    
    // make use of circleColor and  baseColor
    if (overCircle()) {
      fill( circleColor ); // over 
      stroke(255);
    } else {
      fill( baseColor ); // not over
      noStroke();
    }
    ellipse(circleX, circleY, 
      circleSize, circleSize);
    fill(255);
    textAlign(CENTER);
    textSize(22);
    text(text, 
      circleX, circleY);
    //reset
    textAlign(LEFT);
  }//method

  boolean overCircle() { 
    if (dist(mouseX, mouseY, circleX, circleY) < circleSize/2 ) { // using in-build function dist() here!
      circleOver = true;
      return true;
    } else {
      circleOver = false;
      return false;
    }
  }//method

  void printlnProperties() {
    //
    println (text +"\t"+ shownInWhichState +"\t"+ stateToGoTo);
  }//method
  //
}//class // marking the end of the class 
//

of course, the buttons can be all of:

  • textual or
  • graphical (e.g. using a pre-loaded image or a internal drawing like your arrow) or
  • invisible (like when a part of your background, e.g. a door or a path, is clickable)
  • a variable type could decide which type we show

Also you could have a help text for each button that gets displayed in the footer of the page when the mouse hovers. (The small door looks old and forbidding.)

Remark

I mean, hm…

When you want to make a full story like this… hm…

You know, at the moment, when you have a new screen, you write more code. This seems logical at the moment. The code is not separated from the story. Therefore your code gets longer, when the story gets longer.

This will lead to confusing code eventually.

But please go on first, maybe it will work for you.

Instead

Instead you could try the following:

separate the code and the story.

How?

The code would load a text file which holds the story and the code works its way through the text file.

The code remains the same length, when the story grows. Only the text file grows.

The text file would have the following structure. Think of a table or a Excel sheet:

Screen number | text                     | text button 1        |text button 2         |  target 1  |  target 2   | IMG 
0, You come into a village.              | I chose path left    |I chose path right    |      1     |      2      | image2
1, The left path leads down a steep road.| I enter the CAVE     |I pick up the arrow   |      3     |      4      | img8
2, The right path leads up to a mountain.....
3,
4,
5,

It could have additional data like image name for the screen or messages (to a certain extent or in a 2nd text file)

But in your story you will end up with a tree of possible decisions you have to handle.

see https://en.wikipedia.org/wiki/Adventure_game#Graphic_adventure

oh my gosh thank you!!! ill look at this right now, i didn’t expect such a speedy reply!! ill look at this and get back to you!! thank you again for replying!!

1 Like

hey I’m back!!

so i’ve been messing around the code for a bit and i think i’ve come to understand it a bit better! however there is one thing i still cant seem to get and that is circleX and circleY. how can i change it so that i can manually put where I want the buttons to be?? also!

when you said I should use a text file, I would put that in the data folder right? that seems like something i should really invest in cause yeahh my story will get a bit long and thats a lot of code

thanks again for all that you’ve done so far!!

circleX and circleY are done in a for loop at the Moment

Get rid of the for loop and fill the array without it

buttons[0]=new…

and just write in a number for the Position

LIKE THIS


// Naming conventions; I use this throughout :  
//   class = UpperCase and singular (contains only ONE circle) - CircleButton
//   array = lowerCase and plural (contains many circles)      - myCircleButtons 
//   object / variable = lowerCase and singular                - button / myCircleSize 

CircleButton[] myCircleButtons = new CircleButton[6]; // 

int state=0; 
int prevState=0; // previous state - can be improved 

// FOR special buttons:

// special value for onWhichStateIsThisButtonVisible
final int ALL_PAGES  = -17;    // must be negative

//special value for stateToGoTo in the class  
final int PREVIOUS_PAGE = -18; // must be negative

// -----------------------------------------------------------------------------------------------------------------------

void setup() {
  size(1290, 790);
  background(120);  // new

  // Define buttons 
  defineButtons(); 

  // show properties of all buttons 
  int i=0;
  println("#         Text     state    target"); 
  println("-----------------------------------------");
  for (CircleButton button : myCircleButtons) {    // cool way of a for-loop (for **each** button (of type CircleButton) in the array myCircleButtons do the following)
    print(i+"\t");
    button.printlnProperties();
    i++;
  }//for

  println("\nEnd of setup()");
}//function 

void draw() {
  background(120); // the image is more crisp with background 
  fill(255);

  switch (state) {
  case 0: 
    text ("page 0", 111, 311); 
    text ("You come to a crossing. Which way do you want to go?", 19, 19); 
    break; 

  case 1: 
    text ("page 1", 111, 311); 
    break; 

  case 2: 
    text ("page 2", 111, 311); 
    break; 

  case 3: 
    text ("page 3", 111, 311); 
    break;

  case 4: 
    background(0);
    text ("page 4", 111, 311); 
    break;

  default:
    println("Error 3459: Unknown state error " 
      + state);  
    state = 0; 
    break;
  }//switch 

  // cool way of a for-loop (for **each** button (of type CircleButton) in the array myCircleButtons do the following) - see reference
  for (CircleButton button : myCircleButtons) { 
    if (state == button.shownInWhichState || button.shownInWhichState == ALL_PAGES) {   // only for current state OR for special buttons
      button.update();
    }
  }//for
}//function 

// -----------------------------------------------------------------------------------------------------------------------
// defineButtons function 

void defineButtons() {

  // Define buttons 

  int myCircleSize = 100; //
  // we define on Which State Is This Button Visible for each button separately 
  int onWhichStateIsThisButtonVisible=0; 
  // color - color when mouse is NOT over this botton 
  color myColor = color(0, random(255), random(255));  //  
  // define button and put it into the array 

  // change buttons individually: 
  // define individual values
  myCircleSize = 200; //
  onWhichStateIsThisButtonVisible=0; 
  myColor = color(255, 120, 0);  // color
  // make new button and pass the values to it
  myCircleButtons[0] = new CircleButton(
    210, // x-value position 
    170, // y-value position 
    myCircleSize, // size 
    myColor, // color
    "Left", // its text  
    onWhichStateIsThisButtonVisible, 
    1     // the state it leads to when clicked !!!!! 
    );

  // change buttons individually:
  // define individual values
  myCircleSize = 100; //
  onWhichStateIsThisButtonVisible=0;
  myColor = color(0, 255, 0);  // GREEN 
  // make new button and pass the values to it
  myCircleButtons[1] = new CircleButton(
    410, // x-value position 
    310, // y-value position 
    myCircleSize, // size 
    myColor, // color
    "Right", // its text  
    onWhichStateIsThisButtonVisible, 
    2     // the state it leads to when clicked !!!!! 
    );

  // change buttons individually:
  // define individual values
  onWhichStateIsThisButtonVisible=1;
  myColor = color(0, 0, 255);  // BLUE
  // make new button and pass the values to it
  myCircleButtons[2] = new CircleButton(
    310, // x-value position  
    110, // y-value position 
    myCircleSize, // size 
    myColor, // color
    "North", // its text  
    onWhichStateIsThisButtonVisible, 
    3     // the state it leads to when clicked !!!!! 
    );

  // change buttons individually:
  // define individual values
  onWhichStateIsThisButtonVisible=3;
  myColor = color(0, 0, 255);  // BLUE
  // make new button and pass the values to it
  myCircleButtons[3] = new CircleButton(
    310, // x-value position  
    110, // y-value position 
    myCircleSize, // size 
    myColor, // color
    "crouch", // its text  
    onWhichStateIsThisButtonVisible, 
    3     // the state it leads to when clicked !!!!! 
    );

  // ===============================================================
  // on ALL pages 

  // change buttons individually:
  // define individual values
  onWhichStateIsThisButtonVisible=ALL_PAGES;
  myColor = color(0, 0, 255);  // BLUE
  // make new button and pass the values to it
  myCircleButtons[4] = new CircleButton(
    width-45, // x-value position  
    height-45, // y-value position 
    myCircleSize, // size 
    myColor, // color
    "Restart", // its text  
    onWhichStateIsThisButtonVisible, 
    0     // the state it leads to when clicked !!!!! 
    );

  // change buttons individually:
  // define individual values
  onWhichStateIsThisButtonVisible=ALL_PAGES;
  myColor = color(0, 0, 255);  // BLUE
  // make new button and pass the values to it
  myCircleButtons[5] = new CircleButton(
    width-45-103, // x-value position  
    height-45, // y-value position 
    myCircleSize, // size 
    myColor, // color
    "Back", // its text  
    onWhichStateIsThisButtonVisible, 
    PREVIOUS_PAGE     // the state it leads to when clicked !!!!! 
    );
}//func 

// -------------------------------------------------------------------------
// Input functions 

void mousePressed() {
  for (CircleButton button : myCircleButtons) {    // cool way of a for-loop (for **each** button (of type CircleButton) in the array myCircleButtons do the following)
    if (state == button.shownInWhichState || button.shownInWhichState == ALL_PAGES) {    // only for current state OR for special buttons
      if (button.overCircle()) {     // when mouse on this button
        // When its a Back button: 
        if (button.stateToGoTo==PREVIOUS_PAGE) {
          state=prevState; // restore
          return;      // leave
        } else 
        {
          // normal button : go to new page 
          prevState=state; // save old state  
          state=button.stateToGoTo;   // execute 
          return;      // leave
        }
      }//if
    }//if
  }//for
}

// ======================================================================== 
// line to show: here starts a class

class CircleButton {

  int circleX, circleY;  // Position of circle button
  int circleSize;     // Diameter of circle

  String text; 

  color circleColor = color(255, 0, 0);  // RED when over!!!!!!!!!!!!!!!
  color baseColor;  // when not over - gets defined in the constructor

  boolean circleOver = false; // not really in use, never mind 

  // functionality
  int shownInWhichState; 
  int stateToGoTo;

  // constructor
  CircleButton(int posX_, int posY_, // linebreaks for better readability. Marking parameters with a _ sign. 
    int theSize_, 
    color baseColor_, 
    String text_, 
    int shownInWhichState_, 
    int stateToGoTo_) { 
    // constructor 
    circleX = posX_;
    circleY = posY_;
    circleSize = theSize_;
    baseColor = baseColor_;
    shownInWhichState=shownInWhichState_;
    stateToGoTo=stateToGoTo_;
    text=text_;

    ellipseMode(CENTER);
  }// constructor

  void update() {    
    // make use of circleColor and  baseColor
    if (overCircle()) {
      fill( circleColor ); // over 
      stroke(255);
    } else {
      fill( baseColor ); // not over
      noStroke();
    }
    ellipse(circleX, circleY, 
      circleSize, circleSize);
    fill(255);
    textAlign(CENTER);
    textSize(22);
    text(text, 
      circleX, circleY);
    //reset
    textAlign(LEFT);
  }//method

  boolean overCircle() { 
    if (dist(mouseX, mouseY, circleX, circleY) < circleSize/2 ) { // using in-build function dist() here!
      circleOver = true;
      return true;
    } else {
      circleOver = false;
      return false;
    }
  }//method

  void printlnProperties() {
    //
    println (text 
      +"\t"
      + shownInWhichState 
      +"\t"
      + stateToGoTo);
  }//method
  //
}//class // marking the end of the class 
//

Hello!

As discussed briefly above here is an example with text data that are used by the program.
Separation of text and program. Good.

The Text is written in the program here (at the beginning) but you can also use a text file and load it with loadStrings(). But the principle of the separation remains the same.

The text makes dialog lines. Each line is a screen.

A dialog line consists of:

  • an id,
  • the line (text) itself, and
  • a list of choices, ie. of possible answers to this line. This list can be of different length. When you’d mouse, this would be the text of the mouse buttons.

The program has nearly no mouse usage, instead you have to enter the choices with keys 1,2,3…

Program is not by me but from the old forum.
It is also not finished:

  • In terms of the screens and choices, it stops somewhere. No more lines.
  • In terms of Strength, Wealth and Monster Tally: Those don’t get computed.

Warm regards,

Chrisir

// based on http://www.atariarchives.org/adventure/chapter2.php
// and on http://forum.processing.org/topic/help-with-dialog-setup#25080000001811353   
// It's from PhiLho. 

// ------------------------------------------------------------------

// states control the program
final int startScreen = 0; // possible states 
final int play = 1;
final int playerIsDead = 2;
final int playerWon = 3;

int state = startScreen; // current state 


// ----------------------------------------------

String globalSectionNumber;

// ----------------------------------------------

// done correct 7 38 40 21 29 6 28 3 4 5  1  37 38 41 10 17 25

// could also use loadStrings
DialogLine[] dialogLines =
  {
  new DialogLine("1", "You are in a dank, dark dungeon. The only light comes into the room from a small hole in the west wall. To leave the dungeon, go on.", "OK#25" ), 
  new DialogLine("2", "You are in the L-shaped upper hallway of the castle. A moth flutters across the room near the ceiling. To the north is a door and there is a stairwell in the hall as well. If you wish to peek through the door to the north, go to 33. If you wish to look down the stairwell, go to 39. You must flip a coin; if it lands tails, go to 13. To go through the door, go to 30. To go down the stairs, go to 21.", "peek through the door to the north#33", "If you wish to look down the stairwell#39", "You must flip a coin; if it lands tails chose this line#13", "To go through the door#30", "To go down the stairs#21" ), 
  new DialogLine("3", "Looking down the stairwell, you can see a gloomy, unpleasant looking room, the guardroom of the ancient dungeon.", "OK#21" ), 
  new DialogLine("4", "Inside the sack you find jewels worth $500, so add them to your wealth.", "OK#9" ), 
  new DialogLine("5", "The ghost of the guard has awoken! Your strength is halved due to the fright you suffered.", "OK#1" ), 
  new DialogLine("6", "You are in the Great Hall of the castle. There are two doors in the L-shaped room. You notice the wood panels around the room are warped and faded. As you look around, a mouse scampers across the floor. You whirl around at a sudden noise. Flip a coin. If it is heads, go to 43. If it is tails, you see to your relief there is nothing there. If you want to look out of the windows to get your bearings, you can do so. You can also exit by the north doors. Or move to the east.", "look out of the windows#28", "exit by the north or west doors#29", "move to the east#21"), 
  new DialogLine("7", "You are at the entrance of a forbidding-looking stone castle. You are facing east. The huge wooden entrance door stands lightly open. To enter the castle, press 1.", "Enter the castle#40" ), 
  new DialogLine("8", "A werewolf awakes in this room. He attacks you. Flip a coin. If it is heads, the werewolf has beaten you, so go to 37. If it is tails, you have killed it. Add one to your monster tally, then go to 35.", "9" ), 
  new DialogLine("9", "You are in the storeroom, amidst spices, vegetables, and vast sacks of flour and other provisions. The air is thick with spice and curry fumes. If you want to look under some of the sacks, go to 31. If you want to look inside the top sack, go to 4. To leave by the south door, go to 42. Go to 35 if you wish to leave by the north door.", "10" ), 
  new DialogLine("10", "Looking up the stairwell you can just make out an elaborately decorated hallway.", "OK#21" ), 
  new DialogLine("11", "There are rats in this dungeon. They steal gold pieces worth $10 from you.", "OK#1" ), 
  new DialogLine("12", "You are descending very, very slowly. Your strength is sapped by a magic spell left in the elevator. Divide your strength by two, then proceed straight to 42.", "13" ), 
  new DialogLine("13", "A malevolent Maldemer attacks you. You can smell the sulfur on his breath. Your strength diminishes by 10. Flip two coins. If they both come up heads, you have killed the Maldemer, so add one to your monster tally. After the battle, go to 42.", "14" ), 
  new DialogLine("14", "You've done it! That was the exit from the castle. Double your strength.", "OK#27" ), 
  new DialogLine("15", "You are in the castle's ancient, hydraulic elevator. If you wish to descend slowly, go to 12. To get down as quickly as possible, go to 24.", "16" ), 
  new DialogLine("16", "Horrors. There is a devastating Ice-Dragon here. It leaps toward you. Blood drips from his claws. Flip a coin. Heads you win, adding one to your monster tally. Your strength drops by 10 if you win; by 20 if you lose. After the fight, go on.", "OK#30" ), 
  new DialogLine("17", "This is the monarch's private meeting room. The echo of ancient plotting and wrangling hangs heavy in the musty air. Flip a coin. If it lands up heads, you find an emerald worth $100, then go to the exit through the south door. If it is tails, you are attacked by a ghastly Gruesomeness which was hiding behind the drapes. Flip the coin again. If it lands tails again, you win, adding one to your monster tally. If it lands heads the Gruesomeness wins. While you are lying exhausted on the floor, he steals $100 from your wealth.", "OK#21" ), 
  new DialogLine("18", "This tiny room on the upper level is the dressing chamber. There is a window to the north. If you wish to see out the window, go to 22. There is a door which 1eaves the room to the south. To use this door, go to 32.", "19" ), 
  new DialogLine("19", "The noise is frightening. What on earth (or beyond it) is inside that room? Go to 23.", "20" ), 
  new DialogLine("20", "Aha... wealth! You find great treasure here worth $900 in gems and gold. Add it to your wealth, then go to 30.", "21" ), 
  new DialogLine("21", "You are in the inner hallway, which contains a door to the north one to the west, and a circular stairwell. The room is small and unfriendly. \n\n   Now you can: ", "Look down the stairwell#3", "To look up the stairs#10", "To leave by the north door#17", "if you wish to leave by the west door#6", "go up the stairs#2", "go down them#25" ), 
  new DialogLine("22", "Looking out the window you see, below you, the secret herb garden. Looking hard to the left, you recognize the land you crossed to get to the castle entrance. Now go to 18.", "23" ), 
  new DialogLine("23", "You are in the room which was used as the castle treasury years ago. A spider scampers down the wall. There are no windows, just exits to the north and to the east. If you wish to listen at the north door, go to 19. If you want to leave by the north door, go to 32. Go to 36 to leave by the east door.", "24" ), 
  new DialogLine("24", "You feel exhilarated, as a positive spell is triggered by your swift downward flight. Your strength is doubled. Now go to 42.", "25" ), 
  new DialogLine("25", "You are in the prison guardroom, in the basement of the castle. The stairwell ends in this room. There is one other exit, a small hole in the east wall. The air is damp and unpleasant . . . a chill wind rushes into the room from gaps in the stone at the top of the walls. Go east or go up the stairs.", "go east#1", "go up the stairs#21" ), 
  new DialogLine("26", "Looking out the south window you see the ornamental lake. There is a view across open fields through the east window. You look longingly at the outdoors, then go to 42.", "27" ), 
  new DialogLine("27", "Your score is five times your strength, plus two times your wealth, plus thirty times your monster tally. You have come to the end of the adventure. Now proceed with the rest of this book.", "28" ), 
  new DialogLine("28", "By straining your eyes through the mist which has swirled up while you've been exploring, you can see below you, looking southwards, an ornamental lake. By craning your neck round to the right through the west window you can just see the entrance door to the castle. When you've finished looking, go on.", "Finished#6" ), 
  new DialogLine("29", "You are in the castle's Audience Chamber. The faded tapestries on the wall only hint at the splendor which this room once had. There is a window to the west. By craning your neck through it to the right you can see the castle entrance. Flip two coins. If they both land heads, you find diamonds worth $169. If they are both tails, you must fight the fanatical Fleshgorger which suddenly stumbles into the room. To fight the Fleshgorger, flip both coins again. One head and one tail, you defeat it, adding one to your monster tally and doubling your strength. If the two coins are heads or tails, you lose, and your strength is halved. \n\nYou can leave by the north or you can leave by the south or the east doors.", "leave by the north#40", "leave by the south or the east doors#6" ), 
  new DialogLine("30", "You find yourself in the master bedroom on the upper level of the castle. Looking down from the window to the west you can see the entrance to the castle, while the secret herb garden is visible below the north window. There are doors to the east and to the south. You must flip a coin. If it lands heads, go to 20. Go to 16 if it comes up tails. To leave by the south door, go to 2. Go to 82 if you wish to leave by the east door.", "31" ), 
  new DialogLine("31", "A ferocious werewolf leaps at you, his eyes glinting violently. Flip two coins, quickly. If they are the same, you defeat the werewolf. Although your strength is diminished by ten, you manage to escape, and go to 9. If the coins are different, the werewolf starts tearing you apart, cutting your strength to half of what it was before. You drag yourself away, and go to 9.", "32" ), 
  new DialogLine("32", "Oooh . . . you are in the chambermaid's bedroom. Faint perfume hangs in the air. There is an exit to the west and a door to the south. However, your attention is caught by the steady thumping coming from behind the bed. Fearfully, you look behind it, and a devastating Ice-dragon leaps at you! You smell the sulfur on his breath. Flip two coins. Unless they are two heads, you lose, and 15 is struck from your strength tally. If you win, add 100 to your strength. To leave by the north, go to 18. Go to 30 if you wish to leave by the west door. The south door leads to 23.", "33" ), 
  new DialogLine("33", "Peering into the room you see it was once the master bedroom. It appears quiet. As you turn back you notice a small bottle on the ground. Quickly, you uncork it and swallow the contents. Flip two coins. Unless they are both tails, the bottle contained a wonderful elixir which has tripled your strength. If the coins were both tails the bottle contained only water. Now go to 2.", "34" ), 
  new DialogLine("34", "Now you're under attack from a nasty, ghastly Gruesomeness. Flip two coins. Two tails, you win, and add 50 to your strength. Two heads, your strength is halved as the G.G. defeats you. Now go to 2.", "35" ), 
  new DialogLine("35", "This is the castle's kitchen. Through windows in the north wall you can see the secret herb garden. It has been many years since meals were prepared here for the monarch and the court. A rat scurries across the floor. Flip a coin. If it lands heads, you stumble, making a noise, and must go to 8 to see the effect that noise has had. To leave by the south door, go to 9.", "36" ), 
  new DialogLine("36", "You are in a small room which is outside the castle itself. You can see the lake through the southern windows. Flip a coin. If it is heads, go to 41. To leave by the north door, go to 15. Go to 23 if you wish to leave by the west door.", "37" ), 
  new DialogLine("37", "You are dead!!! ", "OK#27" ), 
  new DialogLine("38", "Go to 14", "Go on#14" ), 
  new DialogLine("39", "Looking down the stairwell you can see a small room below, and on the floor below that, you can just make out the gloomy guardroom. A ghost of a former guardsman suddenly appears on the stairwell. He demands $100. If you have it, pay him, then go to 2. If you do not have enough, the guard attacks you in anger. Flip a coin. Heads, go to 37. Tails, halve your strength, then go to 2.", 
  "If you have it, pay him#2", 
  "If you do not have enough, the guard attacks you in anger. Flip a coin. Heads#37", 
  "Tails, halve your strength#2" ), 
  new DialogLine("40", "You are in the hallway entrance to the castle. It is dark and gloomy, and the air of decay and desolation is very depressing. \nYou suddenly feel very frightened. To run away from the castle, press 1. To proceed through the south door, press 2.", "run away#7", "proceed through the south door#29" ), 
  new DialogLine("41", "A spider bites you on the leg. Your strength is diminished by 20.", "OK#36" ), 
  new DialogLine("42", "You are in the rear vestibule. There are windows to the south. To look out them, go to 26. Flip a coin. If it lands heads, go to 13. To leave by the north door, go to 9. Go to 38 to leave by the east door.", "43" ), 
  new DialogLine("43", "The horrendous Hodgepodge attacks you!!! He fights wildly, madly. Flip two coins. Unless they are both tails, you have beaten it and double your strength. If they are both tails, the H.H. beats you, and your strength is halved. Now go to 6.", "44" )
};

// The dialog lines indexed by their id, for easy lookup
HashMap<String, DialogLine> dialogTree = new HashMap<String, DialogLine>();

// The line currently displayed
DialogLine currentLine;

// The dialog so far (logging it)
ArrayList<String> dialog = new ArrayList<String>();

// --------------------------------------------------------------------------

void setup () {
  size(800, 800);
  smooth();
  // fill HashMap 
  for (DialogLine dl : dialogLines) {
    dialogTree.put(dl.id, dl);
  }

  // start point is 7 - see http://www.atariarchives.org/adventure/chapter2.php
  currentLine = dialogTree.get("7");
  globalSectionNumber = "7";
  dialog.add(currentLine.line);

  state=startScreen;
}

void draw () {
  background(255);

  // states: 
  switch(state) {

  case startScreen:
    showStartScreen();
    break;

  case play:
    play();
    break;

  default:
    //error
    println ("unknown state line 64");
    exit();
    break;
  } // switch
} // func 

// --------------------------------------------------------------------------

void showStartScreen() {

  fill(#004499);

  textSize(32);
  text ("The Great Adventure", 70, 70);

  textSize(20);
  int y_value = 130;

  text ("Welcome to our text adventure. You start the game with $50 in gold, and a strength rating of 50. ", 20, y_value, width-40, 100);

  y_value+=90;
  text ("STRENGTH      WEALTH      MONSTER TALLY", 20, y_value);
  y_value+=20;
  text ("   50                   50                   0       ", 20, y_value);
  y_value+=50;
  text ("All you have to do now, as you progress through the castle, aided only by your quick decisions, is survive. \n"
    +"You'll find that you can take part in this adventure several times, as the outcome will be different each time. Keep a "
    +"record of your final score, and see if you can better it each time you go exploring.", 
    20, y_value, 
    width-40, 200);
  y_value+=220;
  text ("Press any key. ", 120, y_value);
}

void play() {  

  // that's the main part. It's from PhiLho from the forum. 

  fill(#004499);
  textSize(20);
  text(currentLine.line, 10, 30, width-30, 360);

  // Display the choice of answers
  fill(#0077EE);
  textSize(15);
  int y = 390;
  int toChoose = 1;
  for (String ch : currentLine.choices) {
    String [] myArray = split(ch, "#");
    text(toChoose++ 
      + ": " 
      + myArray[0], 
      23, y);
    y += 24;  // next line
  }

  // for testing: 
  text (globalSectionNumber, width-30, height-30);

  /* 
   // Display the history of the curent game
   // (this could be an extra state of the program)
   fill(#0055AA);
   textSize(12);
   y = 200;
   for (String line : dialog)
   {
   // println (line);
   text (line, 20,y );
   y += 20;
   }
   println ("----------------------");
   */
}

// inputs ---------------------------------------------------------

void keyPressed() {

  // states: 
  switch(state) {

  case startScreen:
    // start the game 
    state=play;
    break;

  case play:
    // interprete input

    // get the current number of choices 
    int choiceNb = currentLine.choices.length;

    // get key as a number from 0 to choiceNb
    int choice = key - '1';
    // println(choice); 

    // Ignore anything BUT numbers
    if (choice < 0 || choice >= choiceNb)
      return; // Ignore: leave function 

    String choiceMade = currentLine.choices[choice];
    String [] myArray = split(choiceMade, "#");  

    String choiceId = "<No Text.>";
    if (1<myArray.length) {
      choiceId = myArray[1];
    }

    globalSectionNumber = choiceId;

    DialogLine chosenAnswer = dialogTree.get(choiceId);
    if (chosenAnswer != null) {
      currentLine = dialogTree.get(choiceId);
      dialog.add(currentLine.line);
    }
    break;

  default:
    //error
    println ("unknown state line 148");
    exit();
    break;
  } // switch
  //
}//func 

void mousePressed() {
  // states: 
  switch(state) {

  case startScreen:
    state=play;
    break;  

  case play:
    // Display the history of the curent game
    // (this could be an extra state of the program)
    // fill(#0055AA);
    // textSize(12);
    //  y = 200;
    println ("----------------------");
    for (String line : dialog) {
      println (line);
      //text (line, 20,y );
      //y += 20;
    }
    println ("----------------------");
    break;

  default:
    //error
    println ("unknown state line 1480 in mousePressed()");
    exit();
    break;
  } // switch
} 


// ====================================================================

/**
 * A dialog line: an id, the line (text) itself, and a list of choices,
 * ie. of possible answers to this line.
 */
class DialogLine {
  String id;
  String line;
  String[] choices;  // list 

  //constructor 
  DialogLine(String i_, String l_, String... c_) {
    id = i_;
    line = l_;
    choices = c_;
  }//constructor

  String toString() {
    return id
      + " - "
      + line 
      + " (" 
      + choices.length 
      + ")";
  }//method
} // class 
//

thank you!!! so I’ve just been messing around with these example codes you’ve given me and it helped me a lot to understand what each function does

and for the most part, I understand how to work with both now thanks to you!

but now, I’m not sure how to combine the two codes so that they work together?? like I want the button to change to a certain scene instead of a STATE :o

and when I merged the two codes together, I don’t know how to time it correctly.
like Scene1: text.text.text.choice1/choice2 -> goes to scene 2 or scene 3 depending on the choice

rect buttons: https://pastebin.com/4V0ev3M0
textscenes: https://pastebin.com/uzJSdfaS

but hey I am so thankful for all that you’ve explained to me so far
it genuinely helps me more than my teacher could, just cause it really helps me to receive something and dissect it visually

if you think you can’t help me then please let me know, its alright!! :slight_smile:

I am afraid i don’t have time

scene is just another word for state, just use one or the other throughout

But you can’t really merge the codes as such, because in your initial approach, the story is woven into the code and in my new approach they are separated.

When you want to use the second approach, make your story into text lines and replace the old text lines with your story

And implement mouse if you want

yeah i was worried I was taking too much of your time, I thank you for what you have done up till this point though !

I will take your advice :smiley:

1 Like

// I tried to combine the two a bit
// now the text lines generate mouse buttons


// based on http://www.atariarchives.org/adventure/chapter2.php
// and on http://forum.processing.org/topic/help-with-dialog-setup#25080000001811353   
// It's from PhiLho. 

// ------------------------------------------------------------------

// states control the program
final int startScreen = 0; // possible states 
final int play = 1;
final int playerIsDead = 2;
final int playerWon = 3;

int state = startScreen; // current state 

// ----------------------------------------------

ArrayList<CircleButton> myCircleButtons = new ArrayList(); // 

String globalSectionNumber;

// ----------------------------------------------

// done correct 7 38 40 21 29 6 28 3 4 5  1  37 38 41 10 17 25

// could also use loadStrings
DialogLine[] dialogLines =
  {
  new DialogLine("1", "You are in a dank, dark dungeon. The only light comes into the room from a small hole in the west wall. To leave the dungeon, go on.", "OK#25" ), 
  new DialogLine("2", "You are in the L-shaped upper hallway of the castle. A moth flutters across the room near the ceiling. To the north is a door and there is a stairwell in the hall as well. If you wish to peek through the door to the north, go to 33. If you wish to look down the stairwell, go to 39. You must flip a coin; if it lands tails, go to 13. To go through the door, go to 30. To go down the stairs, go to 21.", "peek through the door to the north#33", "If you wish to look down the stairwell#39", "You must flip a coin; if it lands tails chose this line#13", "To go through the door#30", "To go down the stairs#21" ), 
  new DialogLine("3", "Looking down the stairwell, you can see a gloomy, unpleasant looking room, the guardroom of the ancient dungeon.", "OK#21" ), 
  new DialogLine("4", "Inside the sack you find jewels worth $500, so add them to your wealth.", "OK#9" ), 
  new DialogLine("5", "The ghost of the guard has awoken! Your strength is halved due to the fright you suffered.", "OK#1" ), 
  new DialogLine("6", "You are in the Great Hall of the castle. There are two doors in the L-shaped room. You notice the wood panels around the room are warped and faded. As you look around, a mouse scampers across the floor. You whirl around at a sudden noise. Flip a coin. If it is heads, go to 43. If it is tails, you see to your relief there is nothing there. If you want to look out of the windows to get your bearings, you can do so. You can also exit by the north doors. Or move to the east.", "look out of the windows#28", "exit by the north or west doors#29", "move to the east#21"), 
  new DialogLine("7", "You are at the entrance of a forbidding-looking stone castle.\nYou are facing east. The huge wooden entrance door stands lightly open. \n\nEnter the castle.", "Enter the castle#40" ), 
  new DialogLine("8", "A werewolf awakes in this room. He attacks you. Flip a coin. If it is heads, the werewolf has beaten you, so go to 37. If it is tails, you have killed it. Add one to your monster tally, then go to 35.", "9" ), 
  new DialogLine("9", "You are in the storeroom, amidst spices, vegetables, and vast sacks of flour and other provisions. The air is thick with spice and curry fumes. If you want to look under some of the sacks, go to 31. If you want to look inside the top sack, go to 4. To leave by the south door, go to 42. Go to 35 if you wish to leave by the north door.", "10" ), 
  new DialogLine("10", "Looking up the stairwell you can just make out an elaborately decorated hallway.", "OK#21" ), 
  new DialogLine("11", "There are rats in this dungeon. They steal gold pieces worth $10 from you.", "OK#1" ), 
  new DialogLine("12", "You are descending very, very slowly. Your strength is sapped by a magic spell left in the elevator. Divide your strength by two, then proceed straight to 42.", "13" ), 
  new DialogLine("13", "A malevolent Maldemer attacks you. You can smell the sulfur on his breath. Your strength diminishes by 10. Flip two coins. If they both come up heads, you have killed the Maldemer, so add one to your monster tally. After the battle, go to 42.", "14" ), 
  new DialogLine("14", "You've done it! That was the exit from the castle. Double your strength.", "OK#27" ), 
  new DialogLine("15", "You are in the castle's ancient, hydraulic elevator. If you wish to descend slowly, go to 12. To get down as quickly as possible, go to 24.", "16" ), 
  new DialogLine("16", "Horrors. There is a devastating Ice-Dragon here. It leaps toward you. Blood drips from his claws. Flip a coin. Heads you win, adding one to your monster tally. Your strength drops by 10 if you win; by 20 if you lose. After the fight, go on.", "OK#30" ), 
  new DialogLine("17", "This is the monarch's private meeting room. The echo of ancient plotting and wrangling hangs heavy in the musty air. Flip a coin. If it lands up heads, you find an emerald worth $100, then go to the exit through the south door. If it is tails, you are attacked by a ghastly Gruesomeness which was hiding behind the drapes. Flip the coin again. If it lands tails again, you win, adding one to your monster tally. If it lands heads the Gruesomeness wins. While you are lying exhausted on the floor, he steals $100 from your wealth.", "OK#21" ), 
  new DialogLine("18", "This tiny room on the upper level is the dressing chamber. There is a window to the north. If you wish to see out the window, go to 22. There is a door which 1eaves the room to the south. To use this door, go to 32.", "19" ), 
  new DialogLine("19", "The noise is frightening. What on earth (or beyond it) is inside that room? Go to 23.", "20" ), 
  new DialogLine("20", "Aha... wealth! You find great treasure here worth $900 in gems and gold. Add it to your wealth, then go to 30.", "21" ), 
  new DialogLine("21", "You are in the inner hallway, which contains a door to the north one to the west, and a circular stairwell. The room is small and unfriendly. \n\n   Now you can: ", "Look down the stairwell#3", "To look up the stairs#10", "To leave by the north door#17", "if you wish to leave by the west door#6", "go up the stairs#2", "go down them#25" ), 
  new DialogLine("22", "Looking out the window you see, below you, the secret herb garden. Looking hard to the left, you recognize the land you crossed to get to the castle entrance. Now go to 18.", "23" ), 
  new DialogLine("23", "You are in the room which was used as the castle treasury years ago. A spider scampers down the wall. There are no windows, just exits to the north and to the east. If you wish to listen at the north door, go to 19. If you want to leave by the north door, go to 32. Go to 36 to leave by the east door.", "24" ), 
  new DialogLine("24", "You feel exhilarated, as a positive spell is triggered by your swift downward flight. Your strength is doubled. Now go to 42.", "25" ), 
  new DialogLine("25", "You are in the prison guardroom, in the basement of the castle. The stairwell ends in this room. There is one other exit, a small hole in the east wall. The air is damp and unpleasant . . . a chill wind rushes into the room from gaps in the stone at the top of the walls. Go east or go up the stairs.", "go east#1", "go up the stairs#21" ), 
  new DialogLine("26", "Looking out the south window you see the ornamental lake. There is a view across open fields through the east window. You look longingly at the outdoors, then go to 42.", "27" ), 
  new DialogLine("27", "Your score is five times your strength, plus two times your wealth, plus thirty times your monster tally. You have come to the end of the adventure. Now proceed with the rest of this book.", "28" ), 
  new DialogLine("28", "By straining your eyes through the mist which has swirled up while you've been exploring, you can see below you, looking southwards, an ornamental lake. By craning your neck round to the right through the west window you can just see the entrance door to the castle. When you've finished looking, go on.", "Finished#6" ), 
  new DialogLine("29", "You are in the castle's Audience Chamber. The faded tapestries on the wall only hint at the splendor which this room once had. There is a window to the west. By craning your neck through it to the right you can see the castle entrance. Flip two coins. If they both land heads, you find diamonds worth $169. If they are both tails, you must fight the fanatical Fleshgorger which suddenly stumbles into the room. To fight the Fleshgorger, flip both coins again. One head and one tail, you defeat it, adding one to your monster tally and doubling your strength. If the two coins are heads or tails, you lose, and your strength is halved. \n\nYou can leave by the north or you can leave by the south or the east doors.", "leave by the north#40", "leave by the south or the east doors#6" ), 
  new DialogLine("30", "You find yourself in the master bedroom on the upper level of the castle. Looking down from the window to the west you can see the entrance to the castle, while the secret herb garden is visible below the north window. There are doors to the east and to the south. You must flip a coin. If it lands heads, go to 20. Go to 16 if it comes up tails. To leave by the south door, go to 2. Go to 82 if you wish to leave by the east door.", "31" ), 
  new DialogLine("31", "A ferocious werewolf leaps at you, his eyes glinting violently. Flip two coins, quickly. If they are the same, you defeat the werewolf. Although your strength is diminished by ten, you manage to escape, and go to 9. If the coins are different, the werewolf starts tearing you apart, cutting your strength to half of what it was before. You drag yourself away, and go to 9.", "32" ), 
  new DialogLine("32", "Oooh . . . you are in the chambermaid's bedroom. Faint perfume hangs in the air. There is an exit to the west and a door to the south. However, your attention is caught by the steady thumping coming from behind the bed. Fearfully, you look behind it, and a devastating Ice-dragon leaps at you! You smell the sulfur on his breath. Flip two coins. Unless they are two heads, you lose, and 15 is struck from your strength tally. If you win, add 100 to your strength. To leave by the north, go to 18. Go to 30 if you wish to leave by the west door. The south door leads to 23.", "33" ), 
  new DialogLine("33", "Peering into the room you see it was once the master bedroom. It appears quiet. As you turn back you notice a small bottle on the ground. Quickly, you uncork it and swallow the contents. Flip two coins. Unless they are both tails, the bottle contained a wonderful elixir which has tripled your strength. If the coins were both tails the bottle contained only water. Now go to 2.", "34" ), 
  new DialogLine("34", "Now you're under attack from a nasty, ghastly Gruesomeness. Flip two coins. Two tails, you win, and add 50 to your strength. Two heads, your strength is halved as the G.G. defeats you. Now go to 2.", "35" ), 
  new DialogLine("35", "This is the castle's kitchen. Through windows in the north wall you can see the secret herb garden. It has been many years since meals were prepared here for the monarch and the court. A rat scurries across the floor. Flip a coin. If it lands heads, you stumble, making a noise, and must go to 8 to see the effect that noise has had. To leave by the south door, go to 9.", "36" ), 
  new DialogLine("36", "You are in a small room which is outside the castle itself. You can see the lake through the southern windows. Flip a coin. If it is heads, go to 41. To leave by the north door, go to 15. Go to 23 if you wish to leave by the west door.", "37" ), 
  new DialogLine("37", "You are dead!!! ", "OK#27" ), 
  new DialogLine("38", "Go to 14", "Go on#14" ), 
  new DialogLine("39", "Looking down the stairwell you can see a small room below, and on the floor below that, you can just make out the gloomy guardroom. A ghost of a former guardsman suddenly appears on the stairwell. He demands $100. If you have it, pay him, then go to 2. If you do not have enough, the guard attacks you in anger. Flip a coin. Heads, go to 37. Tails, halve your strength, then go to 2.", 
  "If you have it, pay him#2", 
  "If you do not have enough, the guard attacks you in anger. Flip a coin. Heads#37", 
  "Tails, halve your strength#2" ), 
  new DialogLine("40", "You are in the hallway entrance to the castle. It is dark and gloomy, and the air of decay and desolation is very depressing. \nYou suddenly feel very frightened. To run away from the castle, press the left button. To proceed through the south door, press the right button.", "run away#7", "proceed through the south door#29" ), 
  new DialogLine("41", "A spider bites you on the leg. Your strength is diminished by 20.", "OK#36" ), 
  new DialogLine("42", "You are in the rear vestibule. There are windows to the south. To look out them, go to 26. Flip a coin. If it lands heads, go to 13. To leave by the north door, go to 9. Go to 38 to leave by the east door.", "43" ), 
  new DialogLine("43", "The horrendous Hodgepodge attacks you!!! He fights wildly, madly. Flip two coins. Unless they are both tails, you have beaten it and double your strength. If they are both tails, the H.H. beats you, and your strength is halved. Now go to 6.", "44" )
};

// The dialog lines indexed by their id, for easy lookup
HashMap<String, DialogLine> dialogTree = new HashMap<String, DialogLine>();

// The line currently displayed
DialogLine currentLine;

// The dialog so far (logging it)
ArrayList<String> dialog = new ArrayList<String>();

// --------------------------------------------------------------------------

void setup () {
  size(1800, 800);
  smooth();
  // fill HashMap 
  for (DialogLine dl : dialogLines) {
    dialogTree.put(dl.id, dl);
  }

  // start point is 7 - see http://www.atariarchives.org/adventure/chapter2.php
  currentLine = dialogTree.get("7");
  globalSectionNumber = "7";
  dialog.add(currentLine.line);

  state=startScreen;
}

void draw () {
  background(255);

  // states: 
  switch(state) {

  case startScreen:
    showStartScreen();
    break;

  case play:
    play();
    break;

  default:
    //error
    println ("unknown state line 64");
    exit();
    break;
  } // switch
} // func 

// --------------------------------------------------------------------------

void showStartScreen() {

  fill(#004499);

  textSize(32);
  text ("The Great Adventure", 70, 70);

  textSize(20);
  int y_value = 130;

  text ("Welcome to our text adventure. You start the game with $50 in gold, and a strength rating of 50. ", 20, y_value, width-40, 100);

  y_value+=90;
  text ("STRENGTH      WEALTH      MONSTER TALLY", 20, y_value);
  y_value+=20;
  text ("   50                   50                   0       ", 20, y_value);
  y_value+=50;
  text ("All you have to do now, as you progress through the castle, aided only by your quick decisions, is survive. \n"
    +"You'll find that you can take part in this adventure several times, as the outcome will be different each time.\nKeep a "
    +"record of your final score, and see if you can better it each time you go exploring.", 
    20, y_value, 
    width-40, 200);
  y_value+=220;
  text ("Click mouse. ", 120, y_value);
}

void play() {  

  // that's the main part. It's from PhiLho from the forum. 

  fill(#004499);
  textSize(20);
  text(currentLine.line, 10, 30, width-30, 360);

  // Display the choice of answers
  fill(#0077EE);
  textSize(15);
  int x = 145; 
  int y = 590;
  int i=0; 

  myCircleButtons.clear();
  for (String ch : currentLine.choices) {
    String [] myArray = split(ch, "#");

    // Define buttons 

    int myCircleSize = 200; //
    // we define on Which State Is This Button Visible for each button separately 
    //int onWhichStateIsThisButtonVisible=0; 
    // color - color when mouse is NOT over this botton 
    color myColor = color(0, random(255), random(255));  //

    // define button and put it into the array 
    // change buttons individually: 
    // define individual values
    myColor = color(255, 120, 0);  // color
    // make new button and pass the values to it
    myCircleButtons.add( new CircleButton(
      x, // x-value position 
      y, // y-value position 
      myCircleSize, // size 
      myColor, // color
      myArray[0], // its text  
      i     // the state it leads to when clicked !!!!! 
      ));

    /*   text(toChoose++ 
     + ": " 
     + myArray[0], 
     23, y);*/
    x += 254;  // next line
    i++;
  }

  // for testing: 
  text (globalSectionNumber, width-30, height-30);

  // cool way of a for-loop (for **each** button (of type CircleButton) in the array myCircleButtons do the following) - see reference
  for (CircleButton button : myCircleButtons) { 
    button.update();
  }//for

  /* 
   // Display the history of the curent game
   // (this could be an extra state of the program)
   fill(#0055AA);
   textSize(12);
   y = 200;
   for (String line : dialog)
   {
   // println (line);
   text (line, 20,y );
   y += 20;
   }
   println ("----------------------");
   */
}

// inputs ---------------------------------------------------------

void keyPressed() {

  // states: 
  switch(state) {

  case startScreen:
    // start the game 
    state=play;
    break;

  case play:
    //
    break;

  default:
    //error
    println ("unknown state line 148");
    exit();
    break;
  } // switch
  //
}//func 

void mousePressed() {
  // states: 
  switch(state) {

  case startScreen:
    state=play;
    break;  

  case play:
    // Display the history of the curent game
    // (this could be an extra state of the program)
    // fill(#0055AA);
    // textSize(12);
    //  y = 200;

    mousePressed2();

    /*
    println ("----------------------");
     for (String line : dialog) {
     println (line);
     //text (line, 20,y );
     //y += 20;
     }
     println ("----------------------");
     */
    break;

  default:
    //error
    println ("unknown state line 1480 in mousePressed()");
    exit();
    break;
  } // switch
} 

// -------------------------------------------------------------------------
// Input functions 

void mousePressed2() {
  for (CircleButton button : myCircleButtons) {    // cool way of a for-loop (for **each** button (of type CircleButton) in the array myCircleButtons do the following)
    // if (state == button.shownInWhichState || button.shownInWhichState == ALL_PAGES) {    // only for current state OR for special buttons
    if (button.overCircle()) {     // when mouse on this button
      // normal button : go to new page 
      //prevState=state; // save old state  
      // state=button.stateToGoTo;   // execute 
      interpreteInput(button.numberToChoose);  
      return;      // leave
    }
    //}//if
    //  }//if
  }//for
}//func 


void interpreteInput(int value_) {
  // interprete input

  println("HIT " 
    + value_);

  // get the current number of choices 
  int choiceNb = currentLine.choices.length;

  // get key as a number from 0 to choiceNb
  int choice = value_;
  // println(choice); 

  // Ignore anything BUT numbers
  if (choice < 0 || choice >= choiceNb)
    return; // Ignore: leave function 

  String choiceMade = currentLine.choices[choice];
  String [] myArray = split(choiceMade, "#");  

  String choiceId = "<No Text.>";
  if (1<myArray.length) {
    choiceId = myArray[1];
  }

  globalSectionNumber = choiceId;

  DialogLine chosenAnswer = dialogTree.get(choiceId);
  if (chosenAnswer != null) {
    currentLine = dialogTree.get(choiceId);
    dialog.add(currentLine.line);
  }
}//func 

// ====================================================================
// here starts a class

/**
 * A dialog line: an id, the line (text) itself, and a list of choices,
 * ie. of possible answers to this line.
 */
class DialogLine {
  String id;
  String line;
  String[] choices;  // list 

  //constructor 
  DialogLine(String i_, String l_, String... c_) {
    id = i_;
    line = l_;
    choices = c_;
  }//constructor

  String toString() {
    return id
      + " - "
      + line 
      + " (" 
      + choices.length 
      + ")";
  }//method
} // class 
//

// ======================================================================== 
// line to show: here starts a class

class CircleButton {

  int circleX, circleY;  // Position of circle button
  int circleSize;     // Diameter of circle

  String text; 

  color circleColor = color(255, 0, 0);  // RED when over!!!!!!!!!!!!!!!
  color baseColor;  // when not over - gets defined in the constructor

  // boolean circleOver = false; // not really in use, never mind 

  // functionality
  int numberToChoose;

  // constructor
  CircleButton(int posX_, int posY_, // linebreaks for better readability. Marking parameters with a _ sign (like posX_). 
    int theSize_, 
    color baseColor_, 
    String text_, 
    int numberToChoose_) { 
    // constructor 
    circleX = posX_;
    circleY = posY_;
    circleSize = theSize_;
    baseColor = baseColor_;
    numberToChoose=numberToChoose_;
    text=text_;

    ellipseMode(CENTER);
  }// constructor

  void update() {    
    // make use of circleColor and  baseColor
    if (overCircle()) {
      fill( circleColor ); // over 
      stroke(255);
    } else {
      fill( baseColor ); // not over
      noStroke();
    }
    // ellipse(circleX, circleY,       circleSize, circleSize);
    rect( circleX, circleY, 
      circleSize, circleSize-50);

    fill(255);
    textAlign(LEFT);
    textSize(22);
    text(text, 
      circleX+6, circleY, 
      circleSize-20, 900);
    //reset
    textAlign(LEFT);
  }//method

  boolean overCircle() { 
    return 
      mouseX>circleX  && 
      mouseX<circleX+circleSize && 
      mouseY>circleY && 
      mouseY<circleY+circleSize-50;
  }//method

  void printlnProperties() {
    //
    println (text 
      +"\t"
      + numberToChoose);
  }//method
  //
}//class // marking the end of the class 
//

Hey! i was seeing the code above but i dont understand what this part means:

boolean isPointInRectangle(float px, float py,
float rx, float ry,
float rw, float rh) {
if (px >= rx &&
px <= rx + rw &&
py >= ry &&
py <= ry + rh) {
return true;
}
return false;
}

Can anyone help me? Im trying to do something similar (have different scenes and change with a button) but im having troubles with that.

Thanks a lot!

1 Like

This function tells you whether a point (p) is inside a rectangle (r).

  • The variables starting with p mean point… something, the variables with r mean rectangle.

The function returns true or false.

It is to detect whether the mouse is on the button.

it checks if

  • the point’s X is bigger than the upper left corner X (rx) and
  • smaller than the lower right corner X (rx + rw) and
  • same for y

Chrisir

1 Like

Great! Thanks a lot!

Hey again, im sorry, i hope this is the last question of this that i have hah.

I want to understand why there are two different types of screen/scene: for one part the initScreen, gameScreen and for the other scene01, scene02, scene03.

I understand the initScreen but for what do you have the gameScreen?

Thanks a lot