【问题标题】:Issues with collision detection for a moving ellipse and rectangle (multi part)移动椭圆和矩形(多部分)的碰撞检测问题
【发布时间】:2018-09-12 20:59:43
【问题描述】:

最近我一直在使用 Java 在处理中使用 Arduino 开发一个游戏,对于这个问题,我已经删除了所有不必要的 Arduino 代码,只显示我遇到问题的代码,这些代码与处理中的 Java 直接相关。

目标:所以我现在的目标是在一些随机下降的椭圆和屏幕底部来回弹跳的矩形之间进行碰撞检测。这个想法是在物体碰撞时做一些真正简单的事情,比如把背景颜色变成红色。

问题:所以我目前面临两个问题。一个是我知道如何使移动对象与静态对象发生碰撞,但是我在处理两个移动对象时遇到了困难,并且任何示例通常都是矩形上的矩形或椭圆 椭圆,这没有帮助,因为椭圆击中矩形与两个相同的形式相互撞击。

第二个问题我知道我必须使用布尔值,但是因为椭圆是随机坐标,所以我使用的是浮点数而不是整数,并且布尔值不能与浮点数一起使用。

最后一个快速问题是,如果我需要 x 和 y 作为布尔值,它们不仅是浮动的,而且它们被放置在一个类中,这使得它们无法访问(参见下面的代码)。我可以复制相同的浮点数并将它们放置在定义初始整数的位置,除非我不知道这样做有多糟糕。

int direction1 = 100;
int speedX = 12;
int heightWidth=40;
int bounceSize= 40;
int ellipseSizeone=40;
int ellipseSizetwo=50;
float x = random(800);
float y = random(-500);

Meteor meteors;
int total = 10;
Meteor[] fall = new Meteor[total]; 

void setup() {
    size (800, 500);
    background(0);
    smooth();
    noStroke();

    for (int i = 0; i < fall.length; i++) {

        fall[i] = new Meteor(); 
        meteors = new Meteor();
    }
}

void draw() {
   background(0);

   direction1+=speedX;
   if (direction1 > width-bounceSize) {
       direction1 = width-bounceSize;
       speedX = -12;
   }
   if (direction1 < 0) {
       direction1 = 0;
       speedX = 12;
   }
   rect(direction1, 450, heightWidth, heightWidth);
   fill(0,20);
   rect(0,0,800,500);

   for (int i = 0; i < fall.length; i+=3) {
       fall[i].fall();
   }
   fill(0,255,0);
}

class Meteor {
    float x = random(800);
    float y = random(-500);

    void fall() {
        y = y + 3;
        fill(random(200),0,0);
        ellipse(x, y, ellipseSizeone, ellipseSizetwo);

        if(y>height){
            x = random(800);
            y = 0;
        }
    }
}

【问题讨论】:

  • 这个问题也被here发帖了。

标签: java processing


【解决方案1】:

我建议将问题简化为简单的轴对齐有界框相交测试。 I 足以用一个框来近似椭圆,以进行相交测试。请注意,稍后可以应用椭圆和矩形的精确相交测试。

给类Meteor添加交集测试方法:

class Meteor {

    // .....

    boolean intersect(float rx, float ry, float rw, float rh) {
        return  
            (x + ellipseSizeone/2.0f) > rx &&
            (rx + rw) > (x - ellipseSizeone/2.0f) &&
            (y + ellipseSizetwo/2.0f) > ry &&
            (ry + rh) > (y - ellipseSizetwo/2.0f);
    }
}

使用boolean 类型的变量,来通知相交和。循环检查每个对象是否与矩形相交。相交测试的结果必须通过逻辑或运算 (||) 连接起来。如果一个对象与矩形相交,则可以中止测试:

void draw() {

    boolean hit = false;
    for (int i = 0; hit == false && i < fall.length; i+=3) {
        hit = hit || fall[i].intersect(direction1, 450, heightWidth, heightWidth);
    }

    if ( hit )
        background(255, 0, 0);
    else
        background(0); 

    // .....

}

请注意,为了获得准确的结果,在绘制对象后,应增加下落对象的 y 位置,因为相交测试测试的是当前位置,而不是下一个位置。
当然,在为下一帧更新其位置之前绘制矩形。

完整的draw函数:

void draw() {

    boolean hit = false;
    for (int i = 0; hit == false && i < fall.length; i+=3) {
        hit = hit || fall[i].intersect(direction1, 450, heightWidth, heightWidth);
    }

    if ( hit )
        background(255, 0, 0);
    else
        background(0); 

    rect(direction1, 450, heightWidth, heightWidth);
    fill(0,20);
    rect(0,0,800,500);

    direction1+=speedX;
    if (direction1 > width-bounceSize) {
        direction1 = width-bounceSize;
        speedX = -12;
    }
    if (direction1 < 0) {
        direction1 = 0;
        speedX = 12;
    }

    for (int i = 0; i < fall.length; i+=3) {
        fall[i].fall();
    }
    fill(0,255,0);
}

完整的class Meteor:

class Meteor {
    float x = random(800);
    float y = random(-500);

    void fall() {
        fill(random(200),0,0);
        ellipse(x, y, ellipseSizeone, ellipseSizetwo);

        y = y + 3; 
        if(y>height){
            x = random(800);
            y = 0;
        }
    }

    boolean intersect(float rx, float ry, float rw, float rh) {
        return  
            (x + ellipseSizeone/2.0f) > rx &&
            (rx + rw) > (x - ellipseSizeone/2.0f) &&
            (y + ellipseSizetwo/2.0f) > ry &&
            (ry + rh) > (y - ellipseSizetwo/2.0f);
    }
}

【讨论】:

  • 非常感谢还有一个小问题,2.0 之后的 f 是否将其设置为浮点值正确?
  • @Azaels 是的。 double 将自动转换为 float。见Convert double to float in Java
猜你喜欢
  • 2014-05-05
  • 1970-01-01
  • 2012-03-19
  • 1970-01-01
  • 2014-09-03
  • 1970-01-01
  • 2023-01-26
  • 2010-09-28
  • 2018-06-02
相关资源
最近更新 更多