Home > database >  Button for Creative Coding Asteroids project
Button for Creative Coding Asteroids project

Time:11-04

I'm an undergrad and in one of my classes, we have this assignment to make the Asteroids game (you know, the retro one!) on Processing (which is basically a simplified Javascript program). I have the code for a button:

void setup()
{
size(1280, 720);
}

void draw()
{
background(0,0,0);
drawButton();
}
Boolean pointIsInRectangle(int left, int top, int right, int bottom, int pointX, int pointY)
{
if (pointX >= left 
&& pointX <= right 
&& pointY <= bottom 
&& pointY >= top
)
  return true;
else
  return false;
}
void drawButton()
{
int left = 350;
int top = 145;
int right = 860;
int bottom = 220;

rectMode(CORNERS);
color background = color(0,0,0);
if (pointIsInRectangle(left,top,right,bottom,mouseX,mouseY))
{
  background = color(255);
}

// draw outer rectangle
stroke(255);
fill(background);
rect(left,top,right,bottom);

// draw caption
fill(255);
textSize(100);
text(" ASTEROIDS", left,bottom);
}

and I have the preliminary code for the ship for the game, but I need the button to get to an "in between" page so that when the button is clicked, it leads to a new screen that says "click anywhere to play game" and when any point in the screen is clicked, the ship appears and asteroids begin appearing and the game begins. HOW DO I GET THE BUTTON TO LEAD TO A NEW PAGE, AND HOW DO I CREATE THAT PAGE? I really cannot figure it out. Crossing my fingers that someone will be able to give me some guidance!!!!!

The actual result I'm seeing is that nothing is happening when the button is clicked. This makes sense because I don't know how to add the next page that says Click to Play Game, so this is the issue I'm facing. The code I have so far can be found above.

CodePudding user response:

This is not question about a button, but about a game engine with multiple scenes.
Your game is a collection of screens (scenes). Every scene have definition of visuals, definition of logic, and definition of switch for another scene.

Here is the minimal solution of Your problem.
1 - Define visuals of Your screens in .display() method,
2 - Define logic condition for next screen switch in stateCondition().

boolean mouseReleased;
GameScreen screen;
GameScreen splashScreen;
GameScreen inBetweenPage;

void setup() {
  size(1280, 720);
  GameScreen splashScreen = new SplashScreen();
  GameScreen inBetweenPage = new InBetweenPage();

  splashScreen.setNextScreen(inBetweenPage);
  inBetweenPage.setNextScreen(splashScreen);
  screen = splashScreen;
  mouseReleased = false;
}

void draw() {
  screen.display();
  if (screen.stateCondition()) {
    screen = screen.getNextScreen();
  }
}

interface GameScreen {
  /**
   **   screen visual definition
   **/
  void display();

  /**
   **   screen change state condition
   **/
  boolean stateCondition();

  void setNextScreen(GameScreen scr);
  GameScreen getNextScreen();
}

class SplashScreen implements GameScreen {
  GameScreen nextScreen;
  int left = 350;
  int top = 145;
  int right = 860;
  int bottom = 220;

  void display() {
    background(0, 0, 0);
    rectMode(CORNERS);
    color background = color(0, 0, 0);
    if (pointIsInRectangle(left, top, right, bottom, mouseX, mouseY)) {
      background = color(255, 255, 255, 160);
    }

    // draw outer rectangle
    stroke(255);
    fill(background);
    rect(left, top, right, bottom);

    // draw caption
    fill(255);
    textSize(100);
    textAlign(CENTER, CENTER);
    text("ASTEROIDS", (left right)/2, (top bottom)/2-16);
  }

  boolean stateCondition() {
    if (mouseReleased && (mouseButton == LEFT)) {
      mouseReleased = false;
      return pointIsInRectangle(left, top, right, bottom, mouseX, mouseY);
    }
    return false;
  }

  GameScreen getNextScreen() {
    return nextScreen;
  }

  void setNextScreen(GameScreen target) {
    this.nextScreen = target;
  }
}

class InBetweenPage implements GameScreen {
  GameScreen nextScreen;
  int left = 0;
  int top = 0;
  int right = width;
  int bottom = height;

  void display() {
    background(0, 0, 0);
    // draw caption
    fill(255);
    textSize(24);
    textAlign(CENTER, CENTER);
    text("< click anywhere to play game >", width/2, height/2);
  }

  boolean stateCondition() {
    if (mouseReleased && (mouseButton == LEFT)) {
      mouseReleased = false;
      return pointIsInRectangle(left, top, right, bottom, mouseX, mouseY);
    }
    return false;
  }


  GameScreen getNextScreen() {
    return nextScreen;
  }

