Esempio n. 1
0
    //垂直碰撞检测:原理同上
    public static TerrainCollisionData VerticalCollision(Room room, TerrainCollisionData cd)
    {
        IntVector2 lastTile = room.GetTilePosition(cd.lastPos);
        int        count    = 0;

        //速度大于0:向上移动
        if (cd.vel.y > 0.0)
        {
            int  y1       = room.GetTilePosition(new Vector2(0.0f, (float)(cd.pos.y + (double)cd.rad))).y;
            int  y2       = room.GetTilePosition(new Vector2(0.0f, cd.lastPos.y + cd.rad)).y;
            int  x1       = room.GetTilePosition(new Vector2((float)(cd.pos.x - (double)cd.rad + 1.0), 0.0f)).x;
            int  x2       = room.GetTilePosition(new Vector2((float)(cd.pos.x + (double)cd.rad - 1.0), 0.0f)).x;
            bool @checked = false;
            for (int y = y2; y <= y1 && !@checked; ++y)
            {
                for (int x = x1; x <= x2 && !@checked; ++x)
                {
                    if (room.GetTile(x, y).Terrain == Room.Tile.TerrainType.Solid && room.GetTile(x, y - 1).Terrain != Room.Tile.TerrainType.Solid && (lastTile.y < y || room.GetTile(cd.lastPos).Terrain == Room.Tile.TerrainType.Solid))
                    {
                        cd.pos.y          = y * 20f - cd.rad;
                        cd.vel.y          = 0.0f;
                        cd.contactPoint.y = 1;
                        @checked          = true;
                    }
                    ++count;
                    if (count > MaxRepeats)
                    {
                        Debug.Log("!!!!! sharedphysics emergency breakout of terrain check!");
                        @checked = true;
                    }
                }
            }
        }
        //速度小于0:向下移动
        else if (cd.vel.y < 0.0)
        {
            int  y1       = room.GetTilePosition(new Vector2(0.0f, (float)(cd.pos.y - (double)cd.rad))).y;
            int  y2       = room.GetTilePosition(new Vector2(0.0f, cd.lastPos.y - cd.rad)).y;
            int  x1       = room.GetTilePosition(new Vector2((float)(cd.pos.x - (double)cd.rad + 1.0), 0.0f)).x;
            int  x2       = room.GetTilePosition(new Vector2((float)(cd.pos.x + (double)cd.rad - 1.0), 0.0f)).x;
            bool @checked = false;
            for (int y = y2; y >= y1 && !@checked; --y)
            {
                for (int x = x1; x <= x2 && !@checked; ++x)
                {
                    if (SolidFloor(room, x, y, cd.goThroughFloors, cd.lastPos) && !SolidFloor(room, x, y + 1, cd.goThroughFloors, cd.lastPos) && (lastTile.y > y || room.GetTile(cd.lastPos).Terrain == Room.Tile.TerrainType.Solid))
                    {
                        cd.pos.y          = (float)((y + 1.0) * 20.0) + cd.rad;
                        cd.vel.y          = 0.0f;
                        cd.contactPoint.y = -1;
                        @checked          = true;
                    }
                    ++count;
                    if (count > MaxRepeats)
                    {
                        Debug.Log("!!!!! sharedphysics emergency breakout of terrain check!");
                        @checked = true;
                    }
                }
            }
        }
        return(cd);
    }
Esempio n. 2
0
    public static TerrainCollisionData SlopesVertically(Room room, TerrainCollisionData cd)
    {
        IntVector2 tilePos = room.GetTilePosition(cd.pos);
        IntVector2 intVec  = new IntVector2(0, 0);

        Room.SlopeDirection slopeDir = room.IdentifySlope(cd.pos);
        //如果目标地形不是Slope
        if (room.GetTile(cd.pos).Terrain != Room.Tile.TerrainType.Slope)
        {
            //左边Tile斜坡类型不是Broken && 碰撞体与左边Tile发生碰撞:(碰撞体Center - 碰撞半径).X < 当前Tile边界Pos.X
            if (room.IdentifySlope(tilePos.x - 1, tilePos.y) != Room.SlopeDirection.Broken && cd.pos.x - (double)cd.rad <= room.MiddleOfTile(cd.pos).x - 10.0)
            {
                slopeDir = room.IdentifySlope(tilePos.x - 1, tilePos.y);
                intVec.x = -1;
            }
            //右边检测同上
            else if (room.IdentifySlope(tilePos.x + 1, tilePos.y) != Room.SlopeDirection.Broken && cd.pos.x + (double)cd.rad >= room.MiddleOfTile(cd.pos).x + 10.0)
            {
                slopeDir = room.IdentifySlope(tilePos.x + 1, tilePos.y);
                intVec.x = 1;
            }
            //下边检测同上
            else if (cd.pos.y - (double)cd.rad < room.MiddleOfTile(cd.pos).y - 10.0 && room.IdentifySlope(tilePos.x, tilePos.y - 1) != Room.SlopeDirection.Broken)
            {
                slopeDir = room.IdentifySlope(tilePos.x, tilePos.y - 1);
                intVec.y = -1;
            }
            //上边检测同上
            else if (cd.pos.y + (double)cd.rad > room.MiddleOfTile(cd.pos).y + 10.0 && room.IdentifySlope(tilePos.x, tilePos.y + 1) != Room.SlopeDirection.Broken)
            {
                slopeDir = room.IdentifySlope(tilePos.x, tilePos.y + 1);
                intVec.y = 1;
            }
        }
        //如果斜坡类型不是损坏类型
        if (slopeDir != Room.SlopeDirection.Broken)
        {
            //得到碰撞的tile
            Vector2 tile = room.MiddleOfTile(room.GetTilePosition(cd.pos) + intVec);
            float   dist;
            int     sign;
            switch (slopeDir)
            {
            //上左、上右斜坡,碰撞由上到下
            case Room.SlopeDirection.UpLeft:
                dist = (float)(cd.pos.x - (tile.x - 10.0) + (tile.y - 10.0));
                sign = -1;
                break;

            case Room.SlopeDirection.UpRight:
                dist = (float)(20.0 - (cd.pos.x - (tile.x - 10.0)) + (tile.y - 10.0));
                sign = -1;
                break;

            case Room.SlopeDirection.DownLeft:
                dist = (float)(20.0 - (cd.pos.x - (tile.x - 10.0)) + (tile.y - 10.0));
                sign = 1;
                break;

            default:
                dist = (float)(cd.pos.x - (tile.x - 10.0) + (tile.y - 10.0));
                sign = 1;
                break;
            }
            if (sign == -1 && cd.pos.y <= dist + (double)cd.rad + cd.rad)
            {
                cd.pos.y = dist + cd.rad + cd.rad;
            }
            else if (sign == 1 && cd.pos.y >= dist - (double)cd.rad - cd.rad)
            {
                cd.pos.y = dist - cd.rad - cd.rad;
            }
        }
        return(cd);
    }
