当前位置: 首页 > 知识库问答 >
问题:

矩形之间的碰撞检测(无重叠)-libgdx

宋育
2023-03-14

我已经在这里呆了2-3周了,我仍然无法进行适当的碰撞检测。我用矩形创建了一个迷宫。我希望我的对象(在矩形中)每当我的对象与任何墙壁碰撞时停止,并能够移动到任何地方(或滑下墙壁)。我的墙壁(矩形)具有负坐标,如下所示:

shapeRenderer.rect(0.9f, 12, 1.15f, 0, Color.RED, Color.RED, Color.RED, Color.RED); //NORTH
shapeRenderer.rect(1, 12, 0, -1.05f, Color.RED, Color.RED, Color.RED, Color.RED); // WEST
shapeRenderer.rect(2, 12, 0, -1.05f, Color.RED, Color.RED, Color.RED, Color.RED); // EAST
shapeRenderer.rect(0.9f, 11, 1.15f, 0, Color.RED, Color.RED, Color.RED, Color.RED); // SOUTH

我目前正在使用SO中发现的重叠方法。以下是我的CollisionManager类中的方法

private boolean overlaps (Rectangle collision, Rectangle wall) {
    return Math.min(collision.x, collision.x + collision.width) 
        < Math.max(wall.x, wall.x + wall.width) 
    && Math.max(collision.x, collision.x + collision.width) 
        > Math.min(wall.x, wall.x + wall.width) 
    && Math.min(collision.y, collision.y + collision.height) 
        < Math.max(wall.y, wall.y + wall.height) 
    && Math.max(collision.y, collision.y + collision.height) 
        > Math.min(wall.y, wall.y + wall.height);
}

我有一个功能可以保存对象所做的所有位置移动。因此,当发生碰撞时,对象会恢复到最后一次移动之前的上一次移动(因为最后一次移动是在碰撞发生时)(示例如下):

private void overlapsTop(Entity object, Rectangle wall){

    Rectangle r = new Rectangle();
    if(spritePositions.size() != 0){
        r = spritePositions.get(spritePositions.size()-1);
    }
    object.update(r.x, r.y, r.width, r.height);
    object.getObject().setBounds(r.x, r.y, r.width, r.height);
    spritePositions.clear();
}

附加信息:我正在像这样移动我的对象:

public void moveRight(){
    position.x += 1f;
    update();
}

public void update(){

      boundingRectangle.set(position.x, position.y, object.getWidth(), object.getHeight());
}

我遇到的问题是我的重叠函数(我在SO中找到的那个)。它适用于大多数情况;然而,例如,如果对象靠近右侧的墙壁并触摸它,则该函数返回true并执行所有内容。但是,假设我沿着墙壁滑动并直接向下移动并且没有墙壁,则对象会在某一点停止,因为它检测到对象底部与墙壁顶部之间的碰撞(当没有时)以及对象右侧和墙壁左侧之间的碰撞。

我正试图找到另一种解决方案。我只是希望我的对象停在任何一面墙上,能够移动(或滑下一面墙),而不会怀疑附近没有墙的地方可能会发生碰撞。我觉得我已经非常接近解决方案了,但是我需要一点额外的帮助。

更新

我已经更新了moveRight函数和update函数@Adrian Shum和@Matthew Mark Miller,我现在用一个整数做了所有事情(意思是用1f代替0.01f)。

因此,我用于移动对象的以下代码如下:

if(Gdx.input.isKeyPressed(Keys.RIGHT)){

                 if(collisionManager.canSpriteNotMoveRight(object)){
                     object.stopGoingRight();
                 }else{
                     object.moveRight();
                 }
             }

在我的collisionManager类中,函数stopGoingRight如下所示:

public void stopGoingRight(){
    position.x -= 1f;
    update();
}

到目前为止,一切顺利。当物体与墙壁碰撞时,物体停止并反弹回来。那很好。但是我有另一个问题(这是令人恼火的),我将尽我所能描述它。例如,如果我一直把物体向上移动到一面墙上,物体会从那面墙上反弹很多次;如果我停止按向上键,物体有时会卡在墙内。因此,当我按下向下键时,它会向上而不是向下(或者如果我按下左,对象会向右而不是向左),因为overlaps函数被执行(因为对象和墙相交)。

