【问题标题】:Collision detection on Processing处理中的碰撞检测
【发布时间】:2018-05-23 00:14:20
【问题描述】:

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

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

注意:我过去曾因输入过多代码而受到指责,因此我希望只有 Bullet 和 Invader 类才是正确的做法。

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

【问题讨论】:

    标签: processing collision-detection game-physics


    【解决方案1】:

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

    方法一:圆碰撞

    如果您知道两个对象的中心和大小,您可以简单地使用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 中介绍了这两种方法。

    【讨论】:

    • 谢谢你,Kevin,第一个例子,它只适用于圆圈还是任何物体?
    • @FredTheHomie 想象一下在你的对象周围画一个圆圈。然后,您可以在圆圈之间进行碰撞。这并不适用于所有情况,但它适用于许多简单的情况。这样想:圆圈是虚构的。您实际上不必绘制它们。您只是使用它们使对象之间的碰撞更容易。与矩形边界框相同。
    • 我明白,这是有道理的。所以,说我的入侵者,我周围有一个图像圈?那么我该如何在它周围放置这个“圈子”呢?
    • @FredTheHomie 你必须弄清楚你的入侵者的中心,你必须弄清楚它的大小。那是你的圈子。试着在纸上画几个例子。
    • 好的。非常感谢。你直接帮了我。我很感激你,兄弟。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-25
    • 2012-09-14
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    相关资源
    最近更新 更多