Monkey catching game where one monkey is stuck in an corner (should be falling down)

In the game, 2 monkeys or 1 (that already works) should be falling down but with my code one monkey is stuck in the top left corner flickering (blinking)


int monkeyaY = -50;
int monkeybY = -50;
int monkeya_X = 0;
int monkeyb_X = 0;
int monkeyWidth = 76; 
int Counter;
int Score;
int netLeft = 0;
int netWidth = 118;
int NetPointPos = 0;
int randDelay = 0;
int fallType = 0;
int randSpeed = 0;


void Imgs() {
 
  fallType = (int) random(0,3);
 
  PImage img;
    img = loadImage("background.png");
    background(img);
    
  
      randDelay = (int) random(0,100);
      PImage monkey = loadImage("Monkey.png");
  
    if(fallType == 0){
        image(monkey, monkeya_X, monkeyaY);
    }else if(fallType == 1){
        image(monkey, monkeya_X, monkeyaY);
        delay(randDelay);
        image(monkey, monkeyb_X, monkeybY);
      
    }else if(fallType == 2){
      
       image(monkey, monkeya_X, monkeyaY);
       delay(50);
       image(monkey, monkeyb_X, monkeybY); 
       
    }else if(fallType == 3){
      
       delay(randDelay);
       image(monkey, monkeya_X, monkeyaY);
       
    }
      PImage net = loadImage("Net.png");
      NetPointPos = mouseX - netWidth/2;
      netLeft = mouseX - netWidth/2;
      image(net, NetPointPos, 275);

    
 }
  
  
 
    
    




void setup() {
  
  size(1024, 386);
  PImage img;
  img = loadImage("background.png");
  background(img); 
  PImage cursor = loadImage("Cursor.png");
  cursor(cursor);
  fallType = (int) random(0,3);
}

void draw() {
  
  Imgs();
  
  if (monkeyaY < 300) {
    monkeyaY += (int) random(5,6);
  } else {
    monkeya_X =  (int)random(30, 915);
    monkeyaY = -50;
  }
  
  if (monkeybY < 300) {
    monkeyaY += (int) random(5,6);
  } else {
    monkeyb_X = (int)random(30, 915);
    monkeybY = -50;
  }
  
  
  if (monkeya_X >= netLeft && netLeft + netWidth >= monkeya_X + monkeyWidth && monkeyaY == 300 | monkeyb_X >= netLeft && netLeft + netWidth >= monkeyb_X + monkeyWidth && monkeybY == 300) {
      Score++;
    
  }
  
  
  
    fill(225,225,225);
    textSize(20);
    text("your score is: " + Score, 30, 30);  
  
  }

  

These are the images:

(url)

https://www.dropbox.com/sh/yfmfvp59xdc6n3z/AAB2LDcKUn7uApQF-OAfCf1ja?dl=0

Whoa there. Back up a second. Your sketch’s code has some fundamental and common problems.

First things first: You need to load all your images in setup(). If you’re loading them in draw() (or a function that draw() calls, like Imgs()), then they are being reloaded 60 times a second and your sketch’s performance is going in the toilet.

Second thing: You have several calls to delay() in the middle of your code. You don’t want those at all. The delay() function does not do what you think it does. It is not the function you want. It is the wrong function to use in this context. Your code will be 300% better off without those call to delay in it.

Third: I’ve fixed some capitalization issues (where I see them) to match the standards people expect. This also involved renaming your images (sorry, but I saved them without capital letters so you might just want to change your image names to match…).

So after taking your code to the cleaners, we get this:

int monkeyaY = -50;
int monkeybY = -50;
int monkeya_X = 0;
int monkeyb_X = 0;
int monkeyWidth = 76; 
int counter;
int score;
int netLeft = 0;
int netWidth = 118;
int netPointPos = 0;
int randDelay = 0;
int fallType = 0;
int randSpeed = 0;

PImage bg, monkey, net, cursor;

void setup() {

  size(1024, 386);
  bg = loadImage("background.png");
  monkey = loadImage("monkey.png");
  net = loadImage("net.png");
  cursor = loadImage("cursor.png");
  cursor(cursor);
  fallType = (int) random(0, 3);
}

