Basic UI Logic programing is killing me

edited September 2015 in Questions about Code

Hi there.

I am in one of those logic-dark-hole that as been creeping me my whole programers life. Must be a missing piece in my brain. So I'm going to try to explain.

  • I make an Intro Menu where I will have 2 buttons.
  • Built a Button Class and a IntroMenu Class, and I call the IntroMenu Class from draw, when I am in Intro STATE
  • the thing is, I want my Buttons to be animated, like slidding into the screen when appearing, and slidding of the screen when the choice as been done.

Here is my problem:

  • Everything works fine but when my Buttons have finished their slidding out... THEY COME BACK !!
  • Of course I can prevent that by initiating a "change State" as the result of the IntroMenu action, and therefor not calling my IntroMenu instance anymore, but I don't want that (because my "change state" thing is animated too).
  • So I need my IntroMenu to be "ON" when I call it, "OFF" when I have done my choice and the Buttons are gone, BUT ready anyway for the next time I will call It !

ps: do you guys have logic-dark-holes too ? Is there a group I can join ? ;)

pps: I have the code, I can post it but I'm so afraid it would make it even more confusing

Tagged:

Answers

  • You should try to boil your problem down to an MCVE. Don't post your whole code, but try to create a small self-contained example that demonstrates the problem.

  • do you guys have logic-dark-holes too ? Is there a group I can join ?

    Most people that ask questions have their own logic-dark-holes so you have already joined the right group. ;)

    It seems to me that you are already on the right track with using states. I can see the need for 4 states

    1) Menu OFF
    2) Buttons slide ON
    3) Menu ON
    4) Buttons slide OFF

    State changes
    1 > 2 under program control
    2 > 3 sliding buttons reach final display position
    3 > 4 user makes selection from available buttons
    4 > 1 sliding buttons reach final off-screen positions

  • you have states of the program IntroMenu, Game and so on

    and in the class Button you can have another set of state which is standStill, isMoving, hasDissapeared

    both states are totally independent

  • Thank you for answering :) and specially for making me feel that I'm not alone in those darks holes :]

    So I read all your answers and, it looks like what I have been doing so far. And my brain is so much saturated that I just feel like showing you this.

    int ZEROSTATE    = 0;
    int MENUSTATE    = 1;
    int state = ZEROSTATE; // default state
    
    IntroUI introMn;
    String IntroMenuOutPut = "";
    
    void setup() {
      size(300, 200);
      introMn = new IntroUI ();
    }
    
    void draw () {
      background(0);
    
        if (state == ZEROSTATE) {
        fill(255);
        textAlign(CENTER, CENTER);
        text("push 1", width/2, 10);
        println("0");
      }
    
      if (state == MENUSTATE) {
        fill(255);
        textAlign(CENTER, CENTER);
        text("onSTATE", width/2, 10);
        //****************************************RUN MENU UI
        introMn.run();
    
        if (IntroMenuOutPut == "start") {
          //do the thing
          state = ZEROSTATE;
          println("switched back to ZEROSTATE");
        } else  if (IntroMenuOutPut == "edit") {
          //do the edit thing
        } else  if (IntroMenuOutPut == "escape") {
          //do the edit thing
          println("escape back to ZEROSTATE");
          state=ZEROSTATE;
        }
        IntroMenuOutPut = "";
      }
      //*****************************************END OF RUN MENU UI
    }
    
    void  keyPressed() {
      if (key == '1') {
        state=MENUSTATE;
      }
    }
    
    /////////////////////////////
    // Intro MENU Class
    /////////////////////////////
    
    class IntroUI {
      boolean doOnce;
      /////////////////////////// VARIABLES
      // possible outPuts
      int opStart = 1;
      int opEdit  = 2;
      int opEsc   = 3;
      //
      int outPut = 0; 
      // Buttons
      Button start_button;     // the start button
      Button edit_button;      // the edit button
      //
      boolean start_ButtonPressed = false;
      boolean edit_ButtonPressed = false;
      //
      boolean uiON; 
    
    
      /////////////////////////// CONSTRUCTOR
      IntroUI() {
        // last int = "from where comes the button?" 1 = top, 2 Right, 3 Bottom, 4 Left
        //  start_button = new Button("START", ((width/8)*1)+25, height/2, 60, 50, 3);
        //  edit_button = new Button("EDIT", ((width/8)*3)+25, height/2, 60, 50, 1);
        //
        start_button = new Button("START", ((width/8)*1)+25, height/2, 60, 50, 4);
        edit_button = new Button("EDIT", ((width/8)*3)+25, height/2, 60, 50, 2);
      }
      /////////////////////////// FUNCTIONS
    
      void run () {
    
        if ( !start_button.choiceDone() || !edit_button.choiceDone()) {
          //1. start all buttons**************************
          start_button.run();
          edit_button.run();
          clickTracker();//
          keyTracker();
          //println("running");
        } else {
          println("choiceDONE");
          //2. reset all buttons**************************
          start_button.reset();
          edit_button.reset();
          //turn the damned thing Off  !!
    
          //3. get MENU result and put it in global variable********
          if (outPut == opStart) {
            IntroMenuOutPut = "start";
            println("start !");
          } else  if (outPut == opEdit) {
            IntroMenuOutPut = "edit";
          } else  if (outPut == opEdit) {
            IntroMenuOutPut = "escape";
          }
        }
      }
    
      void clickTracker() {
        //on mouse pressed
        if (mousePressed && doOnce == false) {
          if (mouseButton == LEFT) {
            //start**************************
            if (start_button.mouseOver()) {
              start_ButtonPressed = true;
              //println("push");
            } else {
              start_ButtonPressed = false;
            }
            //edit**************************
            if (edit_button.mouseOver()) {
              edit_ButtonPressed = true;
              //println("push");
            } else {
              edit_ButtonPressed = false;
            }
          } else if (mouseButton == RIGHT) {
          } else if (mouseButton == CENTER) {
          }
          doOnce = true;
        }
    
        //on "mouse release
        if (mousePressed == false && doOnce == true) {
          //start**************************
          if (start_button.mouseOver()) {
            if (start_ButtonPressed) {
              //wipe all buttons
              //println("release");
              start_button.wipe();
              edit_button.wipe();
              outPut = opStart;
            }
          }
          //edit**************************
          if (edit_button.mouseOver()) {
            if (edit_ButtonPressed) {
              //wipe all buttons
              //println("release");
              edit_button.wipe();
              start_button.wipe();
              outPut = opEdit;
            }
          }
          doOnce = false;
        }
      }
    
      void keyTracker() {
        if (keyPressed == true) {
          if ( key == '0') {
            start_button.wipe();
            edit_button.wipe();
            outPut = opEsc;
          }
        }
      }
    }
    
    /////////////////////////////
    // Button Class
    /////////////////////////////
    class Button {
      String label;
      float x;    // top left corner x position
      float y;    // top left corner y position
      float w;    // width of button
      float h;    // height of button
      color buttonColor = color(255);
      //translate of the button
      int side;
      float X;
      float Y;
      //chrono
      int startTime;
      int stopTime;
      int duration = 350;
      //sin movement
      float angle = 0.0;
      float p ;
      float offset;
      //logicstuff
      boolean IN = false;   // means the button is IN place
      boolean OUT = false;  // means the button is OUT, gone
      boolean scrollDone = false; // means the scroll movement (in or out) is finished
      boolean goIn = false; // means the scrollIn has been initiated
      boolean goOut = false;// idem for scrollOut
    
      /////////////////////////////CONSTRUCTOR
      Button(String _label, float xpos, float ypos, float _width, float _height, int _side ) {
        label = _label;
        x = xpos;
        y = ypos;
        w = _width;
        h = _height;
        //add from "from where ?" 1 = top, 2 Right, 3 Bottom, 4 Left
        side = _side;
        buttonColor = color(255);
      }
      /////////////////////////////FUNCTIONS
    
      //OPEN THE BUTTON
      //run sets the button up by 1) scrolling In and 2) activate it
      void run () {
        autoBall();
        if (goIn == true || goOut == true || IN == true) {
          display();
        } 
        if (IN == false) {
          //----------------------->scrollIn
          if ( goIn == false) {
            goIn = true;
            //goOut = false;
            //////////////////
            //parameters for one way IN, depending on where from
            if (side == 1) {//-----------------------TOP
              offset = -height - y;
            } else if (side == 2) {//----------------RIGHT
              offset = width + x;
            } else if (side == 3) {//----------------BOTTOM
              offset = y + height ;
            } else if (side == 4) {//----------------LEFT
              offset = -width - x;
            }
            p = offset; 
            /////////////////
            clock();   //TRIGGER
          }
        } else {
          mouseOver();
        }
        //println(  "goIn: " + goIn + " / IN: " + IN + " / goOut: " + goOut + " / out: " + OUT);
      }
    
      //CLOSES THE BUTTON
      //get ride of the button (scrolling Out)
      void wipe() {
        //IN = false;
        if (OUT == false) {
          //-----------------------<scrollOut
          if ( goOut == false) {
            goIn = false; 
            goOut = true;
            /////////////
            if (side == 1) {//-----------------------TOP
              offset = (height*-1) - y ;
            } else if (side == 2) {//----------------RIGHT
              offset = x + width ;
            } else if (side == 3) {//----------------BOTTOM
              offset = y + height ;
            } else if (side == 4) {//----------------LEFT
              offset = -width - x;
            }
            p = offset;
            /////////////
            clock();   //TRIGGER
          }
        }
      }
    
      //choice done is true if the button has been SCROOLED OUT
      boolean choiceDone() {
        return OUT;
      }
    
      //resets the parameters for restarts
      void reset() {
        if (OUT) {
          buttonColor = color(255);
          IN = false;  
          goOut = false;
          goIn = false;
          OUT = false;
        }
      }
    
      ////////////////////////////////////////////////
      ///////////////////////////////internal methodes
      ////////////////////////////////////////////////
    
      void display() {
        pushMatrix();
        translate(X, Y);
        fill(buttonColor);
        stroke(141);
        rect(x, y, w, h, 5);
        textAlign(CENTER, CENTER);
        fill(0);
        text(label, x + (w / 2), y + (h / 2));
        popMatrix();
      }
    
      boolean mouseOver() {
        if (mouseX > x && mouseX < (x + w) && mouseY > y && mouseY < (y + h)) {
          buttonColor = color(255, 63, 63);
          return true;
        }
        buttonColor = color(255);
        return false;
      }
    
      void clock() {
        startTime = millis();
        stopTime = startTime + duration;
      }
    
      void autoBall() {
        //parameters for one way IN, depending on where from
        if (goIn) {
          if (side == 1) {//-----------------------TOP
            X = 0;
            Y = p + 1  ;
          } else if (side == 2) {//----------------RIGHT
            X = p;
            Y = 0;
          } else if (side == 3) {//---------------BOTTOM
            X = 0;
            Y = p - 1;
          } else if (side == 4) {//----------------LEFT
            X = p;
            Y = 0;
          }
        } else if (goOut) {
          //parameters for one way OUT, depending on where from originaly
          //to invert the motion we keep the same offset value 
          //but Y (or X) = offset-p
          if (side == 1) {//-----------------------TOP
            X = 0;
            Y = offset - p;
          } else if (side == 2) {//----------------RIGHT
            X = offset - p;
            Y = 0;
          } else if (side == 3) {//----------------BOTTOM
            X = 0;
            Y = offset - p;
          } else if (side == 4) {//----------------LEFT
            X = offset - p;
            Y = 0;
          }
        }
        //this part does the actual movement
        if (scrollDone != true) {
          if  (millis () < stopTime) {
            // so angle must be between -PI/2 and -PI
            angle = map(millis(), startTime, stopTime, -PI/2, PI/2);
            float sinval = sin(angle);
            //then I want normSin to be from 0 to 1
            float normSin = (sinval +1)/2;
            p = map(normSin, 0, 1, offset, 0);
            //println(" p : " + p);
          } else {
            scrollDone = true;
          }
        }
        //this tell what happen when movement is done
        if (scrollDone) {
          if (goIn == true) {
            IN = true;
          }
          if (goOut == true) {
            OUT = true;
          }
          scrollDone =false;
        }
      }
    }
    
  • use final

    final int ZEROSTATE    = 0;
    final int MENUSTATE    = 1;
    int state = ZEROSTATE; // default state
    
  • edited August 2015

    Just some little tips:

    • In Java's convention, and many other languages, all caps names are for constant fields.
    • Both ZEROSTATE & MENUSTATE are assigned some value and they stay that way till the end.
    • Therefore we should declare them as final. And it's advisable as static as well.
    • static final int ZEROSTATE = 0, MENUSTATE = 1;
    • However, you've got variables IN & OUT in all caps. But they aren't constants!
    • So you should rename them to use lowerCamelCase instead! ;)
  • I guess this is causing you headache

      //logicstuff
      boolean IN = false;   // means the button is IN place
      boolean OUT = false;  // means the button is OUT, gone
      boolean scrollDone = false; // means the scroll movement (in or out) is finished
      boolean goIn = false; // means the scrollIn has been initiated
      boolean goOut = false;// idem for scrollOut
    

    only one of them can be true at a time

    so just make a state out of it like

    final int ZEROSTATE    = 0;
    final int MENUSTATE    = 1;
    int state = ZEROSTATE; // default state
    
  • ah, I see I have written this above already

    ;-)

  • guys, is it possible to turn crazy by giving everything you have at a stupid logic problem ? Because if yes, then this is about to happen to me :( please HELP

    static final int ZEROSTATE    = 0;
    static final int BUTTONSTATE    = 1;
    int state = ZEROSTATE; // default state
    
    IntroUI introMn;
    String IntroMenuOutPut = "";
    
    void setup() {
      size(300, 200);
      introMn = new IntroUI ();
    }
    
    void draw () {
      background(0);
    
      if (state == ZEROSTATE) {
        fill(255);
        textAlign(CENTER, CENTER);
        text("push 1", width/2, 10);
      }
    
      if (state == BUTTONSTATE) {
        fill(255);
        textAlign(CENTER, CENTER);
        text("onSTATE", width/2, 10);
        //****************************************RUN BUTTON UI
        introMn.run();
        if (IntroMenuOutPut == "start") {
          //do the thing
          state = ZEROSTATE;
          println("switched back to ZEROSTATE");
        } else  if (IntroMenuOutPut == "cancel") {
          println("cancelled");
        }
        //*****************************************END OF BUTTON MENU UI
      }
    }
    
    void  keyPressed() {
      if (key == '1') {
        state=BUTTONSTATE;
      }
    }
    
    /////////////////////////////////////
    //////////////////////////////Classes
    /////////////////////////////////////
    class Button {
      String label;
      float x;    // top left corner x position
      float y;    // top left corner y position
      float w;    // width of button
      float h;    // height of button
      color buttonColor = color(255);
      //translate of the button
      int side;
      float X;
      float Y;
      //chrono
      int startTime;
      int stopTime;
      int duration = 350;
      //sin movement
      float angle = 0.0;
      float p ;
      float offset;
      // logicstuff
      static final int READY     = 0;
      static final int MOVINGIN  = 1;
      static final int IN        = 2;
      static final int MOVINGOUT = 3;
      static final int OUT       = 4;
      int buttonState = READY;
    
      boolean doOnce     = false;
      boolean wiped      = false;
      boolean clicked    = false;
      boolean scrollDone = false;
    
      /////////////////////////////CONSTRUCTOR
      Button(String _label, float xpos, float ypos, float _width, float _height, int _side ) {
        label = _label;
        x = xpos;
        y = ypos;
        w = _width;
        h = _height;
        //"from where does the button comes ?" 1 = top, 2 Right, 3 Bottom, 4 Left
        side = _side;
        buttonColor = color(255);
      }
      ////////////////////////////////////////////////////////////////////////////
      //////////////////////////////   RUN    ////////////////////////////////////
      ////////////////////////////////////////////////////////////////////////////
    
      void run() {
        // keyTracker() ;
        autoBall();
        fill(255);
        text(p, width/2+100, 50);
    
        println("buttonState : " + buttonState + " | doOnce : "
          + doOnce + " | scrollDone : " + scrollDone);
    
        if (buttonState == READY) {  //************************  0
          //wait for trigger and when you get it, SHOT to MOVINGIN!
          if (doOnce == false) {
            if (side == 1) {//-----------------------TOP
              offset = -height - y;
            } else if (side == 2) {//----------------RIGHT
              offset = width + x;
            } else if (side == 3) {//----------------BOTTOM
              offset = y + height ;
            } else if (side == 4) {//----------------LEFT
              offset = -width - x;
            }
            p = offset; 
            scrollDone = false;
            clock();   //TRIGGER
            buttonState = MOVINGIN;
          }
        }
    
        if (buttonState == MOVINGIN) {  // *****************  1
          display();
          if (scrollDone) {
            buttonState = IN;
          }
        }
        if (buttonState == IN) {  //************************  2
          display();
          mouseOver();
          //println("IN");
          //wait for Click or Wipe order
          if ( clicked || wiped ) {
            println("CLICKED");
            wiped = false;
            clicked = false;
            /////////////
            if (side == 1) {//-----------------------TOP
              offset = (height*-1) - y ;
            } else if (side == 2) {//----------------RIGHT
              offset = x + width ;
            } else if (side == 3) {//----------------BOTTOM
              offset = y + height ;
            } else if (side == 4) {//----------------LEFT
              offset = - width - x;
            }
            p = offset;
            clock();   //TRIGGER
            scrollDone = false;
            buttonState = MOVINGOUT;
          }
        }
    
        if (buttonState == MOVINGOUT) {  //*******************  3
          display();
          if (scrollDone) {
            buttonState = OUT;
          }
        }
    
        if (buttonState == OUT) {   //************************  4
          doOnce = false;
        }
      }
    
      ////////////////////////////////////////////////////////////////////////////
      /////////////////////////////   END OF RUN   ///////////////////////////////
      ////////////////////////////////////////////////////////////////////////////
    
      boolean choiceDone() {
        if (buttonState == OUT) {
          scrollDone = false;
          return true;
        } else {
          return false;
        }
      }
    
      void wipe() {
        wiped = true;
      }
      void click() {
        clicked = true;
      }
    
      ////////////////////////////////////////////////
      ///////////////////////////////internal methodes
      ////////////////////////////////////////////////
    
      void display() {
        //  println("display");
        pushMatrix();
        translate(X, Y);
        fill(buttonColor);
        stroke(141);
        rect(x, y, w, h, 5);
        textAlign(CENTER, CENTER);
        fill(0);
        text(label, x + (w / 2), y + (h / 2));
        popMatrix();
      }
    
      boolean mouseOver() {
        if (mouseX > x && mouseX < (x + w) && mouseY > y && mouseY < (y + h)) {
          buttonColor = color(255, 63, 63);
          return true;
        }
        buttonColor = color(255);
        return false;
      }
    
      void clock() {
        //println("CLOCK");
        startTime = millis();
        stopTime = startTime + duration;
      }
    
      void autoBall() {
        //parameters for one way iN, depending on where from
        if (buttonState == MOVINGIN) {
          if (side == 1) {//-----------------------TOP
            X = 0;
            Y = p + 1  ;
          } else if (side == 2) {//----------------RIGHT
            X = p;
            Y = 0;
          } else if (side == 3) {//---------------BOTTOM
            X = 0;
            Y = p - 1;
          } else if (side == 4) {//----------------LEFT
            X = p;
            Y = 0;
          }
        } else if (buttonState == MOVINGOUT) {
          //parameters for one way oUT, depending on where from originaly
          //to invert the motion we keep the same offset value 
          //but Y (or X) = offset-p
          if (side == 1) {//-----------------------TOP
            X = 0;
            Y = offset - p;
          } else if (side == 2) {//----------------RIGHT
            X = offset - p;
            Y = 0;
          } else if (side == 3) {//----------------BOTTOM
            X = 0;
            Y = offset - p;
          } else if (side == 4) {//----------------LEFT
            X = offset - p;
            Y = 0;
          }
        }
        //this part does the actual movement
        if (scrollDone != true) {
          //println("SCROLLING");
          if  (millis () < stopTime) {
            // so angle must be between -PI/2 and -PI
            angle = map(millis(), startTime, stopTime, -PI/2, PI/2);
            float sinval = sin(angle);
            //then I want normSin to be from 0 to 1
            float normSin = (sinval +1)/2;
            p = map(normSin, 0, 1, offset, 0);
            //println(" p : " + p);
          } else {
            scrollDone = true;
          }
        }
      }
    }
    
    
    //////////////////////////////////////////UI
    
    class IntroUI {
      boolean doOnce;
      Button start_button;  // the start b
      boolean start_ButtonPressed = false;
      //
      int opStart = 1;
      //
      int outPut = 0; 
    
      /////////////////////////// CONSTRUCTOR
      IntroUI() {
        // last int = "from where comes the button?" 1 = top, 2 Right, 3 Bottom, 4 Left
        start_button = new Button("START", ((width/8)*1)+25, height/2, 60, 50, 1);
      }
    
      /////////////////////////// FUNCTIONS
      void run() {
        if ( !start_button.choiceDone()) {
          //start all buttons**************************
          start_button.run();
          clickTracker();//
          keyTracker();
    
    
        } else {
          // get MENU result and put it in global variable********
          if (outPut == opStart) {
            IntroMenuOutPut = "start";
            //println("start !");
          } else {
            IntroMenuOutPut = "cancel";
            //println("cancel");
          }
        }
    
      }
    
      void clickTracker() {
        //on mouse pressed
        if (mousePressed && doOnce == false) {
          if (mouseButton == LEFT) {
            if (start_button.mouseOver()) {
              start_ButtonPressed = true;
            } else {
              start_ButtonPressed = false;
            }
          } else if (mouseButton == RIGHT) {
          } else if (mouseButton == CENTER) {
          }
          doOnce = true;
        }
        //on "mouse release
        if (mousePressed == false && doOnce == true) {
          if (start_button.mouseOver()) {
            if (start_ButtonPressed) {
              start_button.wipe();
              outPut = opStart;
            }
          }
          doOnce = false;
        }
      }
    
      void keyTracker() {
        if (keyPressed == true) {
          if ( key == '0') {
            start_button.wipe();
          }
        }
      }
    }
    
  • this code is too long for us to read

    what is your question?

    what does happen now, what do you want it to happen?

    About which line numbers are we talking approx.?

  • edited September 2015
      IntroMenuOutPut = "";
    

    like here

      if (state == BUTTONSTATE) {
        fill(255);
        textAlign(CENTER, CENTER);
        text("onSTATE", width/2, 10);
        //****************************************RUN BUTTON UI
        introMn.run();
        if (IntroMenuOutPut == "start") {
          //do the thing
          state = ZEROSTATE;
          introMn = new IntroUI (); //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
          IntroMenuOutPut = "";     //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
          println("switched back to ZEROSTATE");
        } 
        else  if (IntroMenuOutPut == "cancel") {
          // cancel 
          println("cancelled");
          IntroMenuOutPut = ""; // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        }
        //*****************************************END OF BUTTON MENU UI
      }
    
  • if you run the code you will see:

    • you push the "1" key, the program swtiches to BUTTONSTATE and the button comes in
    • you click the button, the button goes away and the program gets back to ZEROSTATE
    • But now when you push "1" again, the button doesn't come.

    on the other side,

    • you push the "1" key, the program swtiches to BUTTONSTATE and the button comes in
    • if instead of clicking you push the "0" button, the button goes away
    • But now the program keeps println "cancelled".

    What I want is

    • calling the UI (introMn.run();)

      let the buttons pop in waits for an action (click or key) pop back out when one of those actions as been performed inform me what the result is (click or key or else) get ready for my next call (introMn.run();)

    • but beside that, what I want is just to make the most obvious/common/normal UI in the world. Launch a menu, the menu appears, you select or escape, the menu disappears ! I've seen this 10 000 times. What is the mystery behind that ? (I might sound a bit hard but I've been banging my head on this for like 5 days now :( )

  • edited September 2015

    also in the button constr say

        X=x = xpos;
        Y=y = ypos;
    

    to reset X and Y as well

    also, when going back, say

          state = ZEROSTATE;
          introMn = new IntroUI (); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
    

    this new IntroUI() is time consuming. Alternatively, check which var you forgot to reset in the class introMn when restarting with state = ZEROSTATE;

    The fact that

    introMn = new IntroUI (); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
    

    is necessary atm shows that you need to reset comething in that class.

    keyPressed

    also keyPressed: in the long run: make it state-sensitive as well

    void  keyPressed() {
      if (state == ZEROSTATE) {
        if (key == '1') {
          state=BUTTONSTATE;
        }
      }
    }
    

    switch

    I'd also recommend to use switch(state) where you have if...else if.... now

    or switch(buttonState) as well

    ;-)

  • edited September 2015

    core idea

    the core idea is that you need to reset everything when entering a state, especially when this state (or this button) has been used already

    Mouse

    also you run clickTracker from run in the button class.

    it could be better to clickTracker from the main func (in the sense that it is outside the class like setup and draw) and call it from mousePressed or mouseClicked.

  • edited September 2015

    I just read your comment

    you wrote

    if you run the code you will see:

    • you push the "1" key, the program swtiches to BUTTONSTATE and the button comes in
    • you click the button, the button goes away and the program gets back to ZEROSTATE
    • But now when you push "1" again, the button doesn't come.

    if you run the code..... yes, that's what takes so long, therefore it's better to write which line numbers you want....

    but that I've solved

    you wrote

    • if instead of clicking you push the "0" button, the button goes away
    • But now the program keeps println "cancelled".

    look into what happens:

    wipe gets called, wiped gets true and never resetted (!!!)

    but wiped is treated like clicked in if ( clicked || wiped ) {

    so finally IntroMenuOutPut = "cancel"; happens in run

    you have to clear that up. Not sure what you want there. When the button wipes... it moves out of the screen and results in IntroMenuOutPut = "cancel"; ?

  • I don't know what wipe means or what you want with it

    why not ignore key "0" ?

  • Hi Chrisir and thank you for your efforts

    Is it supposed to be that complicated ? I mean what is more generic in programming than making a button ? I'll try (like for the hundredth time) to brake it down again.

    A button as 5 states:

      static final int READY     = 0;  // if if button Obj is called, he'll start movingin
      static final int MOVINGIN  = 1;  // the button slides to his proper position
      static final int IN        = 2;  // button runs his mouseOver methode (is active)
      static final int MOVINGOUT = 3; // button as been clicked and is moving out of the screen
      static final int OUT       = 4; // button is out of the screen and even though the object is still called by Main, the Button Does't slide back in
    

    then, when I will call my button again, I will need it to be in READY state, not OUT state

    --

  • So in the constr of the class say state=READY;

    Or make a method reset and call it when you enter the state intromenu in draw()

    You know, we have to tell a Computer step by step what to do

    It all comes with practice

    You're almost there

  • And why do you have wiped??

    This violates your clean Button States?

  • boolean wiped; is like boolean clicked; when I have a UI with more than 1 button, the buttons goes away if:

    • the button has been clicked
    • the button has been asked to go away (wiped) by the UI

    ps: I took a week of this very piece of code to calm down on this, but now I get back to it and still I miss the trick

  • What feature are you missing, it's working now.

  • The missing feature is this:

    • I need the UI to launch again the next time I'll push "1"

    but also

    • I need the UI to keep being "OUT" when is finished.

    I need this because if I need to switch out of the BUTTONSTATE to stop the UI to come on screen, I will get problems.

    • so what I think is good for my UI Class is that I can launch it, use it, and have it out of my way once I've used it, letting me play with my game states as I wish (to help you understand why I want that, the result of the UI may launch different kinds of transitions (Classes), that may take different time to switch state...)
  • I think wiped is currently the main problem since it is the same as

    buttonState = MOVINGOUT;

  • ok but MOUVINGOUT is a state, wiped is a trigger

  • can you post your entire code with my changes

  • ok, you don't use click and clicked....

    I think it's the same as wiped

  • it's pretty much the same, I tried putting state=READY in the constructor, didn't change a thing, then I tried using a reset(); methode... didn't get better.

    here is where I'm at:

    static final int ZEROSTATE    = 0;
    static final int BUTTONSTATE    = 1;
    int state = ZEROSTATE; // default state
    
    IntroUI introMn;
    String IntroMenuOutPut = "";
    
    void setup() {
      size(300, 200);
      introMn = new IntroUI ();
    }
    
    void draw () {
      background(0);
    
      if (state == ZEROSTATE) {
        fill(255);
        textAlign(CENTER, CENTER);
        text("push 1", width/2, 10);
      }
    
      if (state == BUTTONSTATE) {
        fill(255);
        textAlign(CENTER, CENTER);
        text("onSTATE", width/2, 10);
        //****************************************RUN BUTTON UI
        introMn.run();
        if (IntroMenuOutPut == "start") {
          //do the thing
          state = ZEROSTATE;
          println("switched back to ZEROSTATE");
        } else  if (IntroMenuOutPut == "cancel") {
          println("cancelled");
        }
        //*****************************************END OF BUTTON MENU UI
      }
    }
    
    void  keyPressed() {
      if (key == '1') {
        state=BUTTONSTATE;
      }
    }
    
    ///////////////////////////////////////////////////////////////////////
    ///////////////////////////here come the Classes///////////////////////
    ///////////////////////////////////////////////////////////////////////
    
    /////////////////////////////////////////////////////////UI Class
    class IntroUI {
      boolean doOnce;
      Button start_button;  // the start b
      boolean start_ButtonPressed = false;
      //
      int opStart = 1;
      //
      int outPut = 0; 
    
      /////////////////////////// CONSTRUCTOR
      IntroUI() {
        // last int = "from where comes the button?" 1 = top, 2 Right, 3 Bottom, 4 Left
        start_button = new Button("START", ((width/8)*1)+25, height/2, 60, 50, 1);
      }
      /////////////////////////// FUNCTIONS
    
      void run() {
        //start_button.reset();
    
        if ( !start_button.choiceDone()) {
          //1. start all buttons**************************
    
          start_button.run();
          clickTracker();//
          keyTracker();
    
    
        } else {
          //start_button.reset();
          //3. get MENU result and put it in global variable********
          if (outPut == opStart) {
            IntroMenuOutPut = "start";
            //println("start !");
          } else {
            IntroMenuOutPut = "cancel";
            //println("cancel");
          }
        }
    
      }
    
      void clickTracker() {
        //on mouse pressed
        if (mousePressed && doOnce == false) {
          if (mouseButton == LEFT) {
            if (start_button.mouseOver()) {
              start_ButtonPressed = true;
            } else {
              start_ButtonPressed = false;
            }
          } else if (mouseButton == RIGHT) {
          } else if (mouseButton == CENTER) {
          }
          doOnce = true;
        }
        //on "mouse release
        if (mousePressed == false && doOnce == true) {
          if (start_button.mouseOver()) {
            if (start_ButtonPressed) {
              //wipe all buttons
              start_button.wipe();
              outPut = opStart;
            }
          }
          doOnce = false;
        }
      }
    
      void keyTracker() {
        if (keyPressed == true) {
          if ( key == '0') {
            start_button.wipe();
            // outPut = opEsc;
          }
        }
      }
    }
    /////////////////////////////////////////////////END OF UI CLASS
    /////////////////////////////////////////////////BUTTON CLASS
    class Button {
      String label;
      float x;    // top left corner x position
      float y;    // top left corner y position
      float w;    // width of button
      float h;    // height of button
      color buttonColor = color(255);
      //translate of the button
      int side;
      float X;
      float Y;
      //chrono
      int startTime;
      int stopTime;
      int duration = 350;
      //sin movement
      float angle = 0.0;
      float p ;
      float offset;
      // logicstuff
      static final int READY     = 0;
      static final int MOVINGIN  = 1;
      static final int IN        = 2;
      static final int MOVINGOUT = 3;
      static final int OUT       = 4;
      int buttonState = READY;
    
      boolean doOnce     = false;
      boolean wiped      = false;
      boolean clicked    = false;
      boolean scrollDone = false;
    
      /////////////////////////////CONSTRUCTOR
      Button(String _label, float xpos, float ypos, float _width, float _height, int _side ) {
        label = _label;
        x = xpos;
        y = ypos;
        w = _width;
        h = _height;
        //"from where does the button comes ?" 1 = top, 2 Right, 3 Bottom, 4 Left
        side = _side;
        buttonColor = color(255);
        //state=READY;
      }
    
      //////////////////////////////   RUN
      void run() {
        // keyTracker() ;
        autoBall();
        fill(255);
        text(p, width/2+100, 50);
    
        println("buttonState : " + buttonState + " | doOnce : "
          + doOnce + " | scrollDone : " + scrollDone);
    
        if (buttonState == READY) {  //************************  0
          //wait for trigger and when you get it, SHOT to MOVINGIN!
          if (doOnce == false) {
            if (side == 1) {//-----------------------TOP
              offset = -height - y;
            } else if (side == 2) {//----------------RIGHT
              offset = width + x;
            } else if (side == 3) {//----------------BOTTOM
              offset = y + height ;
            } else if (side == 4) {//----------------LEFT
              offset = -width - x;
            }
            p = offset; 
            scrollDone = false;
            clock();   //TRIGGER
            buttonState = MOVINGIN;
          }
        }
    
        if (buttonState == MOVINGIN) {  // *****************  1
          display();
          if (scrollDone) {
            buttonState = IN;
          }
        }
        if (buttonState == IN) {  //************************  2
          display();
          mouseOver();
          //println("IN");
          //wait for Click or Wipe order
          if ( clicked || wiped ) {
            println("CLICKED");
            wiped = false;
            clicked = false;
            /////////////
            if (side == 1) {//-----------------------TOP
              offset = (height*-1) - y ;
            } else if (side == 2) {//----------------RIGHT
              offset = x + width ;
            } else if (side == 3) {//----------------BOTTOM
              offset = y + height ;
            } else if (side == 4) {//----------------LEFT
              offset = - width - x;
            }
            p = offset;
            clock();   //TRIGGER
            scrollDone = false;
            buttonState = MOVINGOUT;
          }
        }
    
        if (buttonState == MOVINGOUT) {  //*******************  3
          display();
          if (scrollDone) {
            buttonState = OUT;
          }
        }
    
        if (buttonState == OUT) {   //************************  4
          doOnce = false;
          reset();
          //get everything init, BUT don't get to READY YET (or something)
        }
      }
      /////////////////////////////   END OF RUN
    
        void reset() {
        doOnce     = false;
        wiped      = false;
        clicked    = false;
        scrollDone = false;
      }
    
    
      boolean choiceDone() {
        if (buttonState == OUT) {
          scrollDone = false;
          return true;
        } else {
          return false;
        }
      }
    
      void wipe() {
        wiped = true;
      }
      void click() {
        clicked = true;
      }
    
      ////////////////////////////////////////////////
      ///////////////////////////////internal methodes
      ////////////////////////////////////////////////
    
      void display() {
        //  println("display");
        pushMatrix();
        translate(X, Y);
        fill(buttonColor);
        stroke(141);
        rect(x, y, w, h, 5);
        textAlign(CENTER, CENTER);
        fill(0);
        text(label, x + (w / 2), y + (h / 2));
        popMatrix();
      }
    
      boolean mouseOver() {
        if (mouseX > x && mouseX < (x + w) && mouseY > y && mouseY < (y + h)) {
          buttonColor = color(255, 63, 63);
          return true;
        }
        buttonColor = color(255);
        return false;
      }
    
      void clock() {
        //println("CLOCK");
        startTime = millis();
        stopTime = startTime + duration;
      }
    
      void autoBall() {
        //parameters for one way iN, depending on where from
        if (buttonState == MOVINGIN) {
          if (side == 1) {//-----------------------TOP
            X = 0;
            Y = p + 1  ;
          } else if (side == 2) {//----------------RIGHT
            X = p;
            Y = 0;
          } else if (side == 3) {//---------------BOTTOM
            X = 0;
            Y = p - 1;
          } else if (side == 4) {//----------------LEFT
            X = p;
            Y = 0;
          }
        } else if (buttonState == MOVINGOUT) {
          //parameters for one way oUT, depending on where from originaly
          //to invert the motion we keep the same offset value 
          //but Y (or X) = offset-p
          if (side == 1) {//-----------------------TOP
            X = 0;
            Y = offset - p;
          } else if (side == 2) {//----------------RIGHT
            X = offset - p;
            Y = 0;
          } else if (side == 3) {//----------------BOTTOM
            X = 0;
            Y = offset - p;
          } else if (side == 4) {//----------------LEFT
            X = offset - p;
            Y = 0;
          }
        }
        //this part does the actual movement
        if (scrollDone != true) {
          //println("SCROLLING");
          if  (millis () < stopTime) {
            // so angle must be between -PI/2 and -PI
            angle = map(millis(), startTime, stopTime, -PI/2, PI/2);
            float sinval = sin(angle);
            //then I want normSin to be from 0 to 1
            float normSin = (sinval +1)/2;
            p = map(normSin, 0, 1, offset, 0);
            //println(" p : " + p);
          } else {
            scrollDone = true;
          }
        }
      }
    }
    ///////////////////////////////////////////////////////END OF BUTTON CLASS
    
  • when I am in BUTTONSTATE

    and press 0

    what do you want to happen? Button moves out, go back to ZEROSTATE, correct?

  • //simple state / UI demo 
    //
    //to do
    //
    //I'd also recommend to use switch(state) where you have if...else if.... now
    //or switch(buttonState) as well
    //
    
    // states
    // consts 
    static final int ZEROSTATE    = 0;
    static final int BUTTONSTATE  = 1;
    // current 
    int state = ZEROSTATE; // default state
    
    IntroUI introMn;
    String IntroMenuOutPut = "";
    
    void setup() {
      size(300, 200);
      introMn = new IntroUI ();
    }
    
    void draw () {
      background(0);
    
      if (state == ZEROSTATE) {
        fill(255);
        textAlign(CENTER, CENTER);
        text("push 1", width/2, 10);
      } 
      else if (state == BUTTONSTATE) {
        fill(255);
        textAlign(CENTER, CENTER);
        text("onSTATE", width/2, 10);
        //****************************************RUN BUTTON UI
        introMn.run();
        // eval the output 
        if (IntroMenuOutPut == "start") {
          //do the thing
          println("switched back to ZEROSTATE");
          state = ZEROSTATE;   
          introMn = new IntroUI (); //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
          IntroMenuOutPut = ""; // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        } 
        else  if (IntroMenuOutPut == "cancel") {
          // cancel
          println("cancelled");
          println("switched back to ZEROSTATE II.");
          state = ZEROSTATE;
          introMn = new IntroUI (); //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
          IntroMenuOutPut = ""; // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        }
        //*****************************************END OF BUTTON MENU UI
      }
    } // func 
    
    void  keyPressed() {
      if (state == ZEROSTATE) {
        if (key == '1') {
          state=BUTTONSTATE;
        }
      }
    }
    
    ///////////////////////////////////////////////////////////////////////
    ///////////////////////////here come the Classes///////////////////////
    ///////////////////////////////////////////////////////////////////////
    
    /////////////////////////////////////////////////////////UI Class
    class IntroUI {
      boolean doOnce;
      Button start_button;  // the start b
      boolean start_ButtonPressed = false;
      //
      int opStart = 1;
      //
      int outPut = 0; 
    
      /////////////////////////// CONSTRUCTOR
      IntroUI() {
        // last int = "from where comes the button?" 1 = top, 2 Right, 3 Bottom, 4 Left
        start_button = new Button("START", ((width/8)*1)+25, height/2, 60, 50, 1);
        start_ButtonPressed = false;
        opStart = 1;
        outPut = 0; 
        doOnce=false;
      }
      /////////////////////////// FUNCTIONS
    
      void run() {
        //start_button.reset();
    
        if ( !start_button.choiceDone()) {
          //1. start all buttons**************************
    
          start_button.run();
          clickTracker();//
          keyTracker();
        } 
        else {
          //start_button.reset();
          //3. get MENU result and put it in global variable********
          if (outPut == opStart) {
            IntroMenuOutPut = "start";
            //println("start !");
          } 
          else {
            IntroMenuOutPut = "cancel";
            //println("cancel");
          }
        }
      }
    
      void clickTracker() {
        //on mouse pressed
        if (mousePressed && doOnce == false) {
          if (mouseButton == LEFT) {
            if (start_button.mouseOver()) {
              start_ButtonPressed = true;
            } 
            else {
              start_ButtonPressed = false;
            }
          } 
          else if (mouseButton == RIGHT) {
            //
          } 
          else if (mouseButton == CENTER) {
            //
          }
          doOnce = true;
        }
        //on "mouse release
        if (mousePressed == false && doOnce == true) {
          if (start_button.mouseOver()) {
            if (start_ButtonPressed) {
              //wipe all buttons
              start_button.wipe();
              println("wipe");
              outPut = opStart;
            }
          }
          doOnce = false;
        }
      }
    
      void keyTracker() {
        if (keyPressed) {
          if (key == '0') {
            start_button.wipe();
            start_ButtonPressed = true; // !!!!!!!!!!!!!!!! ???? 
            // outPut = opEsc;
          }
        }
      }
    }
    /////////////////////////////////////////////////END OF UI CLASS
    /////////////////////////////////////////////////BUTTON CLASS
    class Button {
      String label;
    
      float x;    // top left corner x position
      float y;    // top left corner y position
      float w;    // width of button
      float h;    // height of button
    
      color buttonColor = color(255); // white 
    
      //translate of the button
      int side;
      float X;
      float Y;
    
      //chrono
      int startTime;
      int stopTime;
      int duration = 350;
    
      //sin movement
      float angle = 0.0;
      float p;
      float offset;
    
      // logicstuff
      static final int READY     = 0; // const 
      static final int MOVINGIN  = 1;
      static final int IN        = 2;
      static final int MOVINGOUT = 3;
      static final int OUT       = 4;
      int buttonState = READY;        // current 
    
      boolean doOnce     = false;
      boolean wiped      = false;
      boolean clicked    = false;
      boolean scrollDone = false;
    
      /////////////////////////////CONSTRUCTOR
      Button(String _label, float xpos, float ypos, float _width, float _height, int _side ) {
        label = _label;
        //    x = xpos;
        //    y = ypos;
        X=x = xpos;
        Y=y = ypos;
        w = _width;
        h = _height;
        //"from where does the button comes ?" 1 = top, 2 Right, 3 Bottom, 4 Left
        side = _side;
        buttonColor = color(255);
        //state=READY;
        reset();
      }
    
      //////////////////////////////   RUN
      void run() {
        // keyTracker() ;
        autoBall();
    
        fill(255);
        text(p, width/2+100, 50);
    
        println("buttonState : " + buttonState + " | doOnce : "
          + doOnce + " | scrollDone : " + scrollDone);
    
        if (buttonState == READY) {  //************************  0
          //wait for trigger and when you get it, SHOT to MOVINGIN!
          if (doOnce == false) {
            if (side == 1) {//-----------------------TOP
              offset = -height - y;
            } 
            else if (side == 2) {//----------------RIGHT
              offset = width + x;
            } 
            else if (side == 3) {//----------------BOTTOM
              offset = y + height ;
            } 
            else if (side == 4) {//----------------LEFT
              offset = -width - x;
            }
            p = offset; 
            scrollDone = false;
            clock();   //TRIGGER
            buttonState = MOVINGIN;
          }
        }
    
        else if (buttonState == MOVINGIN) {  // *****************  1
          display();
          if (scrollDone) {
            buttonState = IN;
          }
        }
    
        else if (buttonState == IN) {  //************************  2
          display();
          mouseOver();
          //println("IN");
    
          //wait for Click or Wipe order
          if ( clicked || wiped ) {
            println("CLICKED");
            wiped = false;
            clicked = false;
            /////////////
            if (side == 1) {//-----------------------TOP
              offset = (height*-1) - y ;
            } 
            else if (side == 2) {//----------------RIGHT
              offset = x + width ;
            } 
            else if (side == 3) {//----------------BOTTOM
              offset = y + height ;
            } 
            else if (side == 4) {//----------------LEFT
              offset = - width - x;
            }
            p = offset;
            clock();   //TRIGGER
            scrollDone = false;
            buttonState = MOVINGOUT;
          }
        }
    
        else if (buttonState == MOVINGOUT) {  //*******************  3
          display();
          if (scrollDone) {
            buttonState = OUT;
          }
        }
    
        else if (buttonState == OUT) {   //************************  4
          //      doOnce = false; // ?????????
          //      reset();
          //get everything init, BUT don't get to READY YET (or something)
        }
      } // method 
      /////////////////////////////   END OF RUN
    
      void reset() {
        doOnce     = false;
        wiped      = false;
        clicked    = false;
        scrollDone = false;
      }
    
      boolean choiceDone() {
        if (buttonState == OUT) {
          scrollDone = false;
          return true;
        } 
        else {
          return false;
        }
      }
    
      void wipe() {
        wiped = true;
      }
      void click() {
        clicked = true;
      }
    
      ////////////////////////////////////////////////
      ///////////////////////////////internal methodes
      ////////////////////////////////////////////////
    
      void display() {
        //  println("display");
        pushMatrix();
        translate(X, Y);
        fill(buttonColor);
        stroke(141);
        rect(x, y, w, h, 5);
        textAlign(CENTER, CENTER);
        fill(0);
        text(label, x + (w / 2), y + (h / 2));
        popMatrix();
      }
    
      boolean mouseOver() {
        if (mouseX > x && mouseX < (x + w) && mouseY > y && mouseY < (y + h)) {
          buttonColor = color(255, 63, 63);
          return true;
        }
        buttonColor = color(255);
        return false;
      }
    
      void clock() {
        //println("CLOCK");
        startTime = millis();
        stopTime = startTime + duration;
      }
    
      void autoBall() {
        //parameters for one way iN, depending on where from
        if (buttonState == MOVINGIN) {
          if (side == 1) {//-----------------------TOP
            X = 0;
            Y = p + 1  ;
          } 
          else if (side == 2) {//----------------RIGHT
            X = p;
            Y = 0;
          } 
          else if (side == 3) {//---------------BOTTOM
            X = 0;
            Y = p - 1;
          } 
          else if (side == 4) {//----------------LEFT
            X = p;
            Y = 0;
          }
        } 
        else if (buttonState == MOVINGOUT) {
          //parameters for one way oUT, depending on where from originaly
          //to invert the motion we keep the same offset value 
          //but Y (or X) = offset-p
          if (side == 1) {//-----------------------TOP
            X = 0;
            Y = offset - p;
          } 
          else if (side == 2) {//----------------RIGHT
            X = offset - p;
            Y = 0;
          } 
          else if (side == 3) {//----------------BOTTOM
            X = 0;
            Y = offset - p;
          } 
          else if (side == 4) {//----------------LEFT
            X = offset - p;
            Y = 0;
          }
        }
        //this part does the actual movement
        if (scrollDone != true) {
          //println("SCROLLING");
          if  (millis () < stopTime) {
            // so angle must be between -PI/2 and -PI
            angle = map(millis(), startTime, stopTime, -PI/2, PI/2);
            float sinval = sin(angle);
            //then I want normSin to be from 0 to 1
            float normSin = (sinval +1)/2;
            p = map(normSin, 0, 1, offset, 0);
            //println(" p : " + p);
          } 
          else {
            scrollDone = true;
          }
        }
      }
    }
    ///////////////////////////////////////////////////////END OF BUTTON CLASS
    
  • nop !

    when I am in BUTTONSTATE and press 0, the UI (buttons) is wiped out... and that's it.

    I'm still in BUTTONSTATE, the buttons are gone (because I did wipe them out) and that's it. Of course I did send the message that the UI was cleared ("cancel") but I didn't YET decide what I want to do.

    What I don't want is to tigh the end of my UI process to something out of it (like state switch)

  • edited September 2015

    how do you like my version?

    It's almost perfect now except for the zero part (when I am in BUTTONSTATE and press 0)

    remark

    you wrote:

    when I am in BUTTONSTATE and press 0, the UI (buttons) is wiped out... and that's it.

    I'm still in BUTTONSTATE, the buttons are gone (because I did wipe them out) and that's it. Of course I did send the message that the UI was cleared ("cancel")

    your explanation won't work.

    Or I didn't get it.

    Because you are still in state BUTTONSTATE but the buttons are gone, the user is stack in the BUTTONSTATE and can't ever leave it.....

    bad.

    or do you want the button to come back after it's been out (in this special case)?

  • I let my brain cool down a bit and get back at it you are really giving me energy, that is really cool :)

  • we'll hunt this one down...

    ;-)

  • :)

    If I get back to the basic, this is how I though things should go (because I didn't find "the proper way" on the net:)

    • 1 in my Main, I manage the states and one of those states is INTROSTATE (I'll have "PauseUI" and other...)
    • 2 when I get to this state it seems to me good to run the IntroUI Object (myIntro.run)
    • 3 and to wait for an answer

    • 4 So my IntroUI object does it's job: A) getting the buttons in B) activating the Button (to catch the click and run the rollover methode) C) getting the buttons out AND returning the answer (which button / key has been pushed)

    • 5 when the answer comes in, the buttons are already out of the screen

    • 6 then I act according to what the answer was, thanks to the code I wrote in the INTROSTATE

    //

    If the answer is "switch to Xstate", ok, the INTROSTATE code won't call the IntroUI Object anymore

    if the answer is, "displayIntroInfo", then I'm still in INTROSTATE, so I don't want to have the UI coming back

    I want the UI to come when I call it, not when I am in INTROSTATE

    also I made it so that myIntro.run is called, only if a parameter "choiceIsDone" is false, but when my "choiceIsDone" , I need to know how to reset this parameter...

    (my brain started to melt again at about the fifth line :S)

    • Right now in my code, the button goes away if I click "Start", and we swtich to ZEROSTATE, but then I cannot call the UI again
    • and if I "wipe" the UI, using for instance "0", the buttons don't come back, which is what I think I want
    • Finally, if I make it so that I can relaunch the UI a second time after I click "Start" (by reseting the whole stuff), when I'll wipe the UI using "0", what will happen is that the button come back right after they cleared the screen

    // I put the keyWaiter and mouseTracker inside UI because I'm afraid to get my main way to clutured once I write all the rest (keep in my that this is just like 5% of my code)

  • in my code you can call the UI again and again clicking start!!!!

  • edited September 2015

    also, I noticed you didn't use one of the things I said previously in your code!

    Why?

    do you test my code at all!?

  • Hello, back to the code after a day of other duties.

    So yes, I did test your code and it does work very well

    but if you comment the state change in line 50, the buttons are coming back if you push "0".

    What about thinking of the IntroUI Class as some kind of "box" that I could:

    • switch ON
    • switch OFF

    and that would return

    • a choice as been made (bool)
    • which button as been pushed (string)

    would it be the way to think about it ? I really wouldn't mind re starting that thing from the begining. specially since I already have all the pieces inside that are working

  • rewriting and restarting sounds good

    introUI class represents a state / screen, right?

    i wouldn't really switch a state off....

    I mean you could switch off buttons but the state...?

    but why not... sure....


    you wrote the the buttons are coming back when you push 0

    the point is that you are not clear here. when you push 0 you escape the state / disable the buttons but stay in the state. Can't work.....

  • Keep me up to date please

    Either re start or serious cleaning up

  • restarting from scratch I'll keep you posted :)

  • Here we are Mr Chrisir

    I think it works, at least it does what I need when implemented in my demo. I still have to make a lot of test but I feel somehow confident.

    This is by far the hardest thing I've done in processing. It took me 2 weeks and it is only with the help of my girlfriend, who doesn't know anything about code but who accepted to spend 2 hours with me in front of the damned thing, that I could make it. I guess for you guys it might sound stupid simple but for me it was a case of give up the coding thing or passing through. I can't believe it is so hard for me.

    I want to thank you Chrisir, specially for that "You're almost there" line you drooped me, it really help me :)

    // states
    // consts 
    static final int ZEROSTATE    = 0;
    static final int BUTTONSTATE  = 1;
    int state = ZEROSTATE; // default state
    
    /*How to use IntroUI:
    1 declare IntroUI Object AND IntroMenuOutPut String
    2 always .rest() the IntroUi Objects before calling .run()
    3 when you get the result, reset the String
    */
    IntroUI introMn;
    String IntroMenuOutPut = "";
    
    void setup() {
      size(300, 200);
      introMn = new IntroUI ();
    }
    
    void draw () {
      background(0);
    
      if (state == ZEROSTATE) {
        fill(255);
        textAlign(CENTER, CENTER);
        text("push 1", width/2, 10);
      } 
      //////////////////////////////////
      else if (state == BUTTONSTATE) {
        fill(255);
        textAlign(CENTER, CENTER);
        text("BUTTONSTATE", width/2, 10);
        //****************************************RUN BUTTON UI
        introMn.run();
        // eval the output 
        if (IntroMenuOutPut == "start") {
          //do the thing
          println("MAIN: start!");
          state = ZEROSTATE; 
       // println("rr: " + IntroMenuOutPut); // STRANGE that that code is executed
          IntroMenuOutPut = ""; 
       //   println("tt: " + IntroMenuOutPut);
        } else  if (IntroMenuOutPut == "cancel") {
          // cancel !! DO SOMETHING
          println("MAIN: canceled // push '9'");
          IntroMenuOutPut = ""; 
        }
        //*****************************************END OF BUTTON MENU UI
      }
    } 
    
    void  keyPressed() {
      if (state == ZEROSTATE) {
        if (key == '1') {
          introMn.reset();
          state=BUTTONSTATE;
        }
      }
      if (state == BUTTONSTATE) {
        if (key == '9') {
          state=ZEROSTATE;
        }
      }
    }
    
    ///////////////////////////////////////////////////////////////////////
    ///////////////////////////here come the Classes///////////////////////
    ///////////////////////////////////////////////////////////////////////
    
    /////////////////////////////////////////////////////////UI Class
    class IntroUI {
      boolean doOnce;
      boolean doOnce2;
    
      Button start_button;  // the start b
      boolean start_ButtonPressed = false;
      int outPut = 0; 
      int tempOutPut = 0;
      //
      //possible answer of the UI
      private static final int opStart = 1;
      private static final int opCancel = 2;
    
      /////////////////////////// CONSTRUCTOR
      IntroUI() {
        // last int = "from where comes the button?" 1 = top, 2 Right, 3 Bottom, 4 Left
        start_button = new Button("START", ((width/8)*1)+25, height/2, 60, 50, 1);
        // start_ButtonPressed = false;
        // doOnce=false;
      }
      /////////////////////////// FUNCTIONS
    
      void run() {
        checkForOUT();
        // run button if outPut != Start && != Cancel
        if ( doOnce2 == false) {
          if (outPut == opStart) {
            IntroMenuOutPut = "start";
            doOnce2 = true;
          } else if (outPut == opCancel) {
            IntroMenuOutPut = "cancel";
            doOnce2 = true;
          } else {
            start_button.run();
            clickTracker();//
            keyTracker();
          }
        }
      }
    
      void reset() {
        //reset all buttons
        start_button.reset();
        //reset outPut
        outPut = 0; 
        tempOutPut = 0;
        doOnce2 = false;
      }
    
      //////////////////////////////////////
      /////////////////////internal methodes
      //////////////////////////////////////
    
      void checkForOUT() {
        if (start_button.isOUT()) {
          outPut = tempOutPut;
        }
      }
    
      void clickTracker() {
        //on mouse pressed
        if (mousePressed && doOnce == false) {
          if (mouseButton == LEFT) {
            if (start_button.mouseOver()) {
              start_ButtonPressed = true;
            } else {
              start_ButtonPressed = false;
            }
          } else if (mouseButton == RIGHT) {
            //
          } else if (mouseButton == CENTER) {
            //
          }
          doOnce = true;
        }
        //on "mouse release
        if (mousePressed == false && doOnce == true) {
          if (start_button.mouseOver()) {
            if (start_ButtonPressed) {
              //wipe all buttons
              start_button.wipe();
              tempOutPut = opStart;
            }
          }
          doOnce = false;
        }
      }
    
      void keyTracker() {
        if (keyPressed) {
          if (key == '0') {
            //wipe all buttons
            start_button.wipe();
            tempOutPut = opCancel;
          }
        }
      }
    }
    /////////////////////////////////////////////////END OF UI CLASS
    
    /////////////////////////////////////////////////BUTTON CLASS
    class Button {
      String label;
    
      float x;    // top left corner x position
      float y;    // top left corner y position
      float w;    // width of button
      float h;    // height of button
    
      color buttonColor = color(255); // white 
    
      //translate of the button
      int side;
      float X;
      float Y;
    
      //chrono
      int startTime;
      int stopTime;
      int duration = 350;
    
      //sin movement
      float angle = 0.0;
      float p;
      float offset;
    
      // logicstuff
      private static final int READY     = 0; // const 
      private static final int MOVINGIN  = 1;
      private static final int IN        = 2;
      private static final int MOVINGOUT = 3;
      private static final int OUT       = 4;
      private int buttonState;        // current 
      //
      boolean oneLoopDone= false;
      boolean doOnce     = false;
      boolean wiped      = false;
      boolean clicked    = false;
      boolean scrollDone = false;
      // boolean oneLoopDone ;
    
      /////////////////////////////CONSTRUCTOR
      Button(String _label, float xpos, float ypos, float _width, float _height, int _side ) {
        label = _label;
        X=x = xpos;
        Y=y = ypos;
        w = _width;
        h = _height;
        //"from where does the button comes ?" 1 = top, 2 Right, 3 Bottom, 4 Left
        side = _side;
        buttonColor = color(255);
      }
    
      //////////////////////////////   RUN
      void run() {
    
        if (oneLoopDone == false) { // past the 1st loop, even if we keep running, the Button doesn't do anything
    
          scroll();
    
          if (buttonState == READY) {  //************************  0
            //wait for trigger and when you get it, SHOT to MOVINGIN!
            if (doOnce == false) {
              if (side == 1) {//-----------------------TOP
                offset = -height - y;
              } else if (side == 2) {//----------------RIGHT
                offset = width + x;
              } else if (side == 3) {//----------------BOTTOM
                offset = y + height ;
              } else if (side == 4) {//----------------LEFT
                offset = -width - x;
              }
              p = offset; 
              scrollDone = false;
              clock();   //TRIGGER
              buttonState = MOVINGIN;
            }
          } else if (buttonState == MOVINGIN) {  // *****************  1
            display();
            if (scrollDone) {
              buttonState = IN;
            }
          } else if (buttonState == IN) {  //************************  2
            display();
            mouseOver();
            //wait for Click or Wipe order
            if ( clicked || wiped ) {
              wiped = false;
              clicked = false;
              /////////////
              if (side == 1) {//-----------------------TOP
                offset = (height*-1) - y ;
              } else if (side == 2) {//----------------RIGHT
                offset = x + width ;
              } else if (side == 3) {//----------------BOTTOM
                offset = y + height ;
              } else if (side == 4) {//----------------LEFT
                offset = - width - x;
              }
              p = offset;
              clock();   //TRIGGER
              scrollDone = false;
              buttonState = MOVINGOUT;
            }
          } else if (buttonState == MOVINGOUT) {  //*******************  3
            display();
            if (scrollDone) {
              buttonState = OUT;
            }
          } else if (buttonState == OUT) {   //************************  4
            println("OUT");
            oneLoopDone = true;
          }
        }
      } // method 
      /////////////////////////////   END OF RUN
    
      void reset() {
        doOnce     = false;
        wiped      = false;
        clicked    = false;
        scrollDone = false;
        oneLoopDone = false;
        //
        buttonState = READY;
      }
    
      void wipe() {
        wiped = true;
      }
      void click() {
        clicked = true;
      }
    
      boolean isOUT(){
      if(buttonState == OUT){  
      return true;
      } else {
      return false;
      }
      }
    
      ////////////////////////////////////////////////
      ///////////////////////////////internal methodes
      ////////////////////////////////////////////////
    
      void display() {
        //  println("display");
        pushMatrix();
        translate(X, Y);
        fill(buttonColor);
        stroke(141);
        rect(x, y, w, h, 5);
        textAlign(CENTER, CENTER);
        fill(0);
        text(label, x + (w / 2), y + (h / 2));
        popMatrix();
      }
    
      boolean mouseOver() {
        if (mouseX > x && mouseX < (x + w) && mouseY > y && mouseY < (y + h)) {
          buttonColor = color(255, 63, 63);
          return true;
        }
        buttonColor = color(255);
        return false;
      }
    
      void clock() {
        //println("CLOCK");
        startTime = millis();
        stopTime = startTime + duration;
      }
    
      void scroll() {
        //parameters for one way iN, depending on where from
        if (buttonState == MOVINGIN) {
          if (side == 1) {//-----------------------TOP
            X = 0;
            Y = p + 1  ;
          } else if (side == 2) {//----------------RIGHT
            X = p;
            Y = 0;
          } else if (side == 3) {//---------------BOTTOM
            X = 0;
            Y = p - 1;
          } else if (side == 4) {//----------------LEFT
            X = p;
            Y = 0;
          }
        } else if (buttonState == MOVINGOUT) {
          //parameters for one way oUT, depending on where from originaly
          //to invert the motion we keep the same offset value 
          //but Y (or X) = offset-p
          if (side == 1) {//-----------------------TOP
            X = 0;
            Y = offset - p;
          } else if (side == 2) {//----------------RIGHT
            X = offset - p;
            Y = 0;
          } else if (side == 3) {//----------------BOTTOM
            X = 0;
            Y = offset - p;
          } else if (side == 4) {//----------------LEFT
            X = offset - p;
            Y = 0;
          }
        }
        //this part does the actual movement
        if (scrollDone != true) {
           if  (millis () < stopTime) {
            // so angle must be between -PI/2 and -PI
            angle = map(millis(), startTime, stopTime, -PI/2, PI/2);
            float sinval = sin(angle);
            //then I want normSin to be from 0 to 1
            float normSin = (sinval +1)/2;
            p = map(normSin, 0, 1, offset, 0);
          } else {
            scrollDone = true;
          }
        }
      }
    }
    ///////////////////////////////////////////////////////END OF BUTTON CLASS
    
  • great

    looks much cleaner now

    but: introMn is a state (in a way) - we can't cancel state imho

    either we stay in it OR we go to defined other state (how small it might be)

    e.g. cancel high score screen, you go back to main menu

    cancel help screen, you go back to game etc.

    imho

  • edited September 2015

    I did test it, not thoroughly yet, but so far it does what I need it to do. I might all be connected to "transitions", things that are not talked about in this thread. In my demo, I like to have a smooth animation when switching states. Like "moving" from INTROSTATE to PLAYSTATE. I did wonder if transition itself should be a state but I came to the idea that I needed transitions to be "over" the states (like this I can fade out of a state into fading into another one, for instance) Therefore, once a change is made, I can only "launch" a transition that will drive me into another state, and that will take time. So I cannot have my IntroUI coming back all the time until the next state is launch...

Sign In or Register to comment.