简体   繁体   English

方块之间的2D碰撞检测,简单但比布尔值更具体+不受大型空间跳跃的影响

[英]2D Collision Detection between squares, simple but more specific than boolean + immune to large spacial jumps

Would like to know which direction player hits terrain tile from (just a simple up/down, left/right). 想知道玩家从哪个方向击打地形图块(只需简单地向上/向下,向左/向右)。 Everything I find is either too simple, or is much more complex and seemingly way too much for what I need, like with AABB (granted it's hard to tell, my brain has trouble digesting what amounts to really long equations). 我发现的一切都太简单了,或者太复杂了,似乎对于我所需的东西来说太多了,比如AABB(这很难说,我的大脑很难消化真正长的方程式)。 What I've got so far is the result of spending better part of today reading and experimenting: 到目前为止,我得到的是今天大部分时间阅读和实验的结果:

public int move(double toX, double toY) {

    int col = COLLISION_NONE; //these are bit flags, in case I collide with a block to my right as well as below me

    double nextX = mX+(toX*main.getDelta()); //delta regulates speed
    double nextY = mY+(toY*main.getDelta());

    if(mTerrainCollision){

        int w = GameView.GameLoop.TILE_WIDTH;
        int h = GameView.GameLoop.TILE_HEIGHT;

        for(int i = -2; i <= 2; i++) //broad tile picking will be optimized later, better trace around players path
            for(int j = -2; j <= 2; j++) {
                GameTerrain.Block block = main.mTerrain.get(((int)Math.round(mX)/w)+i,((int)Math.round(mY)/h)+j);
                if(block.type != GameTerrain.BLOCK_TYPE_NONE) {

                    if(nextX+w >= block.x() && mX+w <= block.x()){ //COLLISION ON THE RIGHT?
                        if(mY+h > block.y() && mY < block.y()+h) { //<THIS is a problem line, see below
                            nextX = block.x() - w;
                            xMomentum = 0;

                            col |= COLLISION_RIGHT;
                        }
                    }

                    else if(nextX < block.x()+w && mX >= block.x()+w){ //COLLISION ON THE LEFT?
                        if(mY+h > block.y() && mY < block.y()+h) { //same as above, make sure were on the same plane
                            nextX = block.x() + w;
                            xMomentum = 0;

                            col |= COLLISION_LEFT;
                        }
                    }


                    if(nextY+h >= block.y() && mY+h <= block.y()){ //COLLISION ON THE BOTTOM?
                        if(mX+w > block.x() && mX < block.x()+w) { //make sure were on the same plane
                            nextY = block.y() - h;
                            yMomentum = 0;

                            col |= COLLISION_DOWN;
                        }
                    }

                    else if(nextY < block.y()+h && mY >= block.y()+h){ //COLLISION ON THE TOP?
                        if(mX+w > block.x() && mX < block.x()+w) { //make sure were on the same plane
                            nextY = block.y() + h;
                            yMomentum = 0;

                            col |= COLLISION_UP;
                        }
                    }
                }
            }
    }

    mX = nextX;
    mY = nextY; 

    return col;

}

It works... mostly. 大多数情况下都有效。 Player won't phase through blocks even after long sleeps making the delta skyrocket. 即使长时间睡眠使增量飙升,玩家也不会逐步穿越障碍。 The collision detection itself works unless the player's previous position (mX/mY) are not on the same plane as the block we're checking (see commented line with "THIS..."). 除非玩家的先前位置(mX / mY)与我们要检查的块不在同一平面上,否则碰撞检测本身将起作用(请参见带有“ THIS ...”的注释行)。 Say we're perfectly diagonal to a block and moving straight for it, player will zip right through. 假设我们与街区完美对角,然后直线移动,播放器将向右滑动。 I've been scratching my head for a while now trying to figure out how to go about solving this last issue, preferably without a major rehaul of everything, but if it had to come to that oh well! 我已经摸索了一段时间,试图找出解决最后一个问题的方法,最好是不进行任何大修,但是如果必须解决的话,哦,好! I'm only interested in simple collision data for things like "Did I touch a floor this frame? Ok I can jump", "Am I touching a wall right now? Ok I can wall jump, but not if I also touched a floor", etc. 我只对简单的碰撞数据感兴趣,例如“我在这个框架上碰过地板吗?可以跳吗?”,“我现在在碰壁吗?可以跳墙,但是如果我也碰过地板就不感兴趣”等

由对象的AABB的大小(保持壁的AABB的固定的中心)生长的壁的AABB,构造从对象的之前和位置(使用对象的AABB的中心) 的线段,然后做一个分段AABB相交测试

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

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