Click and point game with array - troubleshooting

Hi,

I’m making a click and point type of game. I want to sort fishes by their color. I want to remove the blue fishes from the big aquarium and “store” them for further use in the small aquarium.

I putting here what I’ve done so far. I can click on the pink fishes and make them disappear. But it ist not what I want to do and I can’t find the way to do it for the blue ones.

Here is my code :

let aquarium;
let inventaireblue;
let fishs = [];
let fishblue1;
let fishblue2;

function setup() {
  createCanvas(1200, 700);
  inventaireblue = new Inventaire(1060, 150, 150);  
  aquarium = new Aquarium(600, 350, 650);
  for (let i = 0; i < 10; i++) {
    let x = random(500, 700);
    let y = random(200, 500);
    let xspeed = random(1, 3);
    let yspeed = random(1, 3);
    let rbody = 100;
    let fscale = random(0.6, 0.8);
    fishs[i] = new Fish(x, y, rbody, color(255, 0, 204), xspeed, yspeed, fscale);
    
  }
  fishblue1 = new Fish(random(500, 700), random(200, 500), 100, color(51, 153, 255), random(1, 3), random(1, 3), random(0.6, 0.8));
  fishblue2 = new Fish(random(500, 700), random(200, 500), 100, color(51, 153, 255), random(1, 3), random(1, 3), random(0.6, 0.8));
}

function mousePressed() {
  for (let i = fishs.length - 1; i >= 0; i--) {
    if (fishs[i].inside(mouseX, mouseY)) { 
      fishs.splice(i, 1);
    }
  }
}

function draw() {
  inventaireblue.show();
  aquarium.show();

  //Fishes that stay in the aquarium
  for (let i = 0; i < fishs.length; i++) {
    push();
    fishs[i].move();
    fishs[i].show();
    pop();
  }

  //Fisches that go into the Inventory
  //Fish blue #1
  if (fishblue1.inside(mouseX, mouseY)){
    fishblue1.changeColor(color(10, 150, 30));
  }else {
    fishblue1.changeColor(color(51, 153, 255));
  }
  push();
  fishblue1.show();
  fishblue1.move();
  pop();
  //Fish blue #2
  if (fishblue2.inside(mouseX, mouseY)){
    fishblue2.changeColor(color(10, 150, 30));
  }else {
    fishblue2.changeColor(color(51, 153, 255));
  }
  push();
  fishblue2.show();
  fishblue2.move();
  pop();  
}

//INVENTORY
class Inventaire {
  constructor(tempX, tempY, tempR) {
    this.x = tempX;
    this.y = tempY;
    this.r = tempR;
  }

  show() {
    fill(171, 252, 255);
    stroke(51, 153, 255);
    strokeWeight(10);
    ellipse(this.x, this.y, this.r);
  }

}

//AQUARIUM
class Aquarium {
  constructor(tempX, tempY, tempR) {
    this.x = tempX;
    this.y = tempY;
    this.r = tempR;
  }

  show() {
    fill(171, 252, 255);
    stroke(255, 0, 204);
    strokeWeight(20);
    ellipse(this.x, this.y, this.r);
  }
}

//FISH
class Fish {
  constructor(tempX, tempY, tempRbody, tempColor, tempXspeed, tempYspeed, tempScale) {
    this.x = tempX;
    this.y = tempY;
    this.color = tempColor;
    this.xspeed = tempXspeed;
    this.yspeed = tempYspeed;
    this.rbody = tempRbody;
    this.fscale = tempScale;
    this.unsorted = true;
  }

  inside(px, py) {
    let d = dist(px, py, this.x, this.y);
    if (d < 50) {
      return true;
    } else {
      return false;
    }
  }

  changeColor(Color2) {
    this.color = Color2;
  }
  
  changeSide() {
    if (this.xspeed > 0) {
      scale (this.scale = 5, this.scale);
    } 
 }

  move() {
    let d2 = dist(this.x, this.y, aquarium.x, aquarium.y);
    if (d2 > 200 || this.y < 200) {
      this.xspeed = this.xspeed * -1;
      this.yspeed = this.yspeed * -1;
    }
    this.x = this.x + this.xspeed;
    this.y = this.y + this.yspeed;
  }