void imgs() {

  background(bg);
  
  fallType = (int) random(0, 3);
  randDelay = (int) random(0, 100);
  

  if (fallType == 0) {
    image(monkey, monkeya_X, monkeyaY);
  } else if (fallType == 1) {
    image(monkey, monkeya_X, monkeyaY);
    // delay(randDelay); // NO! AWEFUL! DO NOT USE DELAY!
    image(monkey, monkeyb_X, monkeybY);
  } else if (fallType == 2) {

    image(monkey, monkeya_X, monkeyaY);
    // delay(50); // NO! BAD! DO NOT USE DELAY!
    image(monkey, monkeyb_X, monkeybY);
  } else if (fallType == 3) {

    // delay(randDelay); // I WISH I COULD EXPRESS HOW TERRIBLE THESE ARE!
    image(monkey, monkeya_X, monkeyaY);
  }
  
  netPointPos = mouseX - netWidth/2;
  netLeft = mouseX - netWidth/2;
  image(net, netPointPos, 275);
}

void draw() {
  
  imgs();

  if (monkeyaY < 300) {
    monkeyaY += (int) random(5, 6);
  } else {
    monkeya_X =  (int)random(30, 915);
    monkeyaY = -50;
  }

  if (monkeybY < 300) {
    monkeyaY += (int) random(5, 6);
  } else {
    monkeyb_X = (int)random(30, 915);
    monkeybY = -50;
  }

  if (monkeya_X >= netLeft && netLeft + netWidth >= monkeya_X + monkeyWidth && monkeyaY == 300 | monkeyb_X >= netLeft && netLeft + netWidth >= monkeyb_X + monkeyWidth && monkeybY == 300) {
    score++;
  }
  
  fill(225, 225, 225);
  textSize(20);
  text("your score is: " + score, 30, 30);
}

This is just a first step. But look how much smoother and faster it runs already!

2 Likes

Next, some restructuring.

Because you may potentially have several monkeys all going at once, it makes sense to write a class that defines the monkeys as a new type of object. This way we can have one place that defines how a monkey behaves, and all monkeys will share that behavior. It also allows us to give each monkey it’s own set of variables (like a position or the fact that it has been counted when it entered the net) without making a fuss with many arrays of variables. You can just have the one array (for now) of falling monkey objects.

int monkeyWidth = 76;
int score = 0;
int netLeft = 0;
int netWidth = 118;

PImage bg, monkey, net, cursor;

class FallingMonkey {
  float x, y;
  int type;
  boolean counted;
  FallingMonkey(){
    reset();
  }
  void reset(){
    type = int(random(3));
    x = random(30,915);
    y = random(-100,-50);
    counted = false;
  }
  void draw(){
    y++; // TODO: Adjust this.  
    image(monkey, x, y);
    if( inNet() && !counted ){
      counted = true;
      score++;
    }
    if( y > 300 ){
      reset();
    }
  }
  boolean inNet(){
    return( x >= netLeft && netLeft + netWidth >= x + monkeyWidth && y >= 300 );
  }
}

FallingMonkey[] falling_monkeys = new FallingMonkey[2];


void setup() {
  size(1024, 386);
  // Load images.
  bg = loadImage("background.png");
  monkey = loadImage("monkey.png");
  net = loadImage("net.png");
  cursor = loadImage("cursor.png");
  // Set cursor image.
  cursor(cursor);
  // Create initial monkeys.
  for( int i = 0; i < falling_monkeys.length; i++){
    falling_monkeys[i] = new FallingMonkey();
  }
}

void draw() {
  // Draw background.
  background(bg);
  // Draw monkeys.
  for( int i = 0; i < falling_monkeys.length; i++){
    falling_monkeys[i].draw();
  }
  // Draw net.
  netLeft = mouseX - netWidth/2;
  image(net, netLeft, 275);  
  // Draw score.
  fill(225, 225, 225);
  textSize(20);
  text("your score is: " + score, 30, 30);
}

Simplifying this code has also blown away several issues with it! The monkey in the top left is no longer stuck. Better yet, monkeys that fall into the net count for score!

1 Like

More restructuring. Instead of an array of two monkeys, we can actually use an ArrayList that lets us have as many as we want. New ones need to periodically appear, so we’ll add a time variable that will determine when the next one should appear. We’ll also update the draw() function of the monkeys to return true if it is time for that monkey to be removed. And since no monkey is being re-used now, having a reset() function in the class makes no sense (just create a new monkey instead).

Tweaking. The monkeys fall slowly, so let’s vary the speed they fall at. Monkeys that aren’t caught in the net just sort of vanish - that seems odd. Let’s have them fall off the bottom of the screen. This means that monkeys are removed either when they have a y position greater that height or they got caught in the net and counted.

int monkeyWidth = 76;
int score = 0;
int netLeft = 0;
int netWidth = 118;
int time;

PImage bg, monkey, net, cursor;

