为了在 Processing 3 (Java) 中检测 PNG 精灵和绘制的圆圈之间的碰撞,我应该在我的代码中做什么?

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)?

我一直在为我的学术工作编写一个非常简单的游戏,其中 PNG 蜜蜂精灵要 运行 远离橙色球。如果蜜蜂与橙色球相撞,她就会死去。除此之外,我打算包括一个计时器,当蜜蜂成功 运行 远离球时,它会继续前进。球自动在整个屏幕上移动,而蜜蜂则通过箭头键和重力在屏幕上弹跳。

我在 Processing 论坛上看到了一些关于碰撞检测的解释,但是我仍然不明白在圆 x 圆碰撞、矩形 x 圆碰撞等情况下如何发生此事件

请原谅我乱七八糟的代码。另外,请原谅我对我想知道的内容描述不当。

这是我在屏幕上看到的:

我的代码:


//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);
  


  }
  
  

有多种方法可以解决这个问题。

碰撞检测可以是粗略的:不太准确但更快(更简单)或更详细(例如像素级精度)但更慢(更复杂)。

就简单的碰撞检测而言,两个选项可以是矩形或圆形相交。

可以手动或使用Rectangle's intersects() method实现矩形相交。

圆相交是微不足道的:如果第一个圆心和第二个圆心之间的距离(dist())小于两个半径则它们必须相交。

这是一个说明圆相交的基本示例:

// 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();
  }

这个条件可以在draw()的这个部分之前添加:

// render beecharacter on screen

  image(charImage, charX, charY);

碰撞检测相当粗糙:像素不完美,但希望是一个好的起点。如果发生碰撞,它应该把所有东西都染成红色。

我还有两个小建议:

  • xspeedyspeed 减少到 10 或更小的值将使游戏更具可玩性。 100px/frame 对人来说太快了,蜜蜂很可能会在用户反应过来之前立即发生碰撞。
  • 而不是 boolean beeIsAlive 类型的变量,一旦击中球立即切换为 true 作为游戏规则也可能过于苛刻。考虑像 int beeHealth = 100; 这样的事情,每次碰撞逐渐降低生命值将使游戏更具可玩性。