2017-08-07 79 views
0

我正在尝试重新创建突破,但块和角球之间的相互作用让我头痛不已。从窗口的边缘弹起,块体工作得很好,从窗户的角落反弹也非常完美。为了简单起见,所有块都是轴对齐的。交换x和y运动只能按照预期的方式对8个案例中的2个运行。对于其他6个,其中一个或两个矢量必须倒置才能使碰撞正确,但我无法找到一种简单的方法。写8 if语句不能正确,并且容易引起错误。反射圈/矩形问题

Ball类是Ellipse2D.Double类的扩展。
Block类是Rectangle类的扩展。

我看过的每个问题/答案/教程可能会过于复杂(不是AA矩形,直方图不是固定位置),简化(处理好像两个矩形相撞)或完全离题(检测碰撞/重叠,球对球)。

这里就是我的了:

public void move(Paddle p, List<Block> b) { 
    //called every frame 

    this.x += dx; 
    this.y += dy; 

    checkCollisionsWalls(); 
    // checkCollisionPaddle(p); 
    checkCollisionBlocks(b); 

    if (this.dir == 90 || this.dir == 270) 
     this.dir++; 
    // make sure ball wont get stuck between two walls of window 

} 

private void checkCollisionBlocks(List<Block> b) { 

    for (Block block : b) { 

     if (this.intersects(block)) { 

      if (this.x + this.width/2 >= block.x && this.x + this.width/2 <= block.x + block.width) { 

       System.out.println("Top/Bot reflect"); 
       this.dy *= -1; 
       break; 
      } 

      if (this.y + this.height/2 >= block.y && this.y + this.height/2 <= block.y + block.height) { 
       System.out.println("Left/Right reflect"); 
       this.dx *= -1; 
       break; 
      } 

      // if execution got here we must have hit a corner 
      reflectCorner(); 

     } 
    } 
} 

private void reflectCorner() { 

    if (dx > dy) { 
     this.dy *= -1; 
    } else { 
     this.dx *= -1; 
    } 

    if (Math.abs(dx) == Math.abs(dy)) { 
     this.dy *= -1; 
     this.dx *= -1; 
    } 

    double temp = this.dx; 
    this.dx = this.dy; 
    this.dy = temp; 
    temp = 0; 

} 

dx和dy是在Ball类全局变量,其实所有的代码是(仍然)在Ball类。

编辑: 对不起,看在问一个清晰的问题的一部分,我有点激动吧...

这有什么当前的代码发生:当敲 反思的作品完美从任何方向的右下角。
击中左上角导致球卡在矩形内部。然后它沿着边缘漂移到右下角
当平行于x轴移动时触摸右上角,并在平行于y轴移动时触摸左下角时,球反射两次,在正y或正x方向上以每次反射1个像素(正交它的轴正向移动)进行微调。
所有其他反射工作正常。

应该发生什么: reflectCorner()方法应该适用于所有拐角,就像它对于右下方一样,而不产生如上所述的结果。

问题: 我该如何做到这一点,而没有过于复杂的if结构?

如有必要,我可以提供我使用的测试设置。

+0

问题寻求调试帮助(“为什么不是这个代码工作?“)必须包含所需的行为,特定的问题或错误,以及在问题本身中重现问题所需的最短代码,没有明确问题陈述的问题对其他读者无效。 “编辑”链接改善你的*问题* - 不要通过评论添加更多信息。谢谢! – GhostCat

+0

换句话说:你的**问题到底是什么**? – GhostCat

回答

0

我终于成功地使它在各方面都有效。首先,我通过检查球的中心与任何角落之间的距离是否小于/等于球的半径来计算哪个角落被击中。然后,我会交换x和y的运动。对于需要的两个角球,对于后两个角球我必须将其中的一个倒置,这取决于球的角落和方向。

最后:

private void reflectCorner(Rectangle rect) { 

    double temp = this.dx; 
    this.dx = this.dy; 
    this.dy = temp; 
    temp = 0; 

    if (Math.abs(dx) == Math.abs(dy)) { 
     this.dy *= -1; 
     this.dx *= -1; 
     return; 
    } 

    if (Math.sqrt(Math.pow(Math.abs(this.getCenterX() - rect.x), 2) 
      + Math.pow(Math.abs(this.getCenterY() - rect.y), 2)) <= this.width/2) { 
     System.out.println("topL"); 
     if (dx < dy) { 
      this.dy *= -1; 
     } else { 
      this.dx *= -1; 
     } 
     return; 
    } 
     if (Math.sqrt(Math.pow(Math.abs(this.getCenterX() - (rect.x + rect.width)), 2) 
      + Math.pow(Math.abs(this.getCenterY() - (rect.y + rect.height)), 2)) <= this.width/2) { 
     System.out.println("botR"); 
     if (dx > dy) { 
      this.dy *= -1; 
     } else { 
      this.dx *= -1; 
     } 
     return; 
    } 

} 

我越不necissary,这是相对紧凑。不过,如果有人有一个更简单的想法,你仍然可以回答,我会测试它。