我有办法解决这个问题吗?似乎Libgdx并不完全适合处理这种碰撞检测,但是我现在正在深入构建我的游戏。

共有2个答案

翁和颂
2023-03-14

多亏了以下链接,我终于找到了一个好的解决方案:在重叠时,玩家会被卡住libgdx Rectangle。

基本上,我必须创建一个“假”移动,以查看对象是否会与墙碰撞。如果发生碰撞,我只是停止对象,不执行新的移动。

谢谢大家的帮助:)!!非常感谢!!

叶允晨
2023-03-14

你的碰撞算法看起来很冗长,但很正确(冗长,因为x的最小值,x宽度总是只有x,因为宽度必须是

您是否考虑过这是浮点精度问题的可能性?例如,如果您将1添加到fp数字中,然后从结果中删除1,则不能保证返回到原始值。您可能或多或少,因为中间结果可能无法表示为浮点数。

我最喜欢的例子:.1f .2f

 类似资料:
  • 在我的自上而下游戏中,当我的玩家通过婴儿床时,我该如何让他发生碰撞?我用的是交叉矩形。 这是我的密码 更新方法 在渲染方法中 这是完整的代码 谁能告诉我矩形碰撞检测的正确实现是什么?没有重叠,我是这个框架的新手。致谢和预付款:)

  • 我使用libgdx为一个项目制作了一个2D游戏,我的碰撞检测技术基于。在矩形中重叠方法,效果良好。我想了解其背后的实现,如果我要将其与intersects方法并行,我知道它是如何工作的。但这是唯一的吗?我读到,在离散碰撞检测方法中,不仅需要计算实体是否发生碰撞,还需要计算它们发生碰撞的“程度”(碰撞深度),并使用轴对齐的边界盒算法将实体推回。首先,我对矩形重叠技术是否与libgdx中的AAAB相同

  • 问题内容: 我遇到一个问题,即一个矩形与另一个矩形发生碰撞。所以我的问题是,如何获取相交方法以检查碰撞?还是在这种情况下还有其他方法可以处理碰撞? 我正在创建一个回合制战斗游戏(类似于《最终幻想》或《龙骑传奇》),其中玩家的角色在屏幕的右侧,而敌人在屏幕的左侧。玩家和敌人轮流进攻。因此,当玩家攻击时,子画面动画会从右到左在屏幕上移动,直到停在敌人面前,进行攻击并返回到其起始坐标。玩家和敌人周围都有

  • 我遇到了一个问题,显示一个矩形与另一个矩形发生了碰撞。所以我的问题是,如何让Intersect方法检查碰撞?或者在这种情况下有其他方法来处理碰撞吗? 我正在制作一个回合制战斗游戏(类似于《最终幻想》或《龙骑兵传说》),其中玩家的角色位于屏幕的右侧,敌人位于屏幕左侧。玩家和敌人轮流攻击。因此,当玩家攻击时,精灵动画会在屏幕上从右向左移动,直到它停在敌人面前,攻击并返回到其起始坐标。玩家和敌人都有一个

  • 因此,我创建了一个方法来检测球形球和矩形球之间的碰撞。我把它分成了4部分;它检测圆的顶部、圆的左侧、圆的底部、圆的右侧和矩形之间的碰撞。其中的两个工作是检测圆上的左点和矩形之间的碰撞,以及检测圆上的右点和矩形之间的碰撞。但是,不起作用的是,如果最上面的点或最下面的点接触矩形,就不会检测到碰撞,正如我记录if语句以查看是否输入它时所看到的那样。下面是我的代码(方法。getr()获取圆圈半径): 我已

  • 我正在编写一个游戏,涉及碰撞的一个移动的圆,由用户控制,和一个移动的矩形,由计算机控制。 完整的代码可以在这里找到:游戏 我在圆和矩形之间的碰撞检测方面遇到了麻烦。当矩形是静态的,碰撞检测工作完美。当圆和矩形的边缘在任一边接触时,程序就会按照它应该的方式进行操作。 这是碰撞检测功能。 谢谢。