  show() {
      //corps droite
      if (this.xspeed > 0) {
        translate(this.x, this.y);
        scale(this.fscale);
        fill(this.color);
        stroke(0);
        strokeWeight(3);
        ellipse(0, 0, 100, 100);
        //queue
        triangle(- 50, 0, - 100, - 50, 0 - 100, 50);
        //aileron
        triangle(0, 10, 5, 30,  - 30, 30);
        //yeux
        fill(255);
        ellipse(15,  - 10, 30, 30);
        fill(0);
        ellipse(15, - 10, 15, 15);
      } else {    
        //corps gauche
        translate(this.x, this.y);
        scale(this.fscale);
        fill(this.color);
        stroke(0);
        strokeWeight(3);
        ellipse(0, 0, 100, 100);
        //queue
        triangle(50, 0, 100, - 50, 100, 50);
        //aileron
        triangle(0, 10,  - 5, 30, 30, 30);
        //yeux
        fill(255);
        ellipse(- 15, - 10, 30, 30);
        fill(0);
        ellipse(- 15, - 10, 15, 15);
      }
    }
}

This is the function mousePressed(), right?

You are using splice, but this is for joining two arrays afaik

Do you want to add a fish? Try push() maybe?

see Array.prototype.push() - JavaScript | MDN

(see also reference | p5.js)

You can check the 2 fishs in mousePressed() also, without a for-loop, so simply after the for-loop.

If they are clicked set a boolean (hasBeenClicked) inside the class to true. It is initially false.

Now when displaying the fishs, check if hasBeenClicked is false or true.

  • If it’s false display the fishs traditionally.

  • If it’s true, display the fishs in the other, small aquarium. (“store” them for further use in the small aquarium)

Warm regards,

Chrisir

Thank you so much for this.

I removed mousePressed function for the pink fishes since I didn’t need it. I just want them to swim around with no interaction.

I’m not sure if I put the boolean (hasBeenClicked) at the right suggested place, but it works. I can display fishes in the small aquarium.

But I have two questions:

  1. If fishblue1 is clicked first, fishblue2 will not appear in the small aquarium - even though it was clicked - as shown in the console

  2. I would like to have the blue fishes in the big aquarium disappear when mousePressed. In javascript, I simply use “display = ‘none’” to do that. I can’t seem to find the right way in p5. Is there a solution?

Here is my modified code:

let aquarium;
let inventaireblue;
let fishs = [];
let fishblue1;
let fishblue2;
let fishblueinv1;
let fishblueinv2;
let hasBeenClicked1 = false;
let hasBeenClicked2 = false;

function setup() {
  createCanvas(1200, 700);
  inventaireblue = new Inventaire(1060, 150, 150);  
  aquarium = new Aquarium(600, 350, 650);
  for (let i = 0; i < 10; i++) {
    let x = random(500, 700);
    let y = random(200, 500);
    let xspeed = random(1, 3);
    let yspeed = random(1, 3);
    let rbody = 100;
    let fscale = random(0.6, 0.8);
    fishs[i] = new Fish(x, y, rbody, color(255, 0, 204), xspeed, yspeed, fscale);
    
  }
  fishblue1 = new Fish(random(500, 700), random(200, 500), 100, color(51, 153, 255), random(1, 3), random(1, 3), random(0.6, 0.8));
  fishblueinv1 = new Fish(1050, 170, 100, color(51, 153,255), random(1,3), random(1,3), 0.3);
  fishblueinv2 = new Fish(1060, 350, 100, color(51, 153,255), random(1,3), random(1,3), 0.3);
  fishblue2 = new Fish(random(500, 700), random(200, 500), 100, color(51, 153, 255), random(1, 3), random(1, 3), random(0.6, 0.8));
}

function draw() {
  inventaireblue.show();
  aquarium.show();

  //Fishes that stay in the aquarium
  for (let i = 0; i < fishs.length; i++) {
    push();
    fishs[i].move();
    fishs[i].show();
    pop();
  }

  //Intruder fishes
  //Fish blue #1
  push();
  fishblue1.show();
  fishblue1.move();
  pop();
  //Fish blue #2
  push();
  fishblue2.show();
  fishblue2.move();
  pop();   

  //Fishes in the blue inventory
  if (hasBeenClicked1 == true) {
    fishblueinv1.show();
  }
  if (hasBeenClicked2 == true) {
  fishblueinv2.show();
  }
}

function mousePressed() {
  if(fishblue1.inside(mouseX, mouseY)){
    hasBeenClicked1 = true;
    print('fish#1 clicked');
  }
  if(fishblue2.inside(mouseX, mouseY)){
    hasBeenClicked2 = true;
    print('fish#2 clicked');
  }
}


//INVENTORY
class Inventaire {
  constructor(tempX, tempY, tempR) {
    this.x = tempX;
    this.y = tempY;
    this.r = tempR;
  }