  void setNextScreen(GameScreen target) {
    this.nextScreen = target;
  }
}


Boolean pointIsInRectangle(int left, int top, int right, int bottom, int pointX, int pointY) {
  if (pointX >= left && pointX <= right && pointY <= bottom && pointY >= top) {
    return true;
  } else
    return false;
}


void mouseReleased() {
  mouseReleased = true;
}

CodePudding user response:

There is a relatively simple solution to this problem, which would be to make some space for a special "splashscreen" state in your code. It would almost be ninja coding to implement it, although in this case as you are learning it's not taking shortcuts but more like climbing a new step in the learning stairwell. Here's a proof of concept which shows what I'm speaking about:

// this boolean keeps track of the current game state: splashscreen or not
boolean splashScreen = true;

void setup() {
  size(600, 400);
}

void draw() {
  background(0);

  // if the game has yet to start, show the splashscreen
  if (splashScreen) {
    drawSplashScreen();
  } else {
    playGame();
  }
}

// this method draws the splashScreen
// it could be coded in the 'draw()' method, but it's easier to read this way
void drawSplashScreen() {
  textAlign(CENTER);
  textSize(30);
  fill(255);
  text("THIS IS THE SPLASHSCREEN \n click anywhere to play the game", width/2, height/2);
}

// this method contains everything your game loop needs to work
void playGame() {
  textAlign(CENTER);
  textSize(40);
  fill(200, 0, 200);
  text("YOU ARE CURRENTLY \n PLAYING THE GAME", width/2, height/2);
}

void mouseClicked() {
  if (splashScreen) {
    splashScreen = !splashScreen;
  }
}

Here you have 2 game states: the splash screen and the game itself, but you could implement more than just these two. There's a design pattern called Easy 3 states game schema

And here's the skeleton code that would implement such a game, including a bonus rectangle collision detection method:

// the game states are as follow:
// 0 is welcome screen with button
// 1 is click anywhere screen
// 2 is the game itself
int gameState = 0;

void setup() {
  size(600, 400);
}

void draw() {
  background(0);

  // let's use the right game state here
  switch(gameState) {
  case 0:
    drawWelcomeScreen();
    break;
  case 1:
    drawClickAnywhereScreen();
    break;
  case 2:
    playGame();
    break;
  }
}

void drawWelcomeScreen() {
  fill(0, 0, 100);
  rect(100, 100, 400, 100);

  textAlign(CENTER);
  textSize(30);
  fill(255);
  text("Click here to play", 300, 150);
  text("THIS IS THE WELCOME SCREEN", width/2, 50);
}

void drawClickAnywhereScreen() {
  textAlign(CENTER);
  textSize(30);
  fill(255);
  text("Click anywhere to play the game", width/2, height/2);
}

void playGame() {
  textAlign(CENTER);
  textSize(40);
  fill(200, 0, 200);
  text("YOU ARE CURRENTLY \n PLAYING THE GAME \n click anywhere to go \n back to the welcome screen", width/2, height/2);
}

void mouseClicked() {
  // now this will be more complicated, because you'll want to deal with clicks differently depending on the game state
  // which kinda answers the question as how we'll deal with this issue: same as in the 'draw()' method

  switch(gameState) {
  case 0:
    // if the click's coordinates are in the rectangle's coordinates (use math here, or a collision method)
    // (in fact, use math pretty much everywhere)
    // (I hope you like math)
    // anyway here's an old collision method I paste everywhere on SO, feel free to steal it and improve on it!
    // I wrote it as a student to deal with pretty much the same stuff that you're going through
    if (intersect(100, 100, 400, 100, mouseX, mouseY, 1, 1)) {
      gameState = 1;
    }
    break;
  case 1:
    gameState = 2;
    break;
  case 2:
    gameState = 0;
    break;
  }
}

// enter the xy coordinates, the width and the heigh of 2 rectangle shapes and it'll return true if they intersect
boolean intersect(float x1, float y1, float w1, float h1, float x2, float y2, float w2, float h2) {
  boolean checkX = false;
  boolean checkY = false;

  if ( (x1<x2 && (x1 w1)>x2) || (x1<(x2 w2) && (x1 w1)>x2 w2) || (x1>x2 && (x1 w1)<(x2 w2)) ) {
    checkX = true;
  }
  if ( (y1<y2 && (y1 h1)>y2) || (y1<(y2 h2) && (y1 h1)>y2 h2) || (y1>y2 && (y1 h1)<(y2 h2)) ) {
    checkY = true;
  }

  return checkX && checkY;
}

I hope I'm not confusing you with all this material. I'll try and keep an eye out for any question you may have about these things.

Good luck and have fun!

  • Related