class FallingMonkey {
  float x, y, dy;
  int type;
  boolean counted;
  FallingMonkey(){
    type = int(random(3));
    x = random(30,915);
    y = random(-100,-50);
    dy = random(2,5);
    counted = false;
  }
  boolean draw(){
    y+=dy;  
    image(monkey, x, y);
    if( inNet() && !counted ){
      counted = true;
      score++;
    }
    return( y > height  || counted ); // 300 );
  }
  boolean inNet(){
    return( x >= netLeft && netLeft + netWidth >= x + monkeyWidth && y >= 300 );
  }
}

ArrayList<FallingMonkey> falling_monkeys = new ArrayList();


void setup() {
  size(1024, 386);
  // Load images.
  bg = loadImage("background.png");
  monkey = loadImage("monkey.png");
  net = loadImage("net.png");
  cursor = loadImage("cursor.png");
  // Set cursor image.
  cursor(cursor);
  // Cause a new monkey to spawn immediately.
  time = -1; 
}

void draw() {
  // Draw background.
  background(bg);
  // Update net position as the monkey-in-net check uses this value.
  netLeft = mouseX - netWidth/2;
  // Spawn a new monkey, if it's time.
  if( millis() > time ){
    // Pick the next time.
    time = millis() + int(random(1000, 5000));
    falling_monkeys.add( new FallingMonkey() );
  }
  // Draw monkeys, removing any that have reached the bottom.
  for( int i = falling_monkeys.size()-1; i>= 0; i--){
    if( falling_monkeys.get(i).draw() ){
      falling_monkeys.remove(i);
    }
  }
  // Draw net.  
  image(net, netLeft, 275);  
  // Draw score.
  fill(225, 225, 225);
  textSize(20);
  text("Your score is: " + score, 30, 30);
}
1 Like

Where you go with this from here is up to you. Click! ARGH MONKEYS SPINNING ALL OVER!

int monkeyWidth = 76;
int score = 0;
int netLeft = 0;
int netWidth = 118;
int time;

PImage bg, monkey, net, cursor;

class FallingMonkey {
  float x, y, dy;
  //int type;
  boolean counted;
  float a, da;
  FallingMonkey(){
    //type = int(random(3));
    x = random(30,915);
    y = random(-100,-50);
    dy = random(2,5);
    counted = false;
    a = random(TWO_PI);
    da = random(-.2,.2);
  }
  boolean draw(){
    y+=dy;
    a+=da;
    pushMatrix();
    translate(x,y);
    rotate(a);
    image(monkey, -monkey.width/2, -monkey.height/2);
    popMatrix();
    //ellipse(x,y,20,20); // for debugging - show monkey true position
    if( inNet() && !counted ){
      counted = true;
      score++;
    }
    return( y > height  || counted ); // 300 );
  }
  boolean inNet(){
    return( netLeft <= x && x <= netLeft + netWidth && y >= 300 );
  }
}

ArrayList<FallingMonkey> falling_monkeys = new ArrayList();


void setup() {
  size(1024, 386);
  // Load images.
  bg = loadImage("background.png");
  monkey = loadImage("monkey.png");
  net = loadImage("net.png");
  cursor = loadImage("cursor.png");
  // Set cursor image.
  cursor(cursor);
  // Cause a new monkey to spawn immediately.
  time = -1; 
}

void draw() {
  // Draw background.
  background(bg);
  // Update net position as the monkey-in-net check uses this value.
  netLeft = mouseX - netWidth/2;
  // For debugging - show net boundry.
  //stroke(255,0,0);
  //line(netLeft, height, netLeft, height-100);
  //line(netLeft+netWidth, height, netLeft+netWidth, height-100);
  // Spawn a new monkey, if it's time.
  if( millis() > time ){
    // Pick the next time.
    time = millis() + int(random(1000, 5000));
    if( falling_monkeys.size() < 300 ){
      falling_monkeys.add( new FallingMonkey() );
    }
  }
  // Draw monkeys, removing any that have reached the bottom.
  for( int i = falling_monkeys.size()-1; i>= 0; i--){
    if( falling_monkeys.get(i).draw() ){
      falling_monkeys.remove(i);
    }
  }
  // Draw net.  
  image(net, netLeft, 275);  
  // Draw score.
  fill(225, 225, 225);
  textSize(20);
  text("Your score is: " + score, 30, 30);
}

void mousePressed(){
  // Monkey explosion!
  for( int t = 0; t < 100 ; t++ ){
    if( falling_monkeys.size() < 300 ){
      falling_monkeys.add( new FallingMonkey() );
    }
  }
}
1 Like

Thank you, but I have one problem.

It says:

size() cannot be used here.

what should I do ?

Post the smallest amount of code that causes that error.

Sorry , false alarm. original code was interfering with the new code