Esempio n. 3
0
    //水平碰撞检测
    public static TerrainCollisionData HorizontalCollision(Room room, TerrainCollisionData cd)
    {
        //获取前一帧Tile位置
        IntVector2 lastTile = room.GetTilePosition(cd.lastPos);
        int        count    = 0;

        //速度大于零:向右移动
        if (cd.vel.x > 0.0)
        {
            //获取当前帧、前一帧(位置+半径)的Tile信息
            int  x1       = room.GetTilePosition(new Vector2(cd.pos.x + cd.rad, 0.0f)).x;
            int  x2       = room.GetTilePosition(new Vector2(cd.lastPos.x + cd.rad, 0.0f)).x;
            int  y1       = room.GetTilePosition(new Vector2(0.0f, (float)(cd.pos.y + (double)cd.rad - 1.0))).y;
            int  y2       = room.GetTilePosition(new Vector2(0.0f, (float)(cd.pos.y - (double)cd.rad + 1.0))).y;
            bool @checked = false;
            //从左到右、从上到下遍历地形
            for (int x = x2; x <= x1 && !@checked; ++x)
            {
                for (int y = y2; y <= y1 && !@checked; ++y)
                {
                    if (room.GetTile(x, y).Terrain == Room.Tile.TerrainType.Solid &&
                        room.GetTile(x - 1, y).Terrain != Room.Tile.TerrainType.Solid &&
                        (lastTile.x < x || room.GetTile(cd.lastPos).Terrain == Room.Tile.TerrainType.Solid))
                    {
                        //修改碰撞数据
                        cd.pos.x          = x * 20f - cd.rad;
                        cd.vel.x          = 0.0f;
                        cd.contactPoint.x = 1;
                        @checked          = true;
                    }
                    //碰撞次数阈值检测
                    ++count;
                    if (count > MaxRepeats)
                    {
                        Debug.Log("!!!!! sharedphysics emergency breakout of terrain check!");
                        @checked = true;
                    }
                }
            }
        }
        //速度小于零:向左移动 : 检测方式同上
        else if (cd.vel.x < 0.0)
        {
            int  x1       = room.GetTilePosition(new Vector2(cd.pos.x - cd.rad, 0.0f)).x;
            int  x2       = room.GetTilePosition(new Vector2(cd.lastPos.x - cd.rad, 0.0f)).x;
            int  y1       = room.GetTilePosition(new Vector2(0.0f, (float)(cd.pos.y + cd.rad - 1.0))).y;
            int  y2       = room.GetTilePosition(new Vector2(0.0f, (float)(cd.pos.y - cd.rad + 1.0))).y;
            bool @checked = false;
            for (int x = x2; x >= x1 && !@checked; --x)
            {
                for (int y = y2; y <= y1 && !@checked; ++y)
                {
                    if (room.GetTile(x, y).Terrain == Room.Tile.TerrainType.Solid && room.GetTile(x + 1, y).Terrain != Room.Tile.TerrainType.Solid && (lastTile.x > x || room.GetTile(cd.lastPos).Terrain == Room.Tile.TerrainType.Solid))
                    {
                        cd.pos.x          = (float)((x + 1.0) * 20.0) + cd.rad;
                        cd.vel.x          = 0.0f;
                        cd.contactPoint.x = -1;
                        @checked          = true;
                    }
                    ++count;
                    if (count > MaxRepeats)
                    {
                        Debug.Log("!!!!! sharedphysics emergency breakout of terrain check!");
                        @checked = true;
                    }
                }
            }
        }
        return(cd);
    }