处理过程中的碰撞检测

Collision detection on Processing

我正在制作 Space Invaders 游戏。非常基本和简单。到目前为止,我有一个可以移动(左右)和射击的射手。我也有一个以某种方式移动的入侵者。我要子弹让入侵者消失

所以我的问题是如何让碰撞检测工作(不是颜色碰撞)?如果有人能告诉我它是如何完成的,那么我将不胜感激。

注意:我过去曾因为输入太多代码而被指责,所以我希望只有 Bullet 和 Invader class 是正确的方法。

ArrayList <Bullet> bullets;

class Bullet
{
  float x;
  float y;
  float speed;
  Bullet(float tx, float ty)
  {
    x = tx;
    y = ty;
  }
  void display()
  {
    stroke(255, 0, 0);
    fill(255);
    ellipse(x,y, 10, 10);
  }
  void move()
  {
    y -= 5;

}
}
void moveAll()
{
  for(Bullet temp : bullets)
  {
    temp.move();
  }
}
void displayAll()
{
  for(Bullet temp : bullets)
  {
    temp.display();
  }
}
Cell[][] grid;

float i, j;

boolean b3=false;
boolean b4=true;
boolean b5=false;

int cols = 5;
int rows = 2;
color pixel;

class Cell {
  float cX,cY;   


  Cell(float tempX, float tempY, float tempW, float tempH) {
    cX = tempX;
    cY = tempY;
  } 

  void display2() {
    stroke(255, 0, 0);
    fill(255, 0, 0);
    rect(cX+30,cY+100,5,5);
    rect(cX+35,cY+95,5,5);
    rect(cX+35,cY+90,5,5);
    rect(cX+40,cY+85,5,5);
    rect(cX+45,cY+80,5,5);
    rect(cX+50,cY+80,5,5);
    rect(cX+55,cY+75,5,5);
    rect(cX+60,cY+75,5,5);
    rect(cX+65,cY+75,5,5);
    rect(cX+70,cY+75,5,5);
    rect(cX+75,cY+80,5,5);
    rect(cX+80,cY+80,5,5);
    rect(cX+85,cY+85,5,5);
    rect(cX+90,cY+90,5,5);
    rect(cX+90,cY+95,5,5);
    rect(cX+95,cY+100,5,5);
    rect(cX+95,cY+105,5,5);
    rect(cX+95,cY+110,5,5);
    rect(cX+95,cY+115,5,5);
    rect(cX+90,cY+120,5,5);
    rect(cX+85,cY+120,5,5);
    rect(cX+80,cY+120,5,5);
    rect(cX+75,cY+115,5,5);
    rect(cX+70,cY+115,5,5);
    rect(cX+70,cY+120,5,5);
    rect(cX+70,cY+125,5,5);
    rect(cX+65,cY+115,5,5);
    rect(cX+60,cY+115,5,5);
    rect(cX+55,cY+115,5,5);
    rect(cX+55,cY+120,5,5);
    rect(cX+55,cY+125,5,5);
    rect(cX+50,cY+115,5,5);
    rect(cX+45,cY+115,5,5);
    rect(cX+45,cY+120,5,5);
    rect(cX+40,cY+120,5,5);
    rect(cX+35,cY+120,5,5);
    rect(cX+30,cY+115,5,5);
    rect(cX+30,cY+110,5,5);
    rect(cX+30,cY+105,5,5);
    rect(cX+40,cY+125,5,5);
    rect(cX+40,cY+130,5,5);
    rect(cX+45,cY+135,5,5);
    rect(cX+50,cY+140,5,5);
    rect(cX+55,cY+140,5,5);
    rect(cX+60,cY+140,5,5);
    rect(cX+65,cY+140,5,5);
    rect(cX+70,cY+140,5,5);
    rect(cX+75,cY+140,5,5);
    rect(cX+80,cY+135,5,5);
    rect(cX+85,cY+130,5,5);
    rect(cX+85,cY+125,5,5);



   if(b4==true) {  //moving right
      b3 = false;
      b5 = false;
      cX += 2;
    }
    else if(b5==true) { //moving left
      b3 = false;
      b4 = false;
      cX -= 2;
    }

   if( (b4 == true && cX >= 780) || (b5 == true && cX <= -1)) 
   {
      b3 = true;  //moving down
      b4 = false;
      b5 = false;
    }

   if( b3 == true) //moving down
   {
       cY += 3;
      if (cY % 10 == 0)  //moving down 10 pixels
      {
        b3=false;
        if ( cX >= 780)  //if it is on the right edge
        {
          b4 = false;
          b5 = true;
        }
         else if ( cX <= -1 ) //if it is on the left edge
        {
          b4 = true;
          b5 = false;
          cY += 3;
        }
      }
  }
  }

  void monster()
  {
          display2();
        }
}

有很多方法可以处理碰撞检测,这使得这个问题非常宽泛。但我将重点介绍两种可能有用的方法:

方法一:圆形碰撞

如果您知道两个物体的中心和大小,您可以简单地使用 dist() 函数计算出两个物体相距多远。如果该距离小于它们的大小,则对象正在碰撞。

这是一个小例子:

void setup() {
  size(500, 500);
  ellipseMode(RADIUS);
}

void draw() {
  background(0);

  float circleOneX = width/2;
  float circleOneY = height/2;
  float circleOneRadius = 50;

  float circleTwoX = mouseX;
  float circleTwoY = mouseY;
  float circleTwoRadius = 100;

  if (dist(circleOneX, circleOneY, circleTwoX, circleTwoY) < circleOneRadius + circleTwoRadius) {
    //colliding!
    fill(255, 0, 0);
  } else {
    //not colliding!
    fill(0, 255, 0);
  }

  ellipse(circleOneX, circleOneY, circleOneRadius, circleOneRadius);
  ellipse(circleTwoX, circleTwoY, circleTwoRadius, circleTwoRadius);
}

方法二:矩形碰撞

或者,您可以在对象周围定义一个边界框。然后您只需要一系列 if 语句来检查这些框是否完全重叠。如果是这样,那么对象正在碰撞。

这是一个小例子:

void setup() {
  size(500, 500);
}

void draw() {
  background(0);

  float rectOneX = width/2;
  float rectOneY = height/2;
  float rectOneWidth = 50;
  float rectOneHeight = 50;

  float rectTwoX = mouseX;
  float rectTwoY = mouseY;
  float rectTwoWidth = 100;
  float rectTwoHeight = 100;

  if (rectOneX < rectTwoX + rectTwoWidth &&
    rectOneX + rectOneWidth > rectTwoX &&
    rectOneY < rectTwoY + rectTwoHeight &&
    rectOneHeight + rectOneY > rectTwoY) {
    //colliding!
    fill(255, 0, 0);
  } else {
    //not colliding!
    fill(0, 255, 0);
  }

  rect(rectOneX, rectOneY, rectOneWidth, rectOneHeight);
  rect(rectTwoX, rectTwoY, rectTwoWidth, rectTwoHeight);
}

Processing 附带的 the button example 中介绍了这两种方法。