Image keeps being redrawn after 'deleted'

Hi all,

I am working on a game in processing where a Fish needs to eat some food.
I used object collision detection to know when the fish collided with a food object, and then want to delete that object. For this I used some boolean statements.
Unfortunately after I tell the program to not redraw the image after collision, it keeps redrawing and deleting the object.

What am I doing wrong?

Here is a screenshot of the situation;

you don’t really see it that well, but one of these ‘Corn objects’ where the fish collided with, is not deleted but redrawn and deleted every frame. (i think)

Here is my code;

/*
 CREATIVE CHALLENGE 2: EGBERT THE FISH GAME_version_11
 DATE: 23_10_2022
 AUTHOR: TAISSIA VISSER
 
 REFERENCES:
 https://www.youtube.com/watch?v=jUmjbFsA2zw&ab_channel=Crazy-Logic
 https://processing.org/examples/interpolate.html
 
 INSPIRATION:
 https://www.youtube.com/watch?v=NrwaKOsplZk&ab_channel=TheCodingTrain
 
 */

// Importing the serial library.
import processing.serial.*;

// Declare serial communication port
Serial myPort;
String inString;
int[] data = {0, 0, 1};   // Array of data received from the serial port

// Declare game characters
PImage Campus;
PImage EgbertRight;
PImage EgbertLeft;
PImage Corn;
PImage Plastic;
boolean dataValid = false;


Object A1;// creating objects by defining a new type
Object A2;
Object A3;
Object A4;
Object A5;
Object A6;
Object A7;
Object A8;

void setup() {
  size (1920, 1081);
  // printArray(Serial.list());

  A1 = new Object(); // constructor, make a new object and store it in variable A
  A2 = new Object();
  A3 = new Object();
  A4 = new Object();
  A5 = new Object();
  A6 = new Object();
  A7 = new Object();
  A8 = new Object();

  String myPortName = Serial.list()[2];
  myPort = new Serial(this, myPortName, 9600);
  myPort.bufferUntil('\n');
  Campus = loadImage("Artboard 1.png");
  EgbertRight = loadImage("Egbertred2.png");
  EgbertLeft = loadImage ("Egbertred2.2.png");
  Corn = loadImage("corn.png");
  Plastic = loadImage("plastic.png");
}

// initiating coordinate variables of joystick
float xPos;            // X data received through serial
float pastxPos;
float yPos;            // Y data received through serial
float pastyPos;

int Pressed;
float EgbertX;      // the X position of the Egbert Image
float EgbertY;      // the y position of the Egbert Image

void draw() {
  background(Campus);
  imageMode(CENTER);
  A1.display();   // calling display function from the object class, showing multiple objects
  A1.dissappear();
  A2.display();
  A3.display();
  A4.display();
  A5.display();
  A6.display();
  A7.display();
  A8.display();


  if (dataValid) {
    // mark new data is processed
    dataValid = false;
    // and process data

    // mapping the range of the X and Y input data of the Joystick to match the drawn pool
    // (I have found the correct X and Y coordinates by a mousepressed function to print the coordinates of every corner)
    if (mousePressed) {
      println("X position is", mouseX, "and Y position is", mouseY);
    }

    xPos = int(map(data[0], 0, 1023, 220, 1684));
    yPos = int(map(data[1], 0, 1023, 220, 855));
  }

  // translating the origin of egbert to the centre of the png of Egbert,
  // for correct mapping of the object. (Because the Png of Egbert has white space around it).

  // interpolating between the X of Y position of Egbert, and the movement of the joystick
  // moving 3% of the way to the joystick location each frame
  // to make sure the movement of the joystick is not so sensitive
  EgbertX = lerp(EgbertX, xPos, 0.03);
  EgbertY = lerp(EgbertY, yPos, 0.03);

  // the game character Egbert the fish is positioned at the X and Y coordinates
  // this data is received by the serial and was initialised with xPos and yPos.
  //println(" x positie van egbert =", EgbertX);
  image(EgbertLeft, EgbertX, EgbertY);
}

