【问题标题】:Java - Collision detection (glitch)Java - 碰撞检测(故障)
【发布时间】:2018-04-19 06:29:35
【问题描述】:

我正在为 HS 的最后一年项目开发一款平台游戏。 但是...我使用的碰撞检测系统基本上是检查角色的特定部分是否与另一个块相交。

碰撞似乎工作正常,除了它会导致一些错误,例如从侧面击球时玩家会卡住或减速,或者同时使用上键和 键时会被抛出。

我的问题是;如何改进碰撞代码以避免此类故障并产生“滑溜”碰撞?

这是我想要达到的那种碰撞效果:
(https://i.imgur.com/KB1M3bt.mp4)

(https://i.imgur.com/I44fmPc.mp4)

这是边界外观的预览


这是游戏中实际外观的预览 (click for better quality)
我用于碰撞检测的代码: (tempObject 是玩家与之相交的方块)

if(getBoundsTop().intersects(tempObject.getBoundsBottom())){
    y = tempObject.getY() + height;
    velY = 0;
    System.out.println("Top collision");
}

if(getBoundsBottom().intersects(tempObject.getBoundsTop())){
    y = tempObject.getY() - height;
    velY = 0;
    falling = false;
    jumping = false;
    //isOnBlock = true;
} else {
    falling = true;
    //isOnBlock = false;
}

if(getBoundsRight().intersects(tempObject.getBoundsLeft())){
    x = tempObject.getX() - this.width;
}


if(getBoundsLeft().intersects(tempObject.getBoundsRight())){
    x = tempObject.getX() + this.width;
}

这里是绑定的方法:

public Rectangle getBounds() { return new Rectangle( (int)x, (int)y, (int)width, (int)height ); }

    public Rectangle getBoundsTop() {
        return new Rectangle(
                (int)x, 
                (int)y, 
                (int)(width-(width*0.01f)), 
                (int)(height/2)
        );
    }
    public Rectangle getBoundsBottom() {
        return new Rectangle(
                (int)x,
                (int)(y+(height/2)),
                (int)(width-(width*0.01f)),
                (int)(height/2)
        );
    }

    public Rectangle getBoundsLeft() {
        return new Rectangle(
                (int)x,
                (int)y, 
                (int)((int)width*0.15f), 
                (int)height
        );
    }

    public Rectangle getBoundsRight() {
        return new Rectangle(
                (int) 
                ((int)x+(width-(width*0.15f))), 
                (int)y, 
                (int) ((int)width*0.15f), 
                (int)height
        );
    }

编辑:我使用恒定的加速度来设置速度

acc = 2.5f;
MAX_SPEED = 10;


if(Game.keyDownMap.containsKey(KeyEvent.VK_A)){

    setVelX(getVelX() - acc);
    if(getVelX() < -MAX_SPEED)
        setVelX(-MAX_SPEED);

} else if(Game.keyDownMap.containsKey(KeyEvent.VK_D)){

    setVelX(getVelX() + acc);
    if(getVelX() > MAX_SPEED)
        setVelX(MAX_SPEED);

}

【问题讨论】:

  • 问得很好! (+1):您提供了一个很好解释的问题,包括现场图像/动画以及详细且格式正确的代码示例。这应该用作编写新问题时参考的模板,恕我直言。
  • 嗯,你首先要定义当发生与墙壁的碰撞时你想要发生什么。你想像马里奥/波斯王子一样跳墙吗?你想要急剧下降吗?你想从墙上滑下来吗?你想在侧面碰撞时发生什么?
  • 看动画,我看到方块在与物体碰撞时会继续移动。在这些情况下,您可能希望在碰撞后停止它向给定方向移动,但不重置位置。尝试调整检查碰撞的位置以及更改角色位置的位置。此外,如果您想要更平滑的运动,您可以添加加速度而不是立即更改速度。这将使动作更流畅一些,但您需要根据自己的目的进行调整。
  • @Tschallacka 我现在更新了这个问题。 :)
  • 你用什么来提高速度?你能把那部分代码贴出来吗?

标签: java collision-detection


【解决方案1】:

当发生侧向碰撞时,您希望将侧向速度设置为零。这样就只能有一个垂直速度,我假设它是 setVelY();

if(getBoundsRight().intersects(tempObject.getBoundsLeft())){
    x = tempObject.getX() - this.width;
    setVelX(0);
}


if(getBoundsLeft().intersects(tempObject.getBoundsRight())){
    x = tempObject.getX() + this.width;
    setVelX(0);
}

如果没有活动的碰撞状态,您还需要检查按键按下。您可能想要创建一个方法来设置它当前是否与您在每个游戏点更新的东西相交。

if(Game.keyDownMap.containsKey(KeyEvent.VK_A) && !isIntersectingLeft()){

    setVelX(getVelX() - acc);
    if(getVelX() < -MAX_SPEED)
        setVelX(-MAX_SPEED);

} else if(Game.keyDownMap.containsKey(KeyEvent.VK_D) && !isIntersectingRight()){

    setVelX(getVelX() + acc);
    if(getVelX() > MAX_SPEED)
        setVelX(MAX_SPEED);

}

如果你想要一点反弹,你可以在不同的方向设置一点速度。

if(getBoundsRight().intersects(tempObject.getBoundsLeft())){
    x = tempObject.getX() - this.width;
    if(this.getVelX() > 0) {
        setVelX(10);
    }
}


if(getBoundsLeft().intersects(tempObject.getBoundsRight())){
    x = tempObject.getX() + this.width;
    if(this.getVelX() > 0) {
       setVelX(-10);
    }
}

【讨论】:

  • 似乎比以前工作得更好:D 我想我将不得不玩边界,以避免玩家在用角落击球时被扔掉
  • 你可以做的是使用多个边界框。你有一个大边界框,可以包围所有较小的 bb。如果大的发生碰撞,那么您在那个大边界框中迭代较小的 bb 集,以查看是否存在“真正的”碰撞。这样您就可以使用圆形和三角形特征。
  • 是的。如果玩家与绿色框碰撞,则迭代红色框以检查碰撞,然后迭代黄色框以迭代碰撞。不过,您不需要中心的碰撞箱,您只需要最外边缘的碰撞箱。
猜你喜欢
  • 2016-04-24
  • 1970-01-01
  • 1970-01-01
  • 2015-06-09
  • 2013-01-31
  • 2011-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多