  show() {
    fill(171, 252, 255);
    stroke(51, 153, 255);
    strokeWeight(10);
    ellipse(this.x, this.y, this.r);
  }
}

//AQUARIUM
class Aquarium {
  constructor(tempX, tempY, tempR) {
    this.x = tempX;
    this.y = tempY;
    this.r = tempR;
  }

  show() {
    fill(171, 252, 255);
    stroke(255, 0, 204);
    strokeWeight(20);
    ellipse(this.x, this.y, this.r);
  }
}

//FISH
class Fish {
  constructor(tempX, tempY, tempRbody, tempColor, tempXspeed, tempYspeed, tempScale) {
    this.x = tempX;
    this.y = tempY;
    this.color = tempColor;
    this.xspeed = tempXspeed;
    this.yspeed = tempYspeed;
    this.rbody = tempRbody;
    this.fscale = tempScale;
  }

  inside(px, py) {
    let d = dist(px, py, this.x, this.y);
    if (d < 50) {
      return true;
    } else {
      return false;
    }
  }

  changeColor(Color2) {
    this.color = Color2;
  }
  
  changeSide() {
    if (this.xspeed > 0) {
      scale (this.scale = 5, this.scale);
    } 
 }

  move() {
    let d2 = dist(this.x, this.y, aquarium.x, aquarium.y);
    if (d2 > 200 || this.y < 200) {
      this.xspeed = this.xspeed * -1;
      this.yspeed = this.yspeed * -1;
    }
    this.x = this.x + this.xspeed;
    this.y = this.y + this.yspeed;
  }

  show() {
      //corps droite
      if (this.xspeed > 0) {
        translate(this.x, this.y);
        scale(this.fscale);
        fill(this.color);
        stroke(0);
        strokeWeight(3);
        ellipse(0, 0, 100, 100);
        //queue
        triangle(- 50, 0, - 100, - 50, 0 - 100, 50);
        //aileron
        triangle(0, 10, 5, 30,  - 30, 30);
        //yeux
        fill(255);
        ellipse(15,  - 10, 30, 30);
        fill(0);
        ellipse(15, - 10, 15, 15);
      } else {    
        //corps gauche
        translate(this.x, this.y);
        scale(this.fscale);
        fill(this.color);
        stroke(0);
        strokeWeight(3);
        ellipse(0, 0, 100, 100);
        //queue
        triangle(50, 0, 100, - 50, 100, 50);
        //aileron
        triangle(0, 10,  - 5, 30, 30, 30);
        //yeux
        fill(255);
        ellipse(- 15, - 10, 30, 30);
        fill(0);
        ellipse(- 15, - 10, 15, 15);
      }
    }
}

should be INSIDE the class

also INSIDE the class check whether it’s true and then in show() display it either in the big aquarium OR in the small one

(I tried to explain in my previous answer)

This is what I was not able to do following your previous answer. I did try to put hasBeenClicked inside the class, but i didn’t know where. If it is in the constructor, how can I formulate it? I tried this.mousePressed = hasBeenClicked, but didn’t work because hasbeenClicked was not defined. Where do I declare it?

And does the mousePressed function has to be inside the class to? And how the hasBeenClicked and the mousePressed function relate to each other?

I know it must seem like very basics questions - but i’m confused with the class concept (and other concepts too : I’m an enthusiast beginner - i started from a homework assignement for a static game, but decided to take it further with p5.js - which I do just for fun with my teenager / not part of the homework).

yeah, put it inside the constructor

    this.hasBeenClicked  = false; 

