简体   繁体   English

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

[英]Collision detection between rectangles (no overlap) - libgdx

I've been at this for 2-3 weeks now and I still can't manage to have a proper collision detection. 我已经在这里工作了2-3个星期,我仍然无法进行适当的碰撞检测。 I have created a maze using rectangles. 我用矩形创建了一个迷宫。 I want my object (which is in a Rectangle) to stop whenever my object collides with any wall and be able to move anywhere (or slide down a wall). 我希望我的对象(在矩形中)在我的对象与任何墙碰撞并且能够移动到任何地方(或向下滑动墙)时停止。 My walls (the rectangles) have negative coordinates like the following: 我的墙(矩形)具有负坐标,如下所示:

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

I'm currently using an overlaps method that I've found in SO. 我目前正在使用我在SO中找到的重叠方法。 Here's the method that's in my CollisionManager class: 这是我的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);
}

I have a function which saves all position moves made by the object. 我有一个函数可以保存对象所做的所有位置移动。 Thus, when a collision occurs, the object restores to the previous move before the last move (since the last move is when the collision occured) (example below): 因此,当发生碰撞时,对象恢复到最后一次移动之前的前一次移动(因为最后一次移动是发生碰撞时)(下面的示例):

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();
}

Additional information: I'm moving my object like this: 附加信息:我正在移动我的对象:

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

public void update(){

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

Where I'm stuck is my overlaps function (the one I've found in SO). 我被困的地方是我的重叠功能(我在SO中找到的那个)。 It works most cases; 它适用于大多数情况; yet, for example, if the object moves near a wall on the right and touches it, the function returns true and everything gets executed. 但是,例如,如果对象在右边的墙壁附近移动并触摸它,则该函数返回true并执行所有操作。 But let's say if I slide along the wall and move directly down and that there are no walls, the object stops at one point because it detects a collision between the bottom of the object and the top of a wall (when there's none) and a collision between the right of the object and the left of a wall. 但是让我们说如果我沿着墙壁滑动并直接向下移动并且没有墙壁,则物体在某一点停止,因为它检测到物体底部与墙壁顶部之间的碰撞(当没有墙壁时)和物体右侧与墙壁左侧之间的碰撞。

I'm trying to find another solution for this. 我正试图为此找到另一种解决方案。 I just want my object to stop at any wall and be able to move (or slide down a wall) without suspecting that there might be a collision where there are no walls nearby. 我只是希望我的物体停在任何墙壁上并能够移动(或滑下墙壁)而不怀疑在附近没有墙壁的地方可能发生碰撞。 I feel that I'm very close to a solution, but I would need a little bit of extra help. 我觉得我非常接近解决方案,但我需要一些额外的帮助。

UPDATE UPDATE

I've updated the moveRight function and the update function. 我已经更新了moveRight函数和更新函数。 @Adrian Shum and @Matthew Mark Miller I've made everything now with an integer (meaning instead of 0.01f, I use 1f). @Adrian Shum和@Matthew Mark Miller我现在用一个整数(意思是代替0.01f,我使用1f)制作了所有东西。

Thus the following code that I use to move the object is like this: 因此,我用来移动对象的以下代码是这样的:

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

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

In my collisionManager class, the function stopGoingRight is the following: 在我的collisionManager类中,函数stopGoingRight如下:

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

So far, so good. 到现在为止还挺好。 When the object collides with the wall, the object stops and bounces back. 当物体与墙壁碰撞时,物体会停止并反弹。 That's good. 非常好。 But I have another problem (which is irritating) that I'll try to describe the best I can. 但我有另一个问题(这很令人恼火),我会尽力描述最好的问题。 If, for example, I keep moving the object up to a wall, the object will bounce back many times from that wall; 例如,如果我继续将物体移动到墙上,物体将从该墙反弹多次; if I stop pressing the up key, the object will sometimes stay stuck within the wall. 如果我停止按下向上键,物体有时会卡在墙内。 Thus what happen is when I press the down key, it'll go up instead of going down (or if I press left, the object will go right instead of going left) because the overlaps function gets executed (since both object and the wall intersect). 因此,当我按下向下键时,它会上升而不是下降(或者如果我向左按下,对象将向右而不是向左),因为重叠功能被执行(因为对象和墙都是相交)。

Is there a way for me to solve this? 我有办法解决这个问题吗? It seems as though Libgdx isn't perfectly well-suited to handle this kind of collision detection, but I'm just far into deep in building my game right now. 似乎Libgdx并不是非常适合处理这种碰撞检测,但我现在正在深入构建我的游戏。

Your collision algorithm seems wordy but correct (Wordy because the min of x, x+ width is always just x as width must be >= 0, and the inverse is true for max). 你的碰撞算法看起来很冗长但是正确(Wordy因为x的最小值,x +宽度总是只有x,因为宽度必须> = 0,而最大值的倒数为真)。

Have you considered the possibility that it's a floating point precision issue? 您是否考虑过它是浮点精度问题的可能性? Eg if you add 1 to an fp number, then later remove 1 from the result, you aren't guaranteed to be back at the original value. 例如,如果您将1添加到fp编号,然后从结果中删除1,则无法保证返回原始值。 You may be a little more or less as the intermediate result may not be representable as a float. 您可能会稍微或多或少,因为中间结果可能无法表示为浮点数。

My favorite example: .1f + .2f > .3f 我最喜欢的例子:.1f + .2f> .3f

I've finally found a good solution all thanks to the following link: On overlap, player gets stuck libgdx Rectangle . 我终于找到了一个很好的解决方案,这要归功于以下链接: 在重叠时,玩家被卡住了libgdx矩形

Basically I have to create a "fake" move to see if the object will collide with the wall. 基本上我必须创建一个“假”移动,以查看对象是否会与墙碰撞。 If there's a collision, i just stop the object and don't execute the new move. 如果发生碰撞,我只是停止对象而不执行新移动。

Thanks for everyone's help :)!! 谢谢大家的帮助:) !! It's greatly appreciated!! 非常感谢!!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM