Buttons with same coordinates are clicked twice

A beginner’s question with buttons. I’m trying to make a program which contains different pages such as splashscreen, main menu, etc. The first page splashScreen() asks the user click anywhere to continue, and then goes to the mainMenu() method containing several buttons. I have noticed that if I click in the same coordinates that a mainMenu button uses, it directly goes to the method indicated by the button.

For example: On splashScreen, click on the coordinates of the “Instructions” button. It then directly goes to instructions and skips the menu.

How can I test for mouseClicked on those button coordinates only when the program is in that method? The program will probably have a ton of buttons, so simply moving the buttons to different coordinates is not an easy fix. The code is below:

Any advice/tips/help is appreciated. Thanks!

PFont fontD, fontE;
String state="splashScreen";
int x=1;
int pointX, pointY;
  
void setup() {
  size(500, 500);
  mainMenu();
  noStroke();
}

void splashScreen() {
  pointX=mouseX;
  pointY=mouseY;
  
  background(255);
 

   //loading bars
   rectMode(CORNER);
   rect(100, 400, 300, 10);
   fill(#2761AA);
   rect(102, 402, x, 6);
   fill(68, 199, 214);
    
  if (x <= 296) {
    x+=8;
  } else {
    background(230);
    fill(240);
    
    textSize(20);
    fill(0);
    text("Click anywhere to continue", 120, 416);
  } 
      if (mousePressed) {
          state="mainMenu";          
  }
  
    fill(68, 199, 214);
    fontD=loadFont("fontD.vlw");
    textFont(fontD);
    textSize(40);
    text("Program", 100, 150);
    textSize(20);
    text("Helping you through your math ordeals", 80, 180);
}

void mainMenu() {
  pointX=mouseX;
  pointY=mouseY;
  
  fontD=loadFont("fontD.vlw");
  textFont(fontD);
  
  background(255);
  textSize(40);
  text("Program", 100, 100);
  textSize(20);
  text("Main Menu", 195, 130);
  
  fontE=loadFont("fontE.vlw");
  textFont(fontE);
  
  //first choice
  rectMode(CORNERS);
  rect(200, 200, 300, 220);
  textSize(20);
  fill(255);
  textSize(15);
  text("Instructions",202,215);
  
  //second choice
  fill(68, 199, 214);
  rect(200, 240, 300, 260);
  textSize(20);
  fill(255);
  textSize(15);
  text("Learn", 230, 255);
  
  //third choice 
  fill(68, 199, 214);
  rect(200, 280, 300, 300);
  textSize(20);
  fill(255);
  textSize(15);
  text("Practice", 220, 295);
  
  //fourth choice 
  fill(68, 199, 214);
  rect(200, 320, 300, 340);
  textSize(20);
  fill(255);
  textSize(15);
  text("Exit", 235, 335);
  
  //first
  if (pointX >=200 && pointX <= 300 && pointY >= 200 && pointY <= 220) {
    
    fill(#2761AA);
    rect(200, 200, 300, 220);
    fill(255);
    text("Instructions",202,215);
    fill(68, 199, 214);
    
    if(mousePressed==true) {
      state="instructions";
    }
  } else if (pointX >=200 && pointX <= 300 && pointY >= 240 && pointY <= 260) {
    
    fill(#2761AA);
    rect(200, 240, 300, 260);
    fill(255);
    text("Learn", 230, 255);
    fill(68, 199, 214);
    
    if(mousePressed==true) {
      state="learn";
    }
  
  } else if (pointX >= 200 && pointX <= 300 && pointY >= 280 && pointY <= 300) {
    
    fill(#2761AA);
    rect(200, 280, 300, 300);
    fill(255);
    text("Practice", 220, 295);
    fill(68, 199, 214);
    
    if(mousePressed==true) {
      state="practice";
    }
    
  } else if (pointX >= 200 && pointX <= 300 && pointY >= 320 && pointY <= 360) {
    
    fill(#2761AA);
    rect(200, 320, 300, 340);
    fill(255);
    text("Exit", 235, 335);
    fill(68, 199, 214);
    
    if(mousePressed==true) {
      state="exit";
    }
    
  } else { 
    fill(68, 199, 214);

  }
  
}

void instructions() {
  fontD=loadFont("fontD.vlw");
  textFont(fontD);
  
  background(255);
  textSize(40);
  text("Program", 100, 100);
  textSize(20);
  text("Instructions", 195, 130);
  
  rectMode(CORNERS);
  rect(200, 200, 300, 220);
  textSize(20);
  fill(255);
  textSize(15);
  text("Instructions",202,215);
  
  
    if (pointX >=200 && pointX <= 300 && pointY >= 200 && pointY <= 220) {
    
    fill(#2761AA);
    rect(200, 200, 300, 220);
    fill(255);
    text("Instructions",202,215);
    fill(68, 199, 214);
    
    if(mousePressed==true) {
      state="learn";
    }
  }
}

void learn() {
  fontD=loadFont("fontD.vlw");
  textFont(fontD);
  
  background(255);
  textSize(40);
  text("Program", 100, 100);
  textSize(20);
  text("Learn", 215, 130);
  textSize(18);
  text("Which shape do you want to learn about?", 85, 150);
  
  //shapes
  stroke(68, 199, 214);
  strokeWeight(2);
  fill(255);
  
  triangle(90, 155, 50, 250, 140, 250);
  
  rectMode(CORNER);
  rect(150, 170, 100, 60);
  
  rect(180, 240, 100, 100);
  
  ellipse(350, 220, 120, 120);
  
  beginShape();
  vertex(70, 260);
  vertex(160, 260);
  vertex(120, 330);
  vertex(30, 330);
  vertex(70, 260);
  endShape();
  
  beginShape();
  vertex(400, 290);
  vertex(320, 290);
  vertex(270, 380);
  vertex(440, 380);
  vertex(400, 290);
  endShape();
  
  
  
  fill(68, 199, 214);
}

void practice() {
  fontD=loadFont("fontD.vlw");
  textFont(fontD);
  
  background(255);
  textSize(40);
  text("Program", 100, 100);
  textSize(20);
  text("Practice", 203, 130);
}

void goodBye()
{
  
 
}

void draw()
{
  if (state.equals("splashScreen"))
{
    splashScreen();
  } else if (state.equals("mainMenu")) 
  {
    mainMenu();
  } else if (state.equals("instructions")) 
  { 
    instructions();
  }
    else if (state.equals("learn")) 
  {
    learn();
  } else if (state.equals("practice")) 
  {
    practice();
  } else if (state.equals("goodBye")) 
  {
    goodBye();
  } else if (state.equals("done")) 
  {
    exit();
  }
}
2 Likes

Hey There!

Why is your main menu being called in setup ?
Secondly I would implement using the mouse pressed event method rather than the Boolean variable. And thirdly maybe look into GUI libraries or make a class to simplify your building of the buttons.

1 Like

I’m not sure why I need main menu in setup either, it just doesn’t seem to work without it.
Thanks so much for the tip with using void mousePressed!

void mousePressed() {
  if (state.equals("mainMenu")) {
    if (pointX >=200 && pointX <= 300 && pointY >= 200 && pointY <= 220) {
    state="instructions";
    }
  }
}

Buttons work very smoothly now, and putting them in mousePressed makes it clear to read.
I didn’t know about GUI libraries before and it’s something I’ll definitely look into.
Thanks again!

3 Likes

Hey There!

I recommend G4P , ControlP5.

you can replace this with

void draw() 
{
  switch(state) {
   case "splashScreen":
        splashScreen();
        break; 
  case "mainMenu":
        mainMenu();
        break; 
   ....
 }

just don’t forget the break; after each entry.

To avoid the double interpretation of one mouse click, the function mousePressed() is better than the boolean variable mousePressed as has been said.

I also recommend to use the switch structure above for the functions mousePressed() and keyPressed() etc., so in each state you analyze only the input for this state.

Chrisir

1 Like