我在Processing中有一个用于弹跳球和矩形的程序。我可以得到矩形边的碰撞正确,但我不知道如何获得角落。这就是我到目前为止所做的:
int radius = 20;
float circleX, circleY; //positions
float vx = 3, vy = 3; //velocities float boxW, boxH; //bat dimensions
void setup(){
size(400,400);
ellipseMode(RADIUS);
rectMode(RADIUS);
circleX = width/4;
circleY = height/4;
boxW = 50;
boxH = 20;
}
void draw(){
background(0);
circleX += vx;
circleY += vy;
//bouncing off sides
if (circleX + radius > width || circleX < radius){ vx *= -1; } //left and right
if (circleY + radius > height || circleY < radius){ vy *= -1; } //top and bottom
if (circleY + radius > height){
circleY = (height-radius)-(circleY-(height-radius)); } //bottom correction
//bouncing off bat
if (circleY + radius > mouseY - boxH && circleX > mouseX - boxW && circleX < mouseX + boxW){
vy *= -1; //top
}
if (circleX - radius < mouseX + boxW && circleY > mouseY - boxH && circleY < mouseY + boxH){
vx *= -1; //right
}
if (circleY - radius > mouseY + boxH && circleX > mouseX - boxW && circleX < mouseX + boxW){
vy *= -1; //bottom
}
if (circleX + radius < mouseX - boxW && circleY > mouseY - boxH && circleY < mouseY + boxH){
vx *= -1; //left
}
if ([CORNER DETECTION???]){
vx *= -1;
vy *= -1;
}
ellipse(circleX,circleY,radius,radius);
rect(mouseX,mouseY,boxW,boxH);
}
我不知道在if语句中放入什么来检测角落碰撞。
答案 0 :(得分:3)
问题不在于您需要检测角落碰撞。问题是,当检测到碰撞时,您当前的碰撞检测不会将球移动到一侧。
在frameRate(5)
功能中拨打setup()
,以便更好地了解正在进行的操作:
请注意,球与框的顶部相交,因此您将vy
变量乘以-1
。这导致圆圈开始向上移动。但是下一帧,圆圈仍然与矩形相撞,因为它还没有向上移动。因此,您的代码会检测到该冲突,再次将vy
乘以-1
,然后球向下移动。下一帧发生同样的事情,直到球最终停止与矩形碰撞。
要解决此问题,当您检测到碰撞时,您需要移动球,使其不再与下一帧中的矩形发生碰撞。
以下是如何为顶端执行此操作的示例:
if (circleY + radius > mouseY - boxH && circleX > mouseX - boxW && circleX < mouseX + boxW) {
vy *= -1; //top
circleY = mouseY-boxH-radius;
}
你必须为对方添加类似的逻辑,但总体思路是一样的:确保球不会在下一帧中发生碰撞,否则它会继续弹跳这样的边缘。
编辑:仔细查看您的碰撞逻辑,仍有一些问题:当您真正应该检查时,您只会检查三个方面所有四个方。
让我们以此为例:
if (circleY + radius > mouseY - boxH && circleX > mouseX - boxW && circleX < mouseX + boxW){
println("top");
vy *= -1; //top
}
您要检查球是否位于矩形顶部下方,矩形左侧右侧以及矩形右侧左侧。对于这种情况,这将是true
:
在每个println()
语句中添加if
语句(请参阅上面if
语句中的示例)并注意球在球拍下方或桨的右侧。
你需要重构你的逻辑,以便你检查所有四个方面,而不仅仅是三个方面。如果我是你,我会编写一个函数,该函数接受球的下一个位置,如果该位置与矩形发生碰撞,则返回boolean
值true
。然后你可以在X和Y轴上移动球之前检查,它告诉你如何反弹。像这样:
if (collides(circleX + vx, circleY)) {
vx*=-1;
}
else {
circleX += vx;
}
if (collides(circleX, circleY + vy)) {
vy*=-1;
}
else {
circleY += vy;
}
这取代了您的四个单独的if
语句,它也解决了您的上述问题。