简体   繁体   English

寻找一种处理基于平铺的角碰撞的好方法

[英]Looking for a good way to handle tile based corner-collisions

Okay so, i have a tiled map (obviously) and implemented a collision detection system which is working really well for me. 好的,我有一个平铺的地图(很明显),并且实现了一个碰撞检测系统,该系统对我来说真的很好用。 It has trouble with those pesky corners though. 但是在那些讨厌的角落有麻烦。 I do know why that is, since i don't even check the corners. 我确实知道为什么会这样,因为我什至不检查角落。 And that's the point, i don't know how to do that. 这就是重点,我不知道该怎么做。 So, first of all here is my current code: 所以,首先这里是我当前的代码:

        Body body = currentObject.Body; // Body is a class storing position, velocity, bounds and so on.

        int tileDimensions = level.TileWidth; // Since the tiles are squares...

        int leftTile = body.Bounds.Left / tileDimensions;
        int topTile = body.Bounds.Top / tileDimensions;
        int rightTile = (int)Math.Ceiling((float)body.Bounds.Right / tileDimensions - 1);
        int bottomTile = (int)Math.Ceiling(((float)body.Bounds.Bottom / tileDimensions) - 1);

        if (body.Velocity.Y > 0) // Moving down.
        {
            for (int x = leftTile; x <= rightTile; x++)
            {
                for (int y = bottomTile + 1; y <= (bottomTile + 1) + (body.Velocity.Y / tileDimensions); y++)
                {
                    if (tiles[x, y] != null && !tiles[x, y].IsPassable)
                    {
                        newVelocity = new Vector2(body.Velocity.X, MathHelper.Clamp(body.Velocity.Y, 0, tiles[x, y].Body.Bounds.Top - body.Bounds.Bottom));
                        body.Velocity = newVelocity;
                        break;
                    }
                }
            }
        }

So thats just for moving down. 因此,仅此而已。 There are 3 other constructs like that for up, left and right. 上面,左边和右边还有其他3种构造。 The only real difference is the loop and the way i clamp the velocity. 唯一真正的区别是回路和钳制速度的方式。

As you can see i just loop through all tiles i could potentially collide with. 如您所见,我只是遍历所有可能发生碰撞的图块。 Then i clamp the velocity, which will slow it down in case there is indeed a tile in it's way. 然后我钳住速度,以防万一确实有瓷砖在移动。

Now, i'm afraid it's hard to explain my problem with just words, so i'll have to post a picture too. 现在,恐怕仅凭文字很难解释我的问题,因此我也必须张贴一张图片。

在此处输入图片说明

In this screenshot yellow means unpassable tile, black are the tiles the above code is currently checking for collision and red is the player. 在此屏幕截图中,黄色表示不可通过的图块,黑色是上述代码当前正在检查碰撞的图块,红色是播放器。

To show you what the problem is, imagine i were to accelerate up and right in this frame. 为了向您展示问题所在,想象一下我将在此框架内加速前进。 As you can see, there would be a collision with the tile on the upper right of my player but the player will just move into the tile since i don't check it for collision. 如您所见,我的播放器右上角的瓷砖会发生碰撞,但是由于我不检查它是否碰撞,所以玩家会进入瓷砖中。 And i will not check it in the next frame either, since i don't check for blocks i'm in because ... i don't even know, that would betray the whole idea behind my code, wouldn't it ? 而且我也不会在下一帧中检查它,因为我不检查我所在的块,因为...我什至不知道,那会背叛我代码的整个思想,不是吗? :P :P

Of course, i could just extend my "searching" range, but then i would collide with tiles, i shouldn't collide with. 当然,我可以扩展“搜索”范围,但随后我将与图块发生冲突,而我不应该与之发生冲突。 Currently, i'm fixing this with an extra check for all the tiles my bounds are overlapping with and... you know, just moving the player back if i find any. 目前,我正在对所有与边界重叠的图块进行额外检查,以解决此问题,并且...如果知道,只要将播放器移回去即可。 But this is really messy and it doesn't preserve the initial velocity. 但这确实很混乱,并且不能保留初始速度。 If the player hits a corner he will move into it, i will detect that, move him back and null his velocity. 如果玩家撞到一个角落,他将进入该角落,我将检测到该情况,将其移回并使其速度无效。 That just doesn't feel right, it's clunky. 只是感觉不对,笨拙。

I just can't seem to figure out a good way of dealing with such cases. 我只是想不出一种处理此类案件的好方法。 I doesn't happen too often (since it's really hard to reproduce) but once in a while it happens and that is of course unacceptable. 我不会经常发生(因为很难复制),但偶尔会发生,这当然是不可接受的。

I'd really like to not even have a bugfix-type thing for it but to integrate it in my other code as nicely as possible. 我真的很想什至没有一个bugfix类型的东西,而是尽可能将其更好地集成到我的其他代码中。 This is not mandatory, but it would be cool to be able to do that. 这不是强制性的,但是能够做到这一点将很酷。 So i'd really appreciate if anyone of you guys could throw something at me. 因此,如果你们中有人能向我扔东西,我将非常感激。

Anyway, i hope you were able to follow what i was trying to say. 无论如何,我希望你能听懂我想说的话。 Since english isn't my native language it's a little hard to explain such things at times. 由于英语不是我的母语,因此有时很难解释这些事情。 Also i'm just really bad at explaining things :/ 我也很不擅长解释事情:/

I suppose you could just add 4 more cases, handing when the currentObject is moving in a diagonal, no? 我想您可以再添加4种情况,当currentObject沿对角线移动时处理,不是吗?

However, you might want to investigate collision based on bounding volumes. 但是,您可能要根据边界体积研究碰撞。

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

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