Fix Capture Bug and Game Over Screen. (Runnable Code!)

edited December 2016 in Library Questions

``Hello everyone!

So I have been making a game similar to the traditional snake game. The difference being that it is on individual shape catching the food rather than it growing. However, after awhile the icon wont pickup the food anymore and I cannot figure out why. I also cant figure out how to create a game over box when the icon hits the wall. Any help would be greatly appreciated! I adjusted the code to not use the images so it could be run by anyone willing to help. Thank you in advance!

_________Main Body____________

import ddf.minim.*;
import ddf.minim.signals.*;
import ddf.minim.analysis.*;
import ddf.minim.effects.*;

Minim minim;
AudioPlayer player;

Logo B;
int grid = 35;
int Time;
//PImage BH;
//PImage SC;
//PImage Rink;
PFont Silom;

PVector Cup;


void setup() {

  size(600, 631);
  B = new Logo();
  frameRate(8);
  pickLocation();
  //BH = loadImage("BH.png");
  //SC = loadImage("SC.png");
  //Rink = loadImage("Rink.jpg");
  Silom = loadFont("Silom.vlw");


  minim = new Minim( this );

  player = minim.loadFile("CD.mp3");
  player.play();
}

void pickLocation() {
  int across = width/grid;
  int down = height/grid;
  Cup = new PVector(floor(random(across)), floor(random(down)));
  Cup.mult(grid);
}

void draw() {
  background(155);


  if (B.capture(Cup)) {
    pickLocation();
  }
  B.death();
  B.update();
  B.show();

  //image(SC, Cup.x, Cup.y, grid, grid);
  rect(Cup.x, Cup.y, grid, grid);
  fill (0);
  textFont(Silom, 20);
  text("Press the arrow keys", 10, 30);
  text("to move around", 40, 50);
}

void keyPressed() {

  if (keyCode == UP) {
    B.dir(0, -1);
  } else if (keyCode == DOWN) {
    B.dir(0, 1);
  } else if (keyCode == RIGHT) {
    B.dir(1, 0);
  } else if (keyCode == LEFT) {
    B.dir(-1, 0);
  }
  else if (keyCode == ' ');

}

__________Logo_____________

    class Logo {
      float x = 0;
      float y = 0;
      float xspeed = 1;
      float yspeed = 0;
      int total = 0;
      boolean endgame=false;
      ArrayList<PVector> hawk = new ArrayList<PVector>();

      Logo() {
      }

      boolean capture(PVector pos) {
        float d = dist(x, y, pos.x, pos.y);
        if (d < 1) {
          return true;
        } else {
          return false;
        }
      }

      void dir(float x, float y) {
        xspeed = x;
        yspeed = y;
      }

      void death() {
        for (int i = 0; i < hawk.size(); i++) {
          PVector pos = hawk.get(i);
          float d = dist(x, y, pos.x, pos.y);
          if (d < 1) {
            text("starting over",100,100);
            total = 0;
            hawk.clear();
          }
        }
      }

      void update() {

        x = x + xspeed*grid;
        y = y + yspeed*grid;

        x = constrain(x, 0, width-grid);
        y = constrain(y, 0, height-grid);
      }

      void show() {
        //image(BH, x, y, grid, grid);
        rect(x, y, grid, grid);
        fill(255, 150, 20);
      }
    }
Tagged:

Answers

  • edited December 2016

    The problem is that you are using floats for positions, and this causes things that may look close, but not be within a dist() of 1 from each other.

    Since your objects are on a grid, their positions could be better represented as a pair of integers that determine which cell of the grid the object is in. For example, the top left position is (0,0), to its right is (1,0), below that is (1,1), etc.

    Then your collision check can be exact - and you would draw your objects at (grid cell size * coordinate).

  • That made a huge difference! How would you say to add in the wall collision game over screen? I tried the advice I was given from another post I made but it didnt work out for me.

  • Answer ✓

    if the position of an object is outside the range of possible cells, it's off the screen, right?

    Example code:

    int x, y;
    int dx, dy;
    int time;
    int delay = 100;
    
    void setup() {
      size(400, 400);
      time = millis() + delay;
    }
    void draw() {
      background(0);
      if (time < millis()) {
        time = millis() + delay;
        x+=dx;
        y+=dy;
      }
      fill(255);
      rect(x*20, y*20, 20, 20);
      fill(0, 255, 255);
      if (x<0||y<0||x>19||y>19) {
        fill(255, 0, 0);
      }
      text("("+x+","+y+")", 200, 200);
    }
    
    void keyPressed() {
      if (keyCode == UP) dy = -1;
      if (keyCode == DOWN) dy = 1;
      if (keyCode == LEFT) dx = -1;
      if (keyCode == RIGHT) dx = 1;
    }
    void keyReleased() {
      if (keyCode == UP) dy = 0;
      if (keyCode == DOWN) dy = 0;
      if (keyCode == LEFT) dx = 0;
      if (keyCode == RIGHT) dx = 0;
    }
    
  • use state to make a game over screen - see my example

  • Runnable Code!

    Silom = loadFont("Silom.vlw");

    file not found

    player = minim.loadFile("CD.mp3");

    file not found

  • @Chrisir can you please post your example code here, or give a link to it?

  • I've been trying to get the code to work using states but for whatever reason, it won't switch to the game. Here is the code if anyone is able to help. Maybe someone can see something I'm not seeing.

    //import ddf.minim.*;
    //import ddf.minim.signals.*;
    //import ddf.minim.analysis.*;
    //import ddf.minim.effects.*;
    
    //Minim minim;
    //AudioPlayer player;
    
    final int stateGame  = 0;
    final int stateHome = 1;
    int state = stateHome;
    int grid = 35;
    int total = 0;
    boolean buttonpressed;
    boolean capture;
    //PFont Silom;
    //PImage Rink;
    //PImage BH;
    //PImage SC;
    PVector Cup;
    int x, y;
    int time;
    int delay = 100;
    int xspeed = 1;
    int yspeed = 0;
    ArrayList<PVector> trail = new ArrayList<PVector>();
    
    
    void setup()
    {
      size(600, 631);
      frameRate(8);
      pickLocation();
      //Rink = loadImage("Rink.jpg");
      //BH = loadImage("BH.png");
      //SC = loadImage("SC.png");
      //Silom = loadFont("Silom.vlw");
      time = millis()+delay;
    
      //minim = new Minim( this );
    
      //player = minim.loadFile("CD.mp3");
      //player.play();
      //player.loop();
    }
    void pickLocation() {
      int across = width/grid;
      int down = height/grid;
      Cup = new PVector(floor(random(across)), floor(random(down)));
      Cup.mult(grid);
    } 
    
    void draw() 
    { 
      background(155);
      if (time < millis()) {
        time = millis() +delay;
        x=xspeed;
        y=yspeed;
    
        switch (state) {
    
        case stateHome:
          handleStateHome(); 
          break;
    
        case stateGame: 
          handleStateGame();
          break;
        }
      }
    }
    void handleStateGame() {
      //image(BH, x, y, grid, grid);
      rect(x,y,grid,grid);
      //image(SC, Cup.x, Cup.y, grid, grid);
      rect(Cup.x, Cup.y, grid, grid);
    
      if (capture(Cup)) {
        pickLocation();
    
        death();
        update();
      }
    }
    boolean capture(PVector pos) {
      float d = dist(x, y, pos.x, pos.y);
      if (d < 1) {
        return true;
      } else {
        return false;
      }
    }
    
    void dir(int x, int y) {
      xspeed = +x;
      yspeed = +y;
    }
    
    void death() {
      if (x<1||y<1||x>18||y>18) {
        buttonpressed = false;
      }
    }
    
    void update() {
      x = x + xspeed*grid;
      y = y + yspeed*grid;
    
      {
        x = constrain(x, 0, width-grid);
        y = constrain(y, 0, height-grid);
      }
    }
    
    void handleStateHome() {
    
      fill(0);
      if (buttonpressed) {
        fill(255, 255, 255, 0);
      } else {
        //textFont(Silom, 20);
        text("Press the arrow keys to move around", 100, 330);
        //textFont(Silom, 60);
        text("Catch the cup!", 70, 300);
        //textFont( Silom, 20);
        text("Press Space to Begin", 180, 360);
      }
    }
    
    void keyPressed() {
    
      switch (state) {
    
      case stateGame: 
        keyPressedForStateGame();
        break; 
    
      case stateHome:
        keyPressedForStateHome(); 
        break;
      }
    }
    void keyPressedForStateHome() {
      if (keyCode == ' ');
      buttonpressed = true;
    }
    void keyPressedForStateGame() { 
      if (keyCode == UP) {
        dir(0, -1);
      } else if (keyCode == DOWN) {
        dir(0, 1);
      } else if (keyCode == RIGHT) {
        dir(1, 0);
      } else if (keyCode == LEFT) {
        dir(-1, 0);
      }
    }
    
  • what is that supposed to do:

      if (time < millis()) {
        time = millis() +delay;
        x=xspeed;
        y=yspeed;
    

    in draw() there should be nothing outside switch when using state properly

  • Answer ✓

    uh oh

    void keyPressedForStateHome() {
      if (keyCode == ' ')  ;   //// !!!!!!!!!!!!!!!!!!!!!!!!
      buttonpressed = true;
    }
    

    first the semicolon ; BAD.

    It ends the if clause. When the condition applies, everything between ) and the ; is executed, which is nothing

    Better always use {} with if :

    void keyPressedForStateHome() {
      if (keyCode == ' ')  {  // no semicolon!!!!!
                buttonpressed = true;  // when true 
      } // if
    } // func 
    

    and :

        buttonpressed = true; 
    

    ????

    no, we want

    state = stateGame;
    

    here

  • edited December 2016

    there were so many errors, I stopped counting

    It is like this when you just copy code from openprocessing without getting it

    One example:

    you had

      x=xspeed;
      y=yspeed;
    

    instead of

      x+=xspeed;
      y+=yspeed;
    

    oh boy....

    //import ddf.minim.*;
    //import ddf.minim.signals.*;
    //import ddf.minim.analysis.*;
    //import ddf.minim.effects.*;
    
    //Minim minim;
    //AudioPlayer player;
    
    final int stateGame  = 0;
    final int stateHome = 1;
    int state = stateHome;
    
    int grid = 35;
    int total = 0;
    boolean buttonpressed;
    boolean capture;
    PFont Silom;
    //PImage Rink;
    //PImage BH;
    //PImage SC;
    
    PVector Cup;
    
    int x, y;
    
    int time;
    int delay = 100;
    int xspeed = 1;
    int yspeed = 0;
    ArrayList<PVector> trail = new ArrayList<PVector>();
    
    // --------------------------------------------------------------------
    // primary functions
    
    void setup()
    {
      size(600, 631);
      //  frameRate(8);
      pickLocation();
      //Rink = loadImage("Rink.jpg");
      //BH = loadImage("BH.png");
      //SC = loadImage("SC.png");
      Silom = createFont("Silom.vlw", 17);
      time = millis()+delay;
    
      //minim = new Minim( this );
    
      //player = minim.loadFile("CD.mp3");
      //player.play();
      //player.loop();
    }
    
    void draw() 
    { 
      switch (state) {
    
      case stateHome:
        handleStateHome(); 
        break;
    
      case stateGame: 
        handleStateGame();
        break;
      }//switch
    }// func 
    
    // --------------------------------------------------------------------
    // secondary functions (directly called from draw())
    
    void handleStateHome() {
      background(155);
      fill(0);
      if (buttonpressed) {
        fill(255, 255, 255, 0);// ???????????????????????????
      } else {
        //textFont(Silom, 20);
        text("Press the arrow keys to move around", 100, 330);
        //textFont(Silom, 60);
        text("Catch the cup!", 70, 300);
        //textFont( Silom, 20);
        text("Press Space to Begin", 180, 360);
      }
    }
    
    void handleStateGame() {
    
      background(155);
    
      if (time > millis()) {
        time = millis() +delay;
      }
    
      x+=xspeed;
      y+=yspeed;
    
      //image(BH, x, y, grid, grid);
      fill(2, 244, 2);
      rect(x, y, grid, grid);
    
      //image(SC, Cup.x, Cup.y, grid, grid);
      fill(255, 2, 2); 
      rect(Cup.x, Cup.y, grid, grid);
    
      if (capture(Cup)) {
        pickLocation();
    
        death();
        update();
      }
    }
    
    // -----------------------------------------------------------
    // Input functions 
    
    void keyPressed() {
      switch (state) {
      case stateGame: 
        keyPressedForStateGame();
        break; 
    
      case stateHome:
        keyPressedForStateHome(); 
        break;
      }
    }
    
    void keyPressedForStateHome() {
      if (keyCode == ' ') {
        state = stateGame; 
        // buttonpressed = true;
      }
    }
    
    void keyPressedForStateGame() { 
      if (keyCode == UP) {
        dir(0, -1);
      } else if (keyCode == DOWN) {
        dir(0, 1);
      } else if (keyCode == RIGHT) {
        dir(1, 0);
      } else if (keyCode == LEFT) {
        dir(-1, 0);
      }
    }
    
    // --------------------------------------------------------------------
    // minor functions
    
    void pickLocation() {
      float  across = width/grid;
      float  down = height/grid;
      Cup = new PVector(floor((across)), floor((down)));
      //  Cup.mult(grid);
    } 
    
    boolean capture(PVector pos) {
      float d = dist(x, y, pos.x, pos.y);
      if (d < 1) {
        return true;
      } else {
        return false;
      }
    }
    
    void dir(int x, int y) {
      xspeed = x;
      yspeed = y;
    }
    
    void death() {
      if (x<1||y<1||
        x>18||y>18) {
        buttonpressed = false; // ???????????  state = gameOver ??
      }
    }
    
    void update() {
      x = x + xspeed*grid;
      y = y + yspeed*grid;
    
      {
        x = constrain(x, 0, width-grid);
        y = constrain(y, 0, height-grid);
      }
    }
    //
    
Sign In or Register to comment.