// will get called every time data comes in
// storing the data string here
void serialEvent(Serial myPort) {
  String inString = myPort.readStringUntil('\n');
  if (inString != null) {
    // removing the whitespace
    inString = trim(inString);
    // Splitting the string at the commas and
    // seperating the variables out into an array
    data = int(split(inString, ","));
    // mark new data is available
    dataValid = true;
  }
  //println(inString);
}

class Object {
  // template for creating an object
  // the data for the object, every object in this class will have this data.
  // every object in this class will have a objectlocation x and y
  float objectlocationX;
  float objectlocationY;
  boolean Collision = false; // did the fish collide with any objects?
  //float Measure = dist(xPos, yPos, objectlocationX, objectlocationY);
  boolean showObject = true;

  // constructor that will return the object
  Object () {
    objectlocationX= random(215, 1680); // the objectlocation x is random between these to values
    objectlocationY = random(215, 840); // the objectlocation y is also random between these to values
  }

  // the functionality of the object
  // all objects have the ability to excecute this function
  // displays the right images when calling the class
  void display() {
    //stroke(0);
    //fill(200);
    //ellipse(objectlocationX, objectlocationY, 100, 100);
    if (showObject) {
      imageMode(CENTER);
      image(Corn, objectlocationX, objectlocationY);

      //image(Plastic, objectlocationX, objectlocationY);
    }
  }

