Problem coding an easy game / how to make it restart

Hi everyone! I’m doing a game using processing.
The game’s pretty simple: there’s a black bar that slowly rises when you get a point and your goal is to bring the bar up to the top. To get a point it works pretty much like Tetris, you have another small bar that falls from the top and you have to click on the mouse when the two bars are overlapping.

Our problem is that at the end of the game it should appear a “win” text and if you want to restart the game you should just click on the mouse. We cannot solve this last part, we tried with a delay but nothing it’s working can you help us? :blush:

Here’s the code:

int val;

//-- Import typography
PFont font;

//-- If "true" means that touch the bar, "false" that it doesn't 
boolean colision = false;

//-- Variables of the rectangle 
float pos_y=0; // Variable posición Y ficha inicializada a 0
float pos_x=250; // Variable posición X ficha iniciazada a 250
float vel=1.4; // Variable velocidad Y inicializada en 1

//-- Variables of the Bar
float posinicial=470; // Posicion inicial en y
float incremento=50; // Variable velocidad subida inicializada en 50
float posbarra=posinicial; // Variable posicion barra

//-- Variable of the safe zone
float safezone=10;

//-- Variable of the touching/colision point
float accierto=10;

//--Variables Colores
color negro=color(0, 0, 0);
color blanco=color(255, 255, 255);
color rosa=color(193, 80, 152);
color morado=color(117, 103, 171);
color azul=color(74, 158, 208);
color purpura=color(122, 55, 139);

void setup()
{
  size(500, 500);
}

//-- drawing loop
void draw() {

    //-- Paint white background
    background(255);

    //-- change position using speed variable 
    pos_y=pos_y+vel;

    //-- if the rectangle reaches the bottom, restart from the top
    if (pos_y>500) {
      pos_y=0;
      pos_x=100+random(300);
      //posbarra=posbarra-20;
      //vel=vel+1;
    }

    //-- drawing the rectangle 
    stroke(1);
    rect(pos_x, pos_y, 50, 10);


    //-- touching point zone (leer ultimo if)  
    fill(0, 255, 0);
    noStroke();
    rect(0, 0, 500, safezone);

    //-- drawing the bar
    fill(0);
    rect(0, posbarra, 500, 10);

    //-- loop if: if the bar and the rect are touching. If yes, the rect becomes pink.
    if ( (pos_y > posbarra-accierto) && (pos_y < posbarra+accierto ) ) {
      fill(rosa);
      colision=true;

      //-- If not, the variable is 'not' and so the rect is in red color
    } else {
      fill(255, 0, 0);
      colision=false;
    }


    //--Loop if for touching point
    //-- If you touch in the right moment, the bar goes up and the rect restarts from the top
    if ( (colision) && ( mousePressed == true )) {

      //-- bar going up
      posbarra=posbarra-incremento;

      //-- restart the rectangle position
      pos_y=0;
      pos_x=100+random(300);
    } 

    //-- Loop if Error - if you click in the wrong moment of collision
    if ( (pos_y > safezone) && (colision == false)  && (mousePressed == true)) {

      //-- bar goes back to start
      posbarra=posinicial;

      //-- pink error dispolay
      background(rosa);
    }

    //-- Loop if with no click
    //-- if you don't click the bar goes down of one step
    if ( (pos_y > posbarra+accierto ) && (posbarra < posinicial) ) {
      //-- bar goes down
      posbarra=posbarra+incremento;

      //-- back to last position
      pos_y=0;
      pos_x=100+random(300);
    }

    //-- if loop, when you finish the game and bar reaches the top
    println(posbarra);
    if (posbarra<30) {
      fill(0);
      rect(0, 0, 500, 500); 

      //-- put typography
      font= loadFont("Bungee-Regular-48.vlw");
      textFont(font, 32);
      textSize(70);
      fill(200, 0, 0);
      
      text("YOU WIN!", 65, 260);
      //frameRate(1);
      textFont(font, 12);
      textSize(70);
      fill(200, 0, 0);
      //text("push to restart", 65, 290);

      
      posbarra=posinicial;
      //frameRate(30);
    }
  }

try to restructure your whole code

example:

//____________________________________________ screen / state system ( like for a game )

int state = 0; 
//.................. please use INT for this, not many boolean..
//.................. 0 for INTRO
//.................. 1 for PLAY GAME
//.................. 2 for WIN LOOSE ..
//.................. 3 END ( if you want a final screen )

void setup(){}
void draw() {
  if      ( state == 0 ) intro();
  else if ( state == 1 ) play();
  else if ( state == 2 ) win();
  else if ( state == 3 ) end();
}

void intro(){
  background(200,200,0);
  text("state: "+state,10,10);
}

void play(){
  background(0,200,0);
  text("state: "+state,10,10);
}

void win(){
  background(0,200,200);
  text("state: "+state,10,10);
}

void end(){  
  background(200,200,200);
  text("state: "+state,10,10);
}

void keyPressed() {
  state++;
  if ( state > 3 ) state = 0;
}

2 Likes

In Theory, kll is correct

In Praxis it might be a too big step

Try to place a new variable of type boolean hasWon and evaluate it in draw

Initially it’s false, set it true when you won

Show a message in draw when it’s true

Put all you have in draw now in the else part of the same if-clause

2 Likes

To summarize what has been said so far, there are two important things here:

  • tracking the game state
  • evaluating a win condition

As @kll has pointed out there are a few naturally arising game states such as PLAYING (playing the game) and WON (having satisfied the win condition – that is you made it True). However those are merely names, but they also have implications. In car racing, winning means you have passed the finish line, but only after some number of laps and you might need to have finished each lap ahead of all the other racers.

Also, like @Chrisir pointed out, in order to transition from PLAYING --> WON you must regularly check the win condition and when it is met do something like stop the game and tell the player they’ve won.

In addition, having won the game, if you want to play again without restarting the program you also need to reset the various game variables back to an INITIAL state and then allow the player to begin playing again. To that end it sometimes helps to introduce a third state that is reached when you click the screen. You can of course have an endless play until win or quit and just do all the necessary reset bits when the transition occurs from WON --> PLAYING.

1 Like

thanks @Nathan
this shows me that some digital ( possibly boolean or SCORE > … ) game state you use, like
WIN or LOOSE
and i use

if ( state == 2 )  win();  // WIN LOOSE

are very different things / but both needed,

i talk about the program / code part
what generates / shows a SCREEN where
game state info if WIN / LOOSE ( the result you talk about )
& / button PLAY AGAIN / QUIT is shown.

so possibly the usage of my variable name state
is bad ( as in confusing )
better call it ?screen?

As long as it’s clear to you what’s going on I wouldn’t worry too much about the naming at least not for something simple. Although it might make sense to call it screen since it’s in draw rather than say:

if( winCondition ) win();

Even though in Processing the draw loop is effectively the main loop it can help with tracking what’s going if you make it clear where stuff is being drawn as opposed to just updated variable values.

However, depending on how complex the end result may be, breaking out the state change into a separate function you call when you want to change state can help keep stuff tidy. The keyPressed() function can get pretty cluttered if you do all the actual handling of stuff there.

1 Like