Reputation: 41
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;
}
}
Upvotes: 0
Views: 137
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
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
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