Search code examples
javaprocessing

What should I do in my code in order to make a collision detection between a PNG sprite and a drawn circle occur in Processing 3 (Java)?


I have been coding a significantly simple game for my academic work in which the PNG bee sprite is meant to run away from the orange ball. If the bee collides with the orange ball, she dies. Apart from this, I intend to include a timer that keeps going onwards as the bee succeeds in running away from the ball. The ball moves automatically throughout the screen, whereas the bee bounces throughout the screen with the arrow keys and gravity.

I have come across some explanations towards collision detection upon the Processing forum, however I still don't understand how this event can occur in the cases of circles x circles collisions, rectangles x circles collisions, etc.

Please, excuse my messy code. Also, excuse my poor description of what I want to know.

This is what I see on the screen:

screenshot of my sketch

My code:


//background
PImage background;

// keys | keyboard
boolean upPressed = false;
boolean downPressed = false;
boolean leftPressed = false;
boolean rightPressed = false;




// bee player character 
PImage charImage;
float charSpeed = 5.5;
float charX = 0;
float charY = 450;
float gravity = 1.5;
float vy = 0;
float bounce = -0.8;


// platforms
PImage bee;// bee
float beeX = 300; 
float beeY = 490;
PImage hi; // hi
float hiX = 400;
float hiY = 300;
PImage ve; // ve
float veX = 420;
float veY = 440;

// more beehives

PImage beehive4;// beehive4
float bee4X = 120; 
float bee4Y = 90; 
PImage beehive5; // beehive5
float bee5X = 200; 
float bee5Y = 300;
PImage beehive6;  // beehive6
float bee6X = 30; 
float bee6Y = 400;
PImage beehive7; // beehive7
float bee7X = 496;
float bee7Y = 90;


// enemy ball

float ballX = 100;
float ballY = 100;
float xspeed = 100;
float yspeed = 100;





//////
public void setup() {
  size(600, 800); 
  noStroke();
  smooth();
 noFill(); // to adjust the image in the screen properly in fullscreen
   

//load beehives 

bee = loadImage("beehive 1.png");
bee.resize(100, 100);
hi = loadImage("beehive 2.png");
hi.resize(100,100);
ve = loadImage("beehive 3.png");
ve.resize(100, 100);

 

// load more beehives

beehive4 = loadImage("beehive 4.png");
beehive4.resize(100, 100);
beehive5 = loadImage("beehive 5.png");
beehive5.resize(100, 100);
beehive6 = loadImage("beehive 6.png");
beehive6.resize(100, 100);
beehive7 = loadImage("beehive 7.png");
beehive7.resize(100, 100);




}




/*********** drawing section !***********/



public void draw() {
background(244, 240, 219);
noStroke();

// render beehives 

image(bee, beeX, beeY);
image(hi, hiX, hiY);
image(ve, veX, veY);

// render more beehives

image(beehive4, bee4X, bee4Y);
image(beehive5, bee5X, bee5Y);
image(beehive6, bee6X, bee6Y);
image(beehive7, bee7X, bee7Y);
 

 // render bee 

 charImage = loadImage("bee walk 3.png");
 charImage.resize(200, 200);
 
vy += gravity; // it applies gravity to the bee sprite
  charY += vy;
  if(charY > height - 150 )
    vy *= bounce;  // bouncing bee
    



 // Add the current speed to the location.
  ballX = ballX + xspeed;
  ballY = ballY + yspeed;

  // Check for bouncing
  if ((ballX > width) || (ballX < 0)) {
    xspeed = xspeed * -1;
  }
  if ((ballY > height) || (ballY < 0)) {
    yspeed = yspeed * -1;
  }

// Display at x,y location
  stroke(0);
  fill(179, 98, 0);
  ellipse(ballX, ballY,80,80);
 

 
// update keys


  if (upPressed) {
    charY--;
  }

  if (downPressed) {
    charY++;
  }

  if (leftPressed) {
    charX--;
  }

  if (rightPressed) {
    charX++;
  }



  if(keyPressed){
    if(keyCode == UP && charY > 0){
      charY -= 30;
    }
    if(keyCode == DOWN && charY < height){
      charY += 10;
    }
    if(keyCode == LEFT && charX > 0){
      charX -= 30;
    }
    if(keyCode == RIGHT && charX < width){
      charX += 10;
    }
    
  
 }
 


  // render beecharacter on screen 

  image(charImage, charX, charY);
  


  }
  
  


Solution

  • There mulitple ways to tackle the problem.

    Collision detection can be coarse: less accurate but faster (and simpler) or detailed (e.g. pixel level precision) but slower (and more complex).

    In terms of simple collision detection two options could rectangle or circle intersections.

    Rectangle intersection can be implemented manually or using Rectangle's intersects() method.

    Circle intersection is trivial: if the distance(dist()) between the 1st circle's center and 2nd circle's center is smaller than the two radii then they must intersect.

    here's a basic example illustrating circle intersection:

    // check collision: circle
      if (dist(ballX, ballY, charX, charY) < charImage.width) {
        // tint red to display collision: placeholder for subtracting bee health
        tint(192, 0, 0);
      }else{
        noTint();
      }
    
    

    this condition can be added before this section in draw():

    // render beecharacter on screen
    
      image(charImage, charX, charY);
    

    The collision detection is quite rough: not pixel perfect, but hopefully a good starting point. It should tint everything red if there's a collision.

    I have two other small suggestions:

    • reducing xspeed, yspeed to 10 or smaller values will make the game more playable. 100px/frame is too fast for people and the bee will likely collide instantly before the users even has a chance to react.
    • intead of a boolean beeIsAlive sort of variable that immediately, with one ball hit switches to true also might be too harsh as a game rule. Consider something like int beeHealth = 100; and gradually reducing the health with each collision will make the game more playable.