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:
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);
}
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:
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.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.