Grey
Grey

Reputation: 41

Simple Collision Detection Project

I am a newbie with coding and doing a collision detection project for my assignment. I think I got the Algorithm right but my problem is how will I access the object from my ArrayList I created and remove the object once collision is detected. Please see my code and help me to improve it to add the remove() from it. I added a boolean variable to check if true or false then do the remove function.

My end goal is to remove the ghost when it collides with the green ball


    ArrayList<Greenball> array1 = new ArrayList<Greenball>();
    ArrayList<Ghost> array2 = new ArrayList<Ghost>();

    void setup(){
      size(1000,500);
      
      
    }
    
    void draw(){
      background(255);
      
      
      for(int i = 0; i < array1.size() ; i++){
       array1.get(i).move();
       array1.get(i).display();
      }
      
      for (int i = 0; i < array2.size() ; i++){
       array2.get(i).move();
       array2.get(i).display();
      }
    }
    
    void mousePressed(){
      if (array1.size() != 5) array1.add(new Greenball(int(mouseX),int(mouseY), 40, 40)); //max at 5
    }
    
    void keyPressed(){
      if (array2.size() != 5)array2.add(new Ghost(int(random(40,960)), int(random(40,460)), 40, 40)); //max at 5

class Ghost{
  
  PImage ghost;
  int x,y,w,h,xSpeed,ySpeed;
  int pixelSize = 40;
  Ghost(int x_, int y_, int w_, int h_){
  x = x_;
  y = y_;
  w = w_;
  h = h_;  
  xSpeed = int(random(-10,10));
  ySpeed = int(random(1,10));  
  }
  
  void move(){
   x = x + xSpeed;
   y = y + ySpeed;
   
   if(x > width-pixelSize || x < 0){
    xSpeed = xSpeed * -1; 
   }
   if(y > height-pixelSize || y < 0){
    ySpeed = ySpeed * -1; 
   }
    
  }
  
  void display(){
   ghost = loadImage("greenghost.png");
   image(ghost,x,y,w,h);
}

class Greenball{
  
 PImage g;
 int x,y,w,h,xSpeed,ySpeed;
 int pixelSize = 40;
 boolean alive=true;
 Greenball(int x_, int y_, int w_, int h_){
   x = x_;
   y = y_;
   w = w_;
   h = h_;
   xSpeed = int(random(-10,10));
   ySpeed = int(random(1,10));
 }
 
 void move(){
   x = x + xSpeed;
   y = y + ySpeed;
   
   if(x > width-pixelSize || x < 0){
    xSpeed = xSpeed * -1; 
   }
   if(y > height-pixelSize || y < 0){
    ySpeed = ySpeed * -1; 
   }
 }
 
 void display(){
   g = loadImage("green.png");
   image(g,x,y,w,h);
 }
 
 
 void checkForCollision(Ghost ghost){
   float d = dist(x,y,ghost.x,ghost.y);
   float r1 = (x+y)/2;
   float r2 = (ghost.x + ghost.y)/2;
   
   if (d < r1 + r2) alive = false;
   else alive = true;
   }

}

enter image description here

enter image description here

Upvotes: 0

Views: 137

Answers (3)

Grey
Grey

Reputation: 41

void draw(){
  background(0);
  
  for(int i = 0; i < gball1.size() ; i++){
    Greenball gball = gball1.get(i);
    gball.move();
    gball.display(); 
   }
  

  for(int i = 0; i < ghost2.size() ; i++){
    
    Ghost ghost = ghost2.get(i);
    ghost.move();
    ghost.display();
    
    for(int e = 0; e < gball1.size(); e++){
      Greenball b = gball1.get(e);
      if(ghost.ifCollided(b)){
        ghost2.remove(i);
      }
    }
   }

}

Upvotes: 0

void main
void main

Reputation: 125

Add the Collision Detection Function inside draw() and run two nested for loops so that you check if any of the Ghosts is colliding with any of the Greenballs You can replace your draw function with the following code:

void draw() {
  background(255);

   // loop through all the Ghosts
   for(int i = 0; i < array2.size(); i++) {

     //move and display the Ghosts
     array2.get(i).move();
     array2.get(i).display();

     /*
      * For every Ghost, check if that Ghost is colliding with any Greenball.
      * Here you are checking collision with each Ghost for each Greenball.
      */
     for (int j = 0; j < array2.size(); j++) { // for each Greenball,
       if (array1.get(i).checkForCollision(array2.get(j)) { // if any Ghost is Colliding with it,
         array1.get(j).alive = false; // then set "alive = false" for it     
       }     
     }
   }

  // loop through all the Greenballs in reverse order, so that each and every Greenball is checked
  for(int i = array1.size() - 1; i >= 0; i--) {
    if (array1.get(i).alive = false) { // if any Greenball is dead,
      array1.remove(i); // then remove it
    } else { // else, move and display it.
      array1.get(i).move();
      array1.get(i).display();
    }
  }
 
}

Suggestion: You don't need to loadImage() everytime you display the Ghost or Greenball as it is very taxing on your system. Just use ghost = loadImage("ghost.png") once in the Constructor and you're done.

Upvotes: 1

Gordon from Blumberg
Gordon from Blumberg

Reputation: 199

It depends on where do you call the checkForCollision method from. I think the best place for it is the draw method. Try replace your second loop with the following code:

Iterator<Ghost> ghostIterator = array2.iterator();  // get iterator object
while (ghostIterator.hasNext()) {
    Ghost ghost = ghostIterator.next();             // get current ghost object
    ghost.move();                                   // recalculate position
    boolean collided = false;
    for (int i = 0, len = array1.size(); i < len; i++) {
        if (array1.get(i).checkForCollision(ghost)) {   // check for collision
            ghostIterator.remove(ghost);               // remove current ghost if it collided
            collided = true;
            break;               // stop inside loop due to collision detected
        }
        if (!collided) {
            ghost.display();  // if ghost isn`t collided display it
        }
    }
}

Please note you should change return type of the checkForCollision method from void to boolean and returns calculated alive value.

Upvotes: 0

Related Questions