  void dissappear() {
    // checking weather Egbert 'overlaps' or 'collides' with one of the objects
    // is so, then erase that object,
    // if the distance between the object location x,y and Egbert, is smaller than 30,
    // then they 'overlap'.
    float distance = dist(objectlocationX, objectlocationY, EgbertX, EgbertY);
    if (distance < 30) {
      Collision = true;
    }
    // if the fish and an object collide, then erase that object.
    if (Collision) {
      showObject =! showObject;
      println("lekker");
      //fill(3);
      //ellipse(objectlocationX, objectlocationY, 100, 100);
    }
  }

Hi @Ties2901,

for the first set showObject=false, otherwise you are flipping on/off as long your fish collides for each draw.

Also I think you need to reconsider your approach. Maybe it would be better to put the food into an array and remove from it if the fish eats it. So you don’t need a dissappear function.
Just check if collides remove it from the array and ie. increment a food eaten counter or s.th. similar.

Cheers
— mnse

1 Like

Hi, mnse, I have all the food in an array now, but still have the disappearing function haha. Thanks for your top btw! it solved the problem.

1 Like

Hi mnse,

I have tried to put the food objects into an array now, but I am having some troubles with removing the right object, as the objects that are in the array are also part of a class.

I tried it two times with different code:
When Ebert the Fish Collides with one of these class objects I want it to erase that object from the array. I can not give a index value to remove that element, but it has to remove the element that Egbert has collided with. I tried to use a splice function and to use ‘i’ as index, but it gives me the error that ‘i’ cannot be resolved to a variable:

Objects.splice(i,1);

First I had the dissapearing function after collusion, where I stop the image from being drawn. I then wanted to count the times this dissapearing function was called, and make an if statement saying that when the amount of times this function is called is equal to the amount of the objects that where initially drawn (in other words, when all objects that where drawn are deleted), then move to the next screen to say ’ You have Won’ or something like this. For this I used a counter, in the class. Where for I initilized the countDissappear = 0 before the class…

int countDissappear = 0;

if (Collision) {
showObject = false;
//countDissappear += 1;
//println(countDissappear);

But unfortunately when one of the object collided with the fish, the counter would just continue to count, and not count just 1 time, each object was removed.

Basically, I tried these two systems in order to make sure after all objects are removed I can make a new screen/ game mode.

Any tips? :slight_smile:

/*
 CREATIVE CHALLENGE 2: EGBERT THE FISH GAME_version_16
 DATE: 02_11_2022
 AUTHOR: TAISSIA VISSER
 
 REFERENCES:
 https://www.youtube.com/watch?v=jUmjbFsA2zw&ab_channel=Crazy-Logic
 https://processing.org/examples/interpolate.html
 
 INSPIRATION:
 https://www.youtube.com/watch?v=NrwaKOsplZk&ab_channel=TheCodingTrain
 
 */

import processing.serial.*;        // Importing the serial library.
Serial myPort;                    // Declare serial communication port
String inString;
int[] data = {0, 0, 1};           // Array of data received from the serial port
boolean dataValid = false;

// initializing an array for the different images which will be placed
// on top of the objects in the game
PImage[] food = new PImage[3];

//  background
PImage Campus;

// Declare game character Egbert the fish
PImage EgbertRight;
PImage EgbertLeft;
float SizeW = 850;  // Height of Egbert
float SizeH = 800;  // Width of Egbert

// moving left or right?
//boolean movingLeft;
//boolean movingRight;
//float EgbertLastX;    // previous position of the Egbert Image

//initializing an array of objects of the class Object.
Object[] objects;

//=======================================  SETUP  =======================================================

void setup() {
  size (1920, 1081);
  // printArray(Serial.list());

  for (int i= 0; i<food.length; i++) {
    // Loading all object images in the PImage array and placing them in the right index.
    // for every food, load one of the food images
    // start with the string food, then take whatever value i is, and take that to the file name
    // to load the right food image.
    //food[i] = loadImage("food"+i+".png");
    food[0] = loadImage("food0.png");
    food[1] = loadImage("food1.png");
    food[2] = loadImage("food2.png");
  }

  //Creating the array with a lenght of 20 objects which will appear in the game
  objects = new Object[20];
  // loop where 'i' goes through the length of the array
  for (int i=0; i<objects.length; i++) {
    // giving a random value between 0 and the length of the array, which will be
    // converted into an integer, which will give a random object out of the array
    int index = int(random(0, food.length));
    // the object stores a variable that indicates which image it will display
    objects [i] = new Object(food[index]);
  }

  String myPortName = Serial.list()[2];
  myPort = new Serial(this, myPortName, 9600);
  myPort.bufferUntil('\n');
  Campus = loadImage("Artboard 1.png");
  EgbertRight = loadImage("Egbertred2.png");
  EgbertLeft = loadImage ("Egbertred2.2.png");
}

// initiating coordinate variables of the joystick
float xPos;            // X data received through serial
float yPos;            // Y data received through serial

int Pressed;
float EgbertX;      // the X position of the Egbert Image
float EgbertY;      // the y position of the Egbert Image


//=======================================  DRAW  ===================================================================

void draw() {
  background(Campus);

  // translating the origin of egbert to the centre of the png of Egbert,
  // for correct mapping of the object. (Because the Png of Egbert has white space around it).
  imageMode(CENTER);

  //calling display function from the object class, showing multiple objects
  //calling the dissappering function for all the objects
  for (int i=0; i<objects.length; i++) {
    objects[i].display();
    objects[i].dissappear();
  }

  if (dataValid) {
    // mark new data is processed
    dataValid = false;
    // and process data

    // mapping the range of the X and Y input data of the Joystick to match the drawn pool
    // (I have found the correct X and Y coordinates by a mousepressed function to print the coordinates of every corner)
    if (mousePressed) {
      println("X position is", mouseX, "and Y position is", mouseY);
    }
    xPos = int(map(data[0], 0, 1023, 220, 1684));
    yPos = int(map(data[1], 0, 1023, 220, 855));
  }

  // interpolating between the X of Y position of Egbert, and the movement of the joystick
  // moving 3% of the way to the joystick location each frame
  // to make sure the movement of the joystick is not so sensitive
  EgbertX = lerp(EgbertX, xPos, 0.03);
  EgbertY = lerp(EgbertY, yPos, 0.03);
  image(EgbertLeft, EgbertX, EgbertY, SizeW, SizeH);
  }

  // MOVING left or right?
  //if (frameCount%120==0){
  //println("xPos van de joystick is:",xPos,"EgbertLastX is:",EgbertLastX);
  //  println(xPos);
  //}

  /*if (EgbertLastX<xPos){
   movingLeft = true;
   } if (movingLeft){
   image(EgbertLeft, EgbertX, EgbertY, SizeW, SizeH);
   } else {
   movingRight = true;
   image(EgbertRight, EgbertX, EgbertY, SizeW, SizeH);
   }
   */

  // the game character Egbert the fish is positioned at the X and Y coordinates
  // this data is received by the serial and was initialised with xPos and yPos.
  //println(" x positie van egbert =", EgbertX);
  // the sizeX and Y are dependend on initialization and on how many food objects it eats


//=========================================  SERIAL EVENT   ================================================================
// will get called every time data comes in
// storing the data string here
void serialEvent(Serial myPort) {
  String inString = myPort.readStringUntil('\n');
  if (inString != null) {
    // removing the whitespace
    inString = trim(inString);
    // Splitting the string at the commas and
    // seperating the variables out into an array
    data = int(split(inString, ","));
    // mark new data is available
    dataValid = true;
  }
  //println(inString);
}
// global variable for counting the times the dissapearing function is called
int countDissappear = 0; 
  
class Object {
  // template for creating an object
  // the data for the object, every object in this class will have this data.
  // every object in this class will have a objectlocation x and y
  float objectlocationX;
  float objectlocationY;
  float distance;
  boolean Collision = false; // did the fish collide with any objects?
  boolean showObject = true;
  boolean Eating = false;
  PImage img;

  // constructor that will return the object
  // the object stores a variable temImg about what image it will display.
  Object (PImage tempImg) {
    objectlocationX= random(215, 1680); // the objectlocation x is random between these to values
    objectlocationY = random(215, 840); // the objectlocation y is also random between these to values
    img = tempImg;
  }

  //============================================  DISPLAY  =============================================================
  // the functionality of the object
  // all objects have the ability to excecute this function
  // displays the right images when calling the class
  void display() {
    //stroke(0);
    //fill(200);
    //ellipse(objectlocationX, objectlocationY, 100, 100);
    if (showObject) {
      imageMode(CENTER);
      // showing a random food object from the array of food.
      // Some objects to draw food1, some to draw food2 and some to draw food3 etc.
      // object stores a reference to the index of the array.
      // at the attained object location X,Y (which is random)
      image(img, objectlocationX, objectlocationY);
    }  
  }

  //=================================================  DISAPPEAR  ================================================
  void dissappear() {
    // checking weather Egbert 'overlaps' or 'collides' with one of the objects
    // is so, then erase that object,
    // if the distance between the object location x,y and Egbert, is smaller than 30,
    // then they 'overlap'.
    distance = dist(objectlocationX, objectlocationY, EgbertX, EgbertY);
    if (distance < 30) {
      Collision = true;
      // whenever the fish eats a food object, it will increase in size
      SizeW = SizeW +10;
      SizeH = SizeH +10;
     
    }
    // if the fish and an object collide, then erase that object by making the showObject boolean false,
    // and the if statement in the display function will then not be called.
    if (Collision) {
      showObject = false;
        //countDissappear += 1; 
        //println(countDissappear);
      //println("lekker");
    }
  }
}

Hi @Ties2901,

you can try s.th like this… (not tested but should work. maybe typos but you should get the idea)
And please rename class Object to better naming ie. class Food…
Why renaming?
Java Object Class - Javatpoint.

Cheers
— mnse

Also this isn’t needed. Only need one fish picture (ie. looking right)

if controller direction goes right display as is

  pushMatrix();
  imageMode(CENTER);
  translate(x,y);
  image(fish,0,0);
  popMatrix();

and if controller goes left use:

  pushMatrix();
  imageMode(CENTER);
  translate(x,y);
  scale(-1, 1); // flip image on X coord
  image(fish,0,0);
  popMatrix();

Cheers
— mnse

1 Like

Hey, okay yeah so it is probably easier to convert the array to an array list then? Is there also a way to store the amount of times that a boolean Showobject returns false?

I have written this now:

for (int i = 0; i < objects.length; i++)
if (objects[i].showObject == true) {
allEaten = false;
}
if (allEaten) {
println(“YOU WON”);
}

but it does not print YOU WON after I eat the objects…
I am making this so that I can make an IF statement, when AllEaten = true go to the next game mode.

/*
 CREATIVE CHALLENGE 2: EGBERT THE FISH GAME_version_16
 DATE: 02_11_2022
 AUTHOR: TAISSIA VISSER
 
 REFERENCES:
 https://www.youtube.com/watch?v=jUmjbFsA2zw&ab_channel=Crazy-Logic
 https://processing.org/examples/interpolate.html
 
 INSPIRATION:
 https://www.youtube.com/watch?v=NrwaKOsplZk&ab_channel=TheCodingTrain
 
 */

import processing.serial.*;        // Importing the serial library.
Serial myPort;                    // Declare serial communication port
String inString;
int[] data = {0, 0, 1};           // Array of data received from the serial port
boolean dataValid = false;

// initializing an array for the different images which will be placed
// on top of the objects in the game
PImage[] food = new PImage[3];

//  background
PImage Campus;

// Declare game character Egbert the fish
PImage EgbertRight;
PImage EgbertLeft;
float SizeW = 850;  // Height of Egbert
float SizeH = 800;  // Width of Egbert

boolean allEaten = true; 
// initiating coordinate variables of the joystick
float xPos;            // X data received through serial
float yPos;            // Y data received through serial

int Pressed;
float EgbertX;      // the X position of the Egbert Image
float EgbertY;      // the y position of the Egbert Image

// moving left or right?
//boolean movingLeft;
//boolean movingRight;
//float EgbertLastX;    // previous position of the Egbert Image

//initializing an array of objects of the class Object.
Object[] objects;

//=======================================  SETUP  =======================================================

void setup() {
  size (1920, 1081);
  // printArray(Serial.list());

  for (int i= 0; i<food.length; i++) {
    // Loading all object images in the PImage array and placing them in the right index.
    // for every food, load one of the food images
    // start with the string food, then take whatever value i is, and take that to the file name
    // to load the right food image.
    //food[i] = loadImage("food"+i+".png");
    food[0] = loadImage("food0.png");
    food[1] = loadImage("food1.png");
    food[2] = loadImage("food2.png");
  }

  //Creating the array with a lenght of 20 objects which will appear in the game
  objects = new Object[2];
  // loop where 'i' goes through the length of the array
  for (int i=0; i<objects.length; i++) {
    // giving a random value between 0 and the length of the array, which will be
    // converted into an integer, which will give a random object out of the array
    int index = int(random(0, food.length));
    // the object stores a variable that indicates which image it will display
    objects [i] = new Object(food[index]);
  }

  String myPortName = Serial.list()[2];
  myPort = new Serial(this, myPortName, 9600);
  myPort.bufferUntil('\n');
  Campus = loadImage("Artboard 1.png");
  EgbertRight = loadImage("Egbertred2.png");
  EgbertLeft = loadImage ("Egbertred2.2.png");
}


//=======================================  DRAW  ===================================================================

void draw() {
  background(Campus);

  // translating the origin of egbert to the centre of the png of Egbert,
  // for correct mapping of the object. (Because the Png of Egbert has white space around it).
  imageMode(CENTER);

  //calling display function from the object class, showing multiple objects
  //calling the dissappering function for all the objects
  for (int i=0; i<objects.length; i++) {
    objects[i].display();
    objects[i].dissappear();
  }

  if (dataValid) {
    // mark new data is processed
    dataValid = false;
    // and process data

    // mapping the range of the X and Y input data of the Joystick to match the drawn pool
    // (I have found the correct X and Y coordinates by a mousepressed function to print the coordinates of every corner)
    if (mousePressed) {
      println("X position is", mouseX, "and Y position is", mouseY);
    }
    xPos = int(map(data[0], 0, 1023, 220, 1684));
    yPos = int(map(data[1], 0, 1023, 220, 855));
  }

  // interpolating between the X of Y position of Egbert, and the movement of the joystick
  // moving 3% of the way to the joystick location each frame
  // to make sure the movement of the joystick is not so sensitive
  EgbertX = lerp(EgbertX, xPos, 0.03);
  EgbertY = lerp(EgbertY, yPos, 0.03);
  image(EgbertLeft, EgbertX, EgbertY, SizeW, SizeH);

  for (int i = 0; i < objects.length; i++)
    if (objects[i].showObject == true) {
      allEaten = false;
    }
 if (allEaten) {
    println("YOU WON");
  }
}

// MOVING left or right?
//if (frameCount%120==0){
//println("xPos van de joystick is:",xPos,"EgbertLastX is:",EgbertLastX);
//  println(xPos);
//}

/*if (EgbertLastX<xPos){
 movingLeft = true;
 } if (movingLeft){
 image(EgbertLeft, EgbertX, EgbertY, SizeW, SizeH);
 } else {
 movingRight = true;
 image(EgbertRight, EgbertX, EgbertY, SizeW, SizeH);
 }
 */

// the game character Egbert the fish is positioned at the X and Y coordinates
// this data is received by the serial and was initialised with xPos and yPos.
//println(" x positie van egbert =", EgbertX);
// the sizeX and Y are dependend on initialization and on how many food objects it eats


//=========================================  SERIAL EVENT   ================================================================
// will get called every time data comes in
// storing the data string here
void serialEvent(Serial myPort) {
  String inString = myPort.readStringUntil('\n');
  if (inString != null) {
    // removing the whitespace
    inString = trim(inString);
    // Splitting the string at the commas and
    // seperating the variables out into an array
    data = int(split(inString, ","));
    // mark new data is available
    dataValid = true;
  }
  //println(inString);
}

class Object {
  // template for creating an object
  // the data for the object, every object in this class will have this data.
  // every object in this class will have a objectlocation x and y
  float objectlocationX;
  float objectlocationY;
  float distance;
  boolean Collision = false; // did the fish collide with any objects?
  boolean showObject = true;
  boolean Eating = false;
  PImage img;

  // constructor that will return the object
  // the object stores a variable temImg about what image it will display.
  Object (PImage tempImg) {
    objectlocationX= random(215, 1680); // the objectlocation x is random between these to values
    objectlocationY = random(215, 840); // the objectlocation y is also random between these to values
    img = tempImg;
  }



  //============================================  DISPLAY  =============================================================
  // the functionality of the object
  // all objects have the ability to excecute this function
  // displays the right images when calling the class
  void display() {
    //stroke(0);
    //fill(200);
    //ellipse(objectlocationX, objectlocationY, 100, 100);
    if (showObject) {
      imageMode(CENTER);
      // showing a random food object from the array of food.
      // Some objects to draw food1, some to draw food2 and some to draw food3 etc.
      // object stores a reference to the index of the array.
      // at the attained object location X,Y (which is random)
      image(img, objectlocationX, objectlocationY);
    }
  }

  //=================================================  DISAPPEAR  ================================================
  void dissappear() {
    // checking weather Egbert 'overlaps' or 'collides' with one of the objects
    // is so, then erase that object,
    // if the distance between the object location x,y and Egbert, is smaller than 30,
    // then they 'overlap'.
    distance = dist(objectlocationX, objectlocationY, EgbertX, EgbertY);
    if (distance < 30) {
      Collision = true;
      // whenever the fish eats a food object, it will increase in size
      SizeW = SizeW +10;
      SizeH = SizeH +10;
    }
    // if the fish and an object collide, then erase that object by making the showObject boolean false,
    // and the if statement in the display function will then not be called.
    if (Collision) {
      showObject = false;
      //println("lekker");
    }
  }
}

Hi @Ties2901,

If you have managed this from above …

You can just add to draw…

void draw() {
   // Do general stuff

   if (objects.isEmpty()) {
      // Do stuff if won
   } else {
      // Do stuff if still food available 
   }
}

Cheers
— mnse

1 Like

Managed to do it in a different way with the boolean variable :slight_smile:

    boolean allEaten = true;
    for (int i = 0; i < objects.length; i++)
      if (objects[i].showObject == true) {
        allEaten = false;
      }
    if (allEaten) {
      println("YOU WON");
      mode ++;
    }
  } // gaming mode 1

  if (mode ==2) {
    background(EndBackground);
    if (keyPressed) {
      if (key == 'Q' || key == 'q') {
        mode =0;
      }

      if (key == 'r') {
        mode =1; 
        for (int i = 0; i < objects.length; i++)
          objects[i].showObject = true;
      }

i am trying to ‘reset the game’ now when pressing key SPACE. Not sure how to make all objects appear again when going through draw again… I think I have to make a reset function to basically start from 0 again. any tips? But how do I reset boolean values?

This is my code so far :slight_smile:

/*
 CREATIVE CHALLENGE 2: EGBERT THE FISH GAME_version_16
 DATE: 02_11_2022
 AUTHOR: TAISSIA VISSER
 
 REFERENCES:
 https://www.youtube.com/watch?v=jUmjbFsA2zw&ab_channel=Crazy-Logic
 https://processing.org/examples/interpolate.html
 
 INSPIRATION:
 https://www.youtube.com/watch?v=NrwaKOsplZk&ab_channel=TheCodingTrain
 */

import processing.serial.*;        // Importing the serial library.
Serial myPort;                    // Declare serial communication port
String inString;
int[] data = {0, 0, 1};           // Array of data received from the serial port
boolean dataValid = false;

// initializing an array for the different images which will be placed
// on top of the objects in the game
PImage[] food = new PImage[3];

//  backgrounds
PImage Campus;
PImage IntroBackground;
PImage EndBackground;


// Declare game character Egbert the fish
PImage EgbertRight;
PImage EgbertLeft;
float SizeW = 850;  // Height of Egbert
float SizeH = 800;  // Width of Egbert

// initiating coordinate variables of the joystick
float xPos;            // X data received through serial
float yPos;            // Y data received through serial

int Pressed;
float EgbertX;      // the X position of the Egbert Image
float EgbertY;      // the y position of the Egbert Image

int mode;
// moving left or right?
//boolean movingLeft;
//boolean movingRight;
//float EgbertLastX;    // previous position of the Egbert Image

//initializing an array of objects of the class Object.
Object[] objects;

//=======================================  SETUP  =======================================================

void setup() {
  size (1920, 1081);
  // printArray(Serial.list());
  PFont pixel;
  pixel = createFont("Hackbot.otf", 30);
  textFont(pixel);

  for (int i= 0; i<food.length; i++) {
    // Loading all object images in the PImage array and placing them in the right index.
    // for every food, load one of the food images
    // start with the string food, then take whatever value i is, and take that to the file name
    // to load the right food image.
    //food[i] = loadImage("food"+i+".png");
    food[0] = loadImage("PIXIL_1.png");
    food[1] = loadImage("PIXIL_2.png");
    food[2] = loadImage("PIXIL_3.png");
  }

  //Creating the array with a lenght of 20 objects which will appear in the game
  objects = new Object[1];
  // loop where 'i' goes through the length of the array
  for (int i=0; i<objects.length; i++) {
    // giving a random value between 0 and the length of the array, which will be
    // converted into an integer, which will give a random object out of the array
    int index = int(random(0, food.length));
    // the object stores a variable that indicates which image it will display
    objects [i] = new Object(food[index]);
  }

  String myPortName = Serial.list()[2];
  myPort = new Serial(this, myPortName, 9600);
  myPort.bufferUntil('\n');
  Campus = loadImage("Artboard 1.png");
  EgbertRight = loadImage("Egbertred2.png");
  EgbertLeft = loadImage ("Egbertred2.2.png");
  IntroBackground = loadImage ("IntroBackground.png");
  EndBackground = loadImage("EndBackground.png");
  mode = 0;
}


// =======================================  DRAW  ===================================================================

void draw() {
  if (mode == 0) {
    imageMode(CENTER);
    image(IntroBackground, width/2, height/2);
    if (mousePressed) {
      mode = 1 ;
    }
  }

  if (mode == 1) {
    background(Campus);

    textSize(40);
    fill(0);
    text("PLEASE GUIDE ME TO THE FOOD!", 60, 80);
    text("LEVEL", 1720, 80);
    text("EGBERT HUNGRE SCALE", 60, 1020);

    // translating the origin of egbert to the centre of the png of Egbert,
    // for correct mapping of the object. (Because the Png of Egbert has white space around it).
    imageMode(CENTER);

    //calling display function from the object class, showing multiple objects
    //calling the dissappering function for all the objects
    for (int i=0; i<objects.length; i++) {
      objects[i].display();
      objects[i].dissappear();
    }

    if (dataValid) {
      // mark new data is processed
      dataValid = false;
      // and process data

      // mapping the range of the X and Y input data of the Joystick to match the drawn pool
      // (I have found the correct X and Y coordinates by a mousepressed function to print the coordinates of every corner)
      if (mousePressed) {
        println("X position is", mouseX, "and Y position is", mouseY);
      }
      xPos = int(map(data[0], 0, 1023, 220, 1684));
      yPos = int(map(data[1], 0, 1023, 220, 855));
    }

    // interpolating between the X of Y position of Egbert, and the movement of the joystick
    // moving 3% of the way to the joystick location each frame
    // to make sure the movement of the joystick is not so sensitive
    EgbertX = lerp(EgbertX, xPos, 0.03);
    EgbertY = lerp(EgbertY, yPos, 0.03);
    image(EgbertLeft, EgbertX, EgbertY, SizeW, SizeH);
    boolean allEaten = true;
    for (int i = 0; i < objects.length; i++)
      if (objects[i].showObject == true) {
        allEaten = false;
      }
    if (allEaten) {
      println("YOU WON");
      mode ++;
    }
  } // gaming mode 1

  if (mode ==2) {
    background(EndBackground);
    if (keyPressed) {
      if (key == 'Q' || key == 'q') {
        mode =0;
      }

      if (key == 'r') {
        mode =1; 
        for (int i = 0; i < objects.length; i++)
          objects[i].showObject = true;
      }
    } // gaming mode 2
  }
}


// MOVING left or right?
//if (frameCount%120==0){
//println("xPos van de joystick is:",xPos,"EgbertLastX is:",EgbertLastX);
//  println(xPos);
//}

/*if (EgbertLastX<xPos){
 movingLeft = true;
 } if (movingLeft){
 image(EgbertLeft, EgbertX, EgbertY, SizeW, SizeH);
 } else {
 movingRight = true;
 image(EgbertRight, EgbertX, EgbertY, SizeW, SizeH);
 }
 */

// the game character Egbert the fish is positioned at the X and Y coordinates
// this data is received by the serial and was initialised with xPos and yPos.
//println(" x positie van egbert =", EgbertX);
// the sizeX and Y are dependend on initialization and on how many food objects it eats


// =========================================  SERIAL EVENT   ================================================================
// will get called every time data comes in
// storing the data string here
void serialEvent(Serial myPort) {
  String inString = myPort.readStringUntil('\n');
  if (inString != null) {
    // removing the whitespace
    inString = trim(inString);
    // Splitting the string at the commas and
    // seperating the variables out into an array
    data = int(split(inString, ","));
    // mark new data is available
    dataValid = true;
  }
  //println(inString);
}

class Object {
  // template for creating an object
  // the data for the object, every object in this class will have this data.
  // every object in this class will have a objectlocation x and y
  float objectlocationX;
  float objectlocationY;
  float distance;
  boolean Collision = false; // did the fish collide with any objects?
  boolean showObject = true;
  boolean Eating = false;
  PImage img;

  // constructor that will return the object
  // the object stores a variable temImg about what image it will display.
  Object (PImage tempImg) {
    objectlocationX= random(215, 1680); // the objectlocation x is random between these to values
    objectlocationY = random(215, 840); // the objectlocation y is also random between these to values
    img = tempImg;
  }



  //============================================  DISPLAY  =============================================================
  // the functionality of the object
  // all objects have the ability to excecute this function
  // displays the right images when calling the class
  void display() {
    //stroke(0);
    //fill(200);
    //ellipse(objectlocationX, objectlocationY, 100, 100);
    if (showObject) {
      imageMode(CENTER);
      // showing a random food object from the array of food.
      // Some objects to draw food1, some to draw food2 and some to draw food3 etc.
      // object stores a reference to the index of the array.
      // at the attained object location X,Y (which is random)
      image(img, objectlocationX, objectlocationY);
    }
  }

  //=================================================  DISAPPEAR  ================================================
  void dissappear() {
    // checking weather Egbert 'overlaps' or 'collides' with one of the objects
    // is so, then erase that object,
    // if the distance between the object location x,y and Egbert, is smaller than 30,
    // then they 'overlap'.
    distance = dist(objectlocationX, objectlocationY, EgbertX, EgbertY);
    if (distance < 30) {
      Collision = true;
      // whenever the fish eats a food object, it will increase in size
      SizeW = SizeW +10;
      SizeH = SizeH +10;
    }
    // if the fish and an object collide, then erase that object by making the showObject boolean false,
    // and the if statement in the display function will then not be called.
    if (Collision) {
      showObject = false;
      //println("lekker");
    }
  }
}



2 Likes