Then

 show() {
      //corps droite
      if (this.xspeed > 0) {

here say

 show() {
    if(hasBeenClicked ) {

new code to display the fish in the small aquarium? 

}
else {

// what you have now in show!!!

      //corps droite
      if (this.xspeed > 0) {
     } else {

    } //else

} // else 

in mousePressed() outside the class you can write

  if(fishblue1.inside(mouseX, mouseY)){
    fishblue1.hasBeenClicked = true;
    print('fish#1 clicked');
  }

It worked!!! And it allowed me to “clean” my setup function and get a better understanding of the constructor. Thank you very much. I can now move to a next step in my game.

Here is my new code:

let aquarium;
let inventaireblue;
let fishs = [];
let fishblue1;
let fishblue2;

function setup() {
  createCanvas(1200, 700);
  inventaireblue = new Inventaire(1060, 150, 150);  
  aquarium = new Aquarium(600, 350, 650);
  for (let i = 0; i < 10; i++) {
    fishs[i] = new Fish(color(255, 0, 204));
    fishblue1 = new Fish(color(51, 153, 255));
    fishblue2 = new Fish(color(51, 153, 255));
}
}

function draw() {
  inventaireblue.show();
  aquarium.show();

  //Fishes that stay in the aquarium
  for (let i = 0; i < fishs.length; i++) {
    push();
    fishs[i].move();
    fishs[i].show();
    pop();
  }

  //Intruder fishes
  //Fish blue #1
  push();
  fishblue1.show();
  fishblue1.move();
  pop();
  //Fish blue #2
  push();
  fishblue2.show();
  fishblue2.move();
  pop();
}

function mousePressed() {
  if(fishblue1.inside(mouseX, mouseY)){
    fishblue1.hasBeenClicked = true;
    print('fish#1 clicked');
  }
  if(fishblue2.inside(mouseX, mouseY)){
    fishblue2.hasBeenClicked = true;
    print('fish#2 clicked');
  }
}


//INVENTORY
class Inventaire {
  constructor(tempX, tempY, tempR) {
    this.x = tempX;
    this.y = tempY;
    this.r = tempR;
  }

  show() {
    fill(171, 252, 255);
    stroke(51, 153, 255);
    strokeWeight(10);
    ellipse(this.x, this.y, this.r);
  }
}

//AQUARIUM
class Aquarium {
  constructor(tempX, tempY, tempR) {
    this.x = tempX;
    this.y = tempY;
    this.r = tempR;
  }

  show() {
    fill(171, 252, 255);
    stroke(255, 0, 204);
    strokeWeight(20);
    ellipse(this.x, this.y, this.r);
  }
}

//FISH
class Fish {
  constructor(tempColor) {
    this.x = random(500,700);
    this.y = random(200,500);
    //x y inventaire
    this.x2 = random(1050, 1100);
    this.y2 = random(100, 200);
    this.color = tempColor;
    this.xspeed = random(1,3);
    this.yspeed = random(1,3);
    this.rbody = 100;
    this.fscale = random(0.6, 0.8);
    this.hasBeenClicked = false;
  }

  inside(px, py) {
    let d = dist(px, py, this.x, this.y);
    if (d < 50) {
      return true;
    } else {
      return false;
    }
  }

  //changeColor(Color2) {
    //this.color = Color2;
  //}

  changePosition(Position2) {
    this.position = Position2;
  }
  
  changeSide() {
    if (this.xspeed > 0) {
      scale (this.scale = 5, this.scale);
    } 
  }


  move() {
    if (this.hasBeenClicked){
      this.xspeed = 0;
      this.yspeed = 0;
    }
    let d2 = dist(this.x, this.y, aquarium.x, aquarium.y);
    if (d2 > 200 || this.y < 200) {
      this.xspeed = this.xspeed * -1;
      this.yspeed = this.yspeed * -1;
    }
    this.x = this.x + this.xspeed;
    this.y = this.y + this.yspeed;
  }

  show() {
    if (this.hasBeenClicked) {
      translate(this.x = this.x2, this.y = this.y2);
      scale(0.3);
      fill(this.color);
      stroke(0);
      strokeWeight(3);
      ellipse(0, 0, 100, 100);
      //queue
      triangle(- 50, 0, - 100, - 50, 0 - 100, 50);
      //aileron
      triangle(0, 10, 5, 30,  - 30, 30);
      //yeux
      fill(255);
      ellipse(15,  - 10, 30, 30);
      fill(0);
      ellipse(15, - 10, 15, 15);
      //this.xspeed=0.5;
      //this.yspeed=0.2;
    } else {
      //corps droite
      if (this.xspeed > 0) {
        translate(this.x, this.y);
        scale(this.fscale);
        fill(this.color);
        stroke(0);
        strokeWeight(3);
        ellipse(0, 0, 100, 100);
        //queue
        triangle(- 50, 0, - 100, - 50, 0 - 100, 50);
        //aileron
        triangle(0, 10, 5, 30,  - 30, 30);
        //yeux
        fill(255);
        ellipse(15,  - 10, 30, 30);
        fill(0);
        ellipse(15, - 10, 15, 15);
      } else {    
        //corps gauche
        translate(this.x, this.y);
        scale(this.fscale);
        fill(this.color);
        stroke(0);
        strokeWeight(3);
        ellipse(0, 0, 100, 100);
        //queue
        triangle(50, 0, 100, - 50, 100, 50);
        //aileron
        triangle(0, 10,  - 5, 30, 30, 30);
        //yeux
        fill(255);
        ellipse(- 15, - 10, 30, 30);
        fill(0);
        ellipse(- 15, - 10, 15, 15);
      }
    }
  } 
}
1 Like