We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpPrograms › Multiple object collisions
Page Index Toggle Pages: 1
Multiple object collisions (Read 722 times)
Multiple object collisions
Dec 2nd, 2009, 9:15pm
 
I have a problem concerning collisions with objects from two arrays. In the below program, 'bubbles' are being shot from the 'otter'. The bubbles are generated from an array; upon mouseClicked, the next bubble in the array is 'alive' and so is fired. The 'enemies' are also generated with an array, based on a timer.

The problem that I'm having is how to program the collision of an object from each array, when neither object is certain. The below code works, but there's nothing to determine collision. There is the 'hit' function in the Bubble class and the kill function in the Enemy class. I think I need some way of keeping track of which bubbles and enemies have been generated and then checking if any of those bubbles collide with any of those enemies.

Update: Perhaps one way of solving this problem would be a way to refer to any object in an array e.g., with something like bubbles[any]. Then I'd need to make sure that only the enemy with which the bubble collided was killed...?


Code:
Bubble[] bubbles = new Bubble[100];
Enemy[] enemies = new Enemy[1000];

Otter otter;

int bubCount;
int totalEnemies;
int startTime;
float enemyAttack = random(1000,3000);

void setup() {
 size(500,500);
 background(255);
 smooth();
 noCursor();
 startTime = millis();

 otter = new Otter(color(0), 20, 50, 5, 3);
 
//Initialise all objects (bubbles and enemies)

 for (int i = 0; i < bubbles.length; i++) {
   bubbles[i] = new Bubble();
 }

 for (int i = 0; i < enemies.length; i++) {
   enemies[i] = new Enemy();
 }

}

void draw() {
 background(152,197,240);
 
//Display the otter at the mouse location

 otter.display();
 otter.setLocation(mouseX,mouseY);
 
//Spawn the first enemy 1-3s after the game starts, then every
//1-2s after that
 
 if ((millis() - startTime) > enemyAttack)  {
   enemies[totalEnemies].alive = true;
   
   if (totalEnemies >= enemies.length) {
totalEnemies = 0;
   }
   
   totalEnemies++;
   startTime = 0;
   enemyAttack = enemyAttack + (random(1000,2000));
 }
 
//Display bubbles (only if alive/after mouse click)

 for (int i = 0; i < bubbles.length; i++) {
   bubbles[i].move();
   bubbles[i].display();
   
   if (i == bubbles.length) {
i = 0;
   }
 }
 
//Display enemies (only if alive/after elapsed time)

 for (int i = 0; i < enemies.length; i++) {
   enemies[i].move();
   enemies[i].display();
   
   if (i == enemies.length) {
i = 0;
   }

//Kill enemies if they reach the left side of the screen

   if (enemies[i].reachedEnd()) {
 enemies[i].kill();
   }
 }
}

//Create bubbles upon mouse click with the same x and y position
//as the otter

void mouseClicked() {
 bubbles[bubCount].alive = true;

 bubbles[bubCount].x = otter.x;
 bubbles[bubCount].y = otter.y;

 if (bubCount >= bubbles.length - 1) {
   bubCount = 0;
 }

 bubCount++;
}




class Bubble {

 color c;
 int r;
 int speedX;
 int x;
 int y;
 boolean alive;

 Bubble() {
   r = 5;
   x = otter.x;
   y = otter.y;
   c = color(9,54,98);
   speedX = 5;
   alive = false;
 }

 void display() {
   if (alive) {  //Only display if alive (after mouse click)
stroke(0);
fill(c);
ellipse(x,y,r,r);
   }
 }

 void move() {
   if (alive) {  //Only move if alive (after mouse click)
x = x + speedX;
   }
 }
 
 boolean hit(Enemy a){
   float distance = dist(x,y,a.x,a.y);
   if (distance < r + a.r) {
return true;
   } else {
return false;
   }
 }

}




class Enemy {

 float x,y;
 float speed;
 color c;
 int r;
 boolean alive;

 Enemy() {
   r = 20;
   x = height + r*2;
   y = random(height);
   speed = random(1,3);
   c = color(234,76,76);
   alive = false;
 }

 void move() {
   if (alive) {    //Only move if alive (after elapsed time)
x -= speed;   //Move left
   }
 }

//Determines whether the enemies have reached the left side of the
//screen

 boolean reachedEnd() {
   if (x < 0 - r*2) {
return true;
   }
   else {
return false;
   }
 }

 void display() {
   if (alive) {    //Display only if alive (after elapsed time)
fill(c);
stroke(0);
ellipse(x,y,r,r);
   }
 }
 
 void kill() {
   alive = false;
 }

}




class Otter {

 color furColor;
 int h;
 int w;
 int x;
 int y;
 int speedX;
 int speedY;

 Otter(color tempColor, int tempH, int tempW, int tempSpeedX, int tempSpeedY) {
   furColor = tempColor;
   h = tempH;
   w = tempW;
   speedX = tempSpeedX;
   speedY = tempSpeedY;
 }

 void display() {
   noStroke();
   fill(furColor);
   rectMode(CENTER);
   rect(x,y,w,h);
 }

 void setLocation(int tempX, int tempY) {
   x = tempX;
   y = tempY;
 }
}


Any and all help will be greatly appreciated.
Re: Multiple object collisions
Reply #1 - Dec 3rd, 2009, 1:17am
 
Collision detection is a FAQ (i.e. try a search) and probably also demonstrated in the learning section.  The principle is simple enough; for instance you already iterate over all your bubble objects when you draw them:

Code:
//Display bubbles (only if alive/after mouse click)

 for (int i = 0; i < bubbles.length; i++) {
   bubbles[i].move();
   bubbles[i].display();
   
   if (i == bubbles.length) { // This looks ugly - why do you need it?
i = 0;
   }
 }


Note that loops can be nested; so within this loop you can iterate over the enemies array - i.e. for each bubble you check against all enemies - and use some basic maths to check the distance between them.  If the distance is below a certain threshold you have a hit.  There are ways to optimise this process - a search will tell you more Wink
Re: Multiple object collisions
Reply #2 - Dec 3rd, 2009, 2:31pm
 
That worked beautifully - thank you for the help.
Page Index Toggle Pages: 1