Esempio n. 1
0
 public virtual void OnBoundingBoxExit(ActiveBoundingBox other)
 {
 }
Esempio n. 2
0
 public virtual void OnBoundingBoxEnter(CollisionStateFlags collisionState, int pixelPenetration, ActiveBoundingBox other)
 {
 }
Esempio n. 3
0
 public override void OnBoundingBoxExit(ActiveBoundingBox other)
 {
 }
Esempio n. 4
0
 public override void OnBoundingBoxEnter(CollisionStateFlags collisionState, int pixelPenetration, ActiveBoundingBox other)
 {
     if ((collisionState & CollisionStateFlags.GROUND) == CollisionStateFlags.GROUND)
     {
         VelocityY = 0.0f;
         IsJumping = false;
     }
 }
Esempio n. 5
0
 public CollisionEvent(int penetrationDepth, ActiveBoundingBox.CollisionStateFlags collisionState, ActiveBoundingBox other)
 {
     Other            = other;
     CollisionState   = collisionState;
     PenetrationDepth = penetrationDepth;
 }
Esempio n. 6
0
    private void MoveBoundingBoxInstances()
    {
        for (int i = 0; i < ObstacleBoundingBoxInstances.Count; ++i)
        {
            ActiveBoundingBox obstacleBoundingBoxInstance = ObstacleBoundingBoxInstances[i];

            obstacleBoundingBoxInstance.Awake();
            obstacleBoundingBoxInstance.ComputeVelocity();
            obstacleBoundingBoxInstance.IncrementPositions();
            obstacleBoundingBoxInstance.SetPixelPosition(obstacleBoundingBoxInstance.PixelPositionX, obstacleBoundingBoxInstance.PixelPositionY);
            obstacleBoundingBoxInstance.DrawGeometry();
        }

        for (int i = 0; i < ControllerBoundingBoxInstances.Count; ++i)
        {
            ActiveBoundingBox controllerBoundingBoxInstance = ControllerBoundingBoxInstances[i];

            controllerBoundingBoxInstance.Awake();
            controllerBoundingBoxInstance.ComputeVelocity();
            controllerBoundingBoxInstance.IncrementPositions();

            int controllerPixelMinimumX = controllerBoundingBoxInstance.PixelPositionX;
            int controllerPixelMaximumX = controllerPixelMinimumX + (int)(controllerBoundingBoxInstance.Width * controllerBoundingBoxInstance.PixelsPerUnit);

            int controllerPixelMinimumY = controllerBoundingBoxInstance.PixelPositionY;
            int controllerPixelMaximumY = controllerPixelMinimumY + (int)(controllerBoundingBoxInstance.Height * controllerBoundingBoxInstance.PixelsPerUnit);

            for (int j = 0; j < ObstacleBoundingBoxInstances.Count; ++j)
            {
                ActiveBoundingBox    obstacleBoundingBoxInstance = ObstacleBoundingBoxInstances[j];
                BoundingBox.Geometry obstaclePixelGeometry       = obstacleBoundingBoxInstance.PixelGeometry;

                int obstaclePixelMinimumX = obstaclePixelGeometry.MinimumX;
                int obstaclePixelMinimumY = obstaclePixelGeometry.MinimumY;

                int obstaclePixelMaximumX = obstaclePixelGeometry.MaximumX;
                int obstaclePixelMaximumY = obstaclePixelGeometry.MaximumY;

                if (
                    obstaclePixelMinimumX >= controllerPixelMaximumX ||
                    obstaclePixelMinimumY >= controllerPixelMaximumY ||
                    controllerPixelMinimumX > obstaclePixelMaximumX ||
                    controllerPixelMinimumY > obstaclePixelMaximumY
                    )
                {
                    CollisionEvent exitCollisionEvent = new CollisionEvent(0, ActiveBoundingBox.CollisionStateFlags.NONE, obstacleBoundingBoxInstance);

                    if (!CollisionEventHistory.Contains(exitCollisionEvent) ||
                        ((obstacleBoundingBoxInstance.BehaviourFlag & BoundingBox.BehaviourFlags.SLOPE) == BoundingBox.BehaviourFlags.SLOPE)
                        )
                    {
                        continue;
                    }

                    controllerBoundingBoxInstance.OnBoundingBoxExit(obstacleBoundingBoxInstance);
                    obstacleBoundingBoxInstance.OnBoundingBoxExit(controllerBoundingBoxInstance);

                    CollisionEventHistory.Remove(exitCollisionEvent);

                    continue;
                }

                int[] pixelPenetrationList = new int[4]
                {
                    Mathf.Abs(controllerPixelMaximumX - obstaclePixelMinimumX),
                    Mathf.Abs(controllerPixelMaximumY - obstaclePixelMinimumY),
                    Mathf.Abs(obstaclePixelMaximumX - controllerPixelMinimumX),
                    Mathf.Abs(obstaclePixelMaximumY - controllerPixelMinimumY)
                };

                int minimumPixelPenetration = pixelPenetrationList.Min();
                ActiveBoundingBox.CollisionStateFlags controllerCollisionState = ActiveBoundingBox.CollisionStateFlags.NONE;
                ActiveBoundingBox.CollisionStateFlags obstacleCollisionState   = ActiveBoundingBox.CollisionStateFlags.NONE;

                if (minimumPixelPenetration == pixelPenetrationList[0])
                {
                    controllerCollisionState |= ActiveBoundingBox.CollisionStateFlags.RIGHT_WALL;
                    obstacleCollisionState   |= ActiveBoundingBox.CollisionStateFlags.LEFT_WALL;

                    if ((obstacleBoundingBoxInstance.BehaviourFlag & BoundingBox.BehaviourFlags.SLOPE) == BoundingBox.BehaviourFlags.SLOPE)
                    {
                        SlopeObstacleBoundingBox slopeObstacleBoundingBoxInstance = obstacleBoundingBoxInstance as SlopeObstacleBoundingBox;
                        List <List <bool> >      slopeTextureBitmap = slopeObstacleBoundingBoxInstance.TextureBitmap;

                        if (controllerBoundingBoxInstance.VelocityY < 0.0f)
                        {
                            int bitmapColumnIndex = controllerPixelMaximumX - obstaclePixelMinimumX - 1;

                            int pixelPenetrationY          = obstaclePixelMaximumY - controllerPixelMinimumY;
                            int pixelPenetrationAllowanceY = 0;

                            for (int k = slopeTextureBitmap.Count - 1; k > 0; --k)
                            {
                                List <bool> bitmapRow = slopeTextureBitmap[k];

                                if (
                                    bitmapColumnIndex < 0 ||
                                    bitmapColumnIndex >= bitmapRow.Count
                                    )
                                {
                                    break;
                                }

                                if (bitmapRow[bitmapColumnIndex])
                                {
                                    break;
                                }

                                ++pixelPenetrationAllowanceY;
                            }

                            int pixelPenetrationDifferenceY = pixelPenetrationY - pixelPenetrationAllowanceY;

                            if (pixelPenetrationDifferenceY > 0)
                            {
                                CollisionEvent slopeEnterCollisionEvent = new CollisionEvent(
                                    pixelPenetrationDifferenceY,
                                    ActiveBoundingBox.CollisionStateFlags.GROUND,
                                    obstacleBoundingBoxInstance
                                    );

                                if (!CollisionEventHistory.Contains(slopeEnterCollisionEvent))
                                {
                                    controllerBoundingBoxInstance.OnBoundingBoxEnter(ActiveBoundingBox.CollisionStateFlags.GROUND, pixelPenetrationDifferenceY, obstacleBoundingBoxInstance);
                                    obstacleBoundingBoxInstance.OnBoundingBoxEnter(obstacleCollisionState, pixelPenetrationDifferenceY, controllerBoundingBoxInstance);

                                    CollisionEventHistory.Add(slopeEnterCollisionEvent);
                                }

                                controllerPixelMinimumY += pixelPenetrationDifferenceY;
                            }
                            else
                            {
                                CollisionEvent slopeExitCollisionEvent = new CollisionEvent(
                                    0,
                                    ActiveBoundingBox.CollisionStateFlags.NONE,
                                    obstacleBoundingBoxInstance
                                    );

                                if (CollisionEventHistory.Contains(slopeExitCollisionEvent))
                                {
                                    controllerBoundingBoxInstance.OnBoundingBoxExit(obstacleBoundingBoxInstance);
                                    obstacleBoundingBoxInstance.OnBoundingBoxExit(controllerBoundingBoxInstance);

                                    CollisionEventHistory.Remove(slopeExitCollisionEvent);
                                }
                            }
                        }
                        else
                        {
                            int pixelPenetrationX = controllerPixelMaximumX - obstaclePixelMinimumX;

                            if (controllerBoundingBoxInstance.VelocityX < 0.0f)
                            {
                                int bitmapColumnIndex = pixelPenetrationX - 1;

                                int pixelPenetrationY          = obstaclePixelMaximumY - controllerPixelMinimumY;
                                int pixelPenetrationAllowanceY = 0;

                                for (int k = slopeTextureBitmap.Count - 1; k > 0; --k)
                                {
                                    List <bool> bitmapRow = slopeTextureBitmap[k];

                                    if (
                                        bitmapColumnIndex < 0 ||
                                        bitmapColumnIndex >= bitmapRow.Count
                                        )
                                    {
                                        break;
                                    }

                                    if (bitmapRow[bitmapColumnIndex])
                                    {
                                        break;
                                    }

                                    ++pixelPenetrationAllowanceY;
                                }

                                int pixelPenetrationDifferenceY = pixelPenetrationY - pixelPenetrationAllowanceY;

                                if (pixelPenetrationDifferenceY < 0)
                                {
                                    controllerPixelMinimumY += pixelPenetrationDifferenceY;

                                    if (bitmapColumnIndex == 0)
                                    {
                                        --controllerPixelMinimumY;
                                    }
                                }
                            }
                            else
                            {
                                int bitmapRowCount = slopeTextureBitmap.Count;
                                int bitmapRowIndex = controllerPixelMinimumY - obstaclePixelMinimumY;

                                if (
                                    bitmapRowIndex >= 0 &&
                                    bitmapRowIndex < bitmapRowCount
                                    )
                                {
                                    List <bool> bitmapRow = slopeTextureBitmap[bitmapRowIndex];
                                    int         pixelPenetrationAllowanceX = 0;

                                    for (int k = 0; k < bitmapRow.Count; ++k)
                                    {
                                        if (bitmapRow[k])
                                        {
                                            break;
                                        }

                                        ++pixelPenetrationAllowanceX;
                                    }

                                    int pixelPenetrationDifferenceX = pixelPenetrationX - pixelPenetrationAllowanceX;

                                    if (pixelPenetrationDifferenceX > 0)
                                    {
                                        CollisionEvent slopeEnterCollisionEvent = new CollisionEvent(
                                            pixelPenetrationDifferenceX,
                                            ActiveBoundingBox.CollisionStateFlags.GROUND,
                                            obstacleBoundingBoxInstance
                                            );

                                        if (!CollisionEventHistory.Contains(slopeEnterCollisionEvent))
                                        {
                                            controllerBoundingBoxInstance.OnBoundingBoxEnter(controllerCollisionState, pixelPenetrationDifferenceX, obstacleBoundingBoxInstance);
                                            obstacleBoundingBoxInstance.OnBoundingBoxEnter(obstacleCollisionState, pixelPenetrationDifferenceX, controllerBoundingBoxInstance);

                                            CollisionEventHistory.Add(slopeEnterCollisionEvent);
                                        }

                                        controllerPixelMinimumX -= pixelPenetrationDifferenceX;
                                        controllerBoundingBoxInstance.RoundingRemainderX = 0.0f;

                                        if (
                                            controllerBoundingBoxInstance.VelocityX > 0 &&
                                            controllerBoundingBoxInstance.VelocityY == 0.0f
                                            )
                                        {
                                            ++controllerPixelMinimumY;
                                            ++controllerPixelMinimumX;
                                        }
                                    }
                                    else
                                    {
                                        CollisionEvent slopeExitCollisionEvent = new CollisionEvent(
                                            0,
                                            ActiveBoundingBox.CollisionStateFlags.NONE,
                                            obstacleBoundingBoxInstance
                                            );

                                        if (CollisionEventHistory.Contains(slopeExitCollisionEvent))
                                        {
                                            controllerBoundingBoxInstance.OnBoundingBoxExit(obstacleBoundingBoxInstance);
                                            obstacleBoundingBoxInstance.OnBoundingBoxExit(controllerBoundingBoxInstance);

                                            CollisionEventHistory.Remove(slopeExitCollisionEvent);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        controllerPixelMinimumX -= minimumPixelPenetration;
                    }

                    controllerBoundingBoxInstance.RoundingRemainderX = 0.0f;
                }
                else if (minimumPixelPenetration == pixelPenetrationList[1])
                {
                    controllerCollisionState |= ActiveBoundingBox.CollisionStateFlags.CEILING;
                    obstacleCollisionState   |= ActiveBoundingBox.CollisionStateFlags.GROUND;
                    controllerPixelMinimumY  -= minimumPixelPenetration;
                    controllerBoundingBoxInstance.RoundingRemainderY = 0.0f;
                }
                else if (minimumPixelPenetration == pixelPenetrationList[2])
                {
                    controllerCollisionState |= ActiveBoundingBox.CollisionStateFlags.LEFT_WALL;
                    obstacleCollisionState   |= ActiveBoundingBox.CollisionStateFlags.RIGHT_WALL;
                    controllerPixelMinimumX  += minimumPixelPenetration;
                    controllerBoundingBoxInstance.RoundingRemainderX = 0.0f;
                }
                else if (minimumPixelPenetration == pixelPenetrationList[3])
                {
                    controllerCollisionState |= ActiveBoundingBox.CollisionStateFlags.GROUND;
                    obstacleCollisionState   |= ActiveBoundingBox.CollisionStateFlags.CEILING;

                    if ((obstacleBoundingBoxInstance.BehaviourFlag & BoundingBox.BehaviourFlags.SLOPE) == BoundingBox.BehaviourFlags.SLOPE)
                    {
                        SlopeObstacleBoundingBox slopeObstacleBoundingBoxInstance = obstacleBoundingBoxInstance as SlopeObstacleBoundingBox;
                        List <List <bool> >      slopeTextureBitmap = slopeObstacleBoundingBoxInstance.TextureBitmap;

                        if (controllerBoundingBoxInstance.VelocityX > 0.0f)
                        {
                            int bitmapRowCount = slopeTextureBitmap.Count;
                            int bitmapRowIndex = controllerPixelMinimumY - obstaclePixelMinimumY;

                            if (
                                bitmapRowIndex >= 0 &&
                                bitmapRowIndex < bitmapRowCount
                                )
                            {
                                int pixelPenetrationX = controllerPixelMaximumX - obstaclePixelMinimumX;

                                List <bool> bitmapRow = slopeTextureBitmap[bitmapRowIndex];
                                int         pixelPenetrationAllowanceX = 0;

                                for (int k = 0; k < bitmapRow.Count; ++k)
                                {
                                    if (bitmapRow[k])
                                    {
                                        break;
                                    }

                                    ++pixelPenetrationAllowanceX;
                                }

                                int pixelPenetrationDifferenceX = pixelPenetrationX - pixelPenetrationAllowanceX;

                                if (pixelPenetrationDifferenceX > 0)
                                {
                                    CollisionEvent slopeEnterCollisionEvent = new CollisionEvent(
                                        pixelPenetrationDifferenceX,
                                        obstacleCollisionState,
                                        obstacleBoundingBoxInstance
                                        );

                                    if (!CollisionEventHistory.Contains(slopeEnterCollisionEvent))
                                    {
                                        controllerBoundingBoxInstance.OnBoundingBoxEnter(controllerCollisionState, pixelPenetrationDifferenceX, obstacleBoundingBoxInstance);
                                        obstacleBoundingBoxInstance.OnBoundingBoxEnter(obstacleCollisionState, pixelPenetrationDifferenceX, controllerBoundingBoxInstance);

                                        CollisionEventHistory.Add(slopeEnterCollisionEvent);
                                    }

                                    controllerPixelMinimumX -= pixelPenetrationDifferenceX;
                                    controllerBoundingBoxInstance.RoundingRemainderX = 0.0f;

                                    if (
                                        controllerBoundingBoxInstance.VelocityX > 0 &&
                                        controllerBoundingBoxInstance.VelocityY == 0.0f
                                        )
                                    {
                                        ++controllerPixelMinimumY;
                                        ++controllerPixelMinimumX;
                                    }
                                }
                                else
                                {
                                    CollisionEvent slopeExitCollisionEvent = new CollisionEvent(
                                        0,
                                        ActiveBoundingBox.CollisionStateFlags.NONE,
                                        obstacleBoundingBoxInstance
                                        );

                                    if (CollisionEventHistory.Contains(slopeExitCollisionEvent))
                                    {
                                        controllerBoundingBoxInstance.OnBoundingBoxExit(obstacleBoundingBoxInstance);
                                        obstacleBoundingBoxInstance.OnBoundingBoxExit(controllerBoundingBoxInstance);

                                        CollisionEventHistory.Remove(slopeExitCollisionEvent);
                                    }
                                }
                            }
                        }
                        else
                        {
                            int bitmapColumnIndex = controllerPixelMaximumX - obstaclePixelMinimumX - 1;

                            int pixelPenetrationY          = obstaclePixelMaximumY - controllerPixelMinimumY;
                            int pixelPenetrationAllowanceY = 0;

                            for (int k = slopeTextureBitmap.Count - 1; k > 0; --k)
                            {
                                List <bool> bitmapRow = slopeTextureBitmap[k];

                                if (
                                    bitmapColumnIndex < 0 ||
                                    bitmapColumnIndex >= bitmapRow.Count
                                    )
                                {
                                    break;
                                }

                                if (bitmapRow[bitmapColumnIndex])
                                {
                                    break;
                                }

                                ++pixelPenetrationAllowanceY;
                            }

                            int pixelPenetrationDifferenceY = pixelPenetrationY - pixelPenetrationAllowanceY;

                            if (
                                controllerBoundingBoxInstance.VelocityX < 0.0f &&
                                controllerBoundingBoxInstance.VelocityY == 0.0f
                                )
                            {
                                if (pixelPenetrationDifferenceY < 0)
                                {
                                    controllerPixelMinimumY += pixelPenetrationDifferenceY;
                                }
                            }
                            else
                            {
                                if (pixelPenetrationDifferenceY > 0)
                                {
                                    CollisionEvent slopeEnterCollisionEvent = new CollisionEvent(
                                        pixelPenetrationDifferenceY,
                                        obstacleCollisionState,
                                        obstacleBoundingBoxInstance
                                        );

                                    if (!CollisionEventHistory.Contains(slopeEnterCollisionEvent))
                                    {
                                        controllerBoundingBoxInstance.OnBoundingBoxEnter(controllerCollisionState, pixelPenetrationDifferenceY, obstacleBoundingBoxInstance);
                                        obstacleBoundingBoxInstance.OnBoundingBoxEnter(obstacleCollisionState, pixelPenetrationDifferenceY, controllerBoundingBoxInstance);

                                        CollisionEventHistory.Add(slopeEnterCollisionEvent);
                                    }

                                    controllerPixelMinimumY += pixelPenetrationDifferenceY;
                                }
                                else
                                {
                                    CollisionEvent slopeExitCollisionEvent = new CollisionEvent(
                                        0,
                                        ActiveBoundingBox.CollisionStateFlags.NONE,
                                        obstacleBoundingBoxInstance
                                        );

                                    if (CollisionEventHistory.Contains(slopeExitCollisionEvent))
                                    {
                                        controllerBoundingBoxInstance.OnBoundingBoxExit(obstacleBoundingBoxInstance);
                                        obstacleBoundingBoxInstance.OnBoundingBoxExit(controllerBoundingBoxInstance);

                                        CollisionEventHistory.Remove(slopeExitCollisionEvent);
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        controllerPixelMinimumY += minimumPixelPenetration;
                        controllerBoundingBoxInstance.RoundingRemainderY = 0.0f;
                    }
                }

                CollisionEvent enterCollisionEvent = new CollisionEvent(minimumPixelPenetration, controllerCollisionState, obstacleBoundingBoxInstance);

                if (!CollisionEventHistory.Contains(enterCollisionEvent) &&
                    ((obstacleBoundingBoxInstance.BehaviourFlag & BoundingBox.BehaviourFlags.SLOPE) != BoundingBox.BehaviourFlags.SLOPE)
                    )
                {
                    controllerBoundingBoxInstance.OnBoundingBoxEnter(controllerCollisionState, minimumPixelPenetration, obstacleBoundingBoxInstance);
                    obstacleBoundingBoxInstance.OnBoundingBoxEnter(obstacleCollisionState, minimumPixelPenetration, controllerBoundingBoxInstance);

                    CollisionEventHistory.Add(enterCollisionEvent);
                }
            }

            controllerBoundingBoxInstance.SetPixelPosition(controllerPixelMinimumX, controllerPixelMinimumY);
            controllerBoundingBoxInstance.DrawGeometry();
        }
    }