Switching between scenes with buttons as choices

// 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 
//