示例#1
0
        public List <CollisionTile> GetCollidingTiles(Rectangle rectangle, TileInfo.SideType direction)
        {
            TileUnit firstPrimary = Units.GameToTile(rectangle.Side(TileInfo.OppositeSide(direction)));
            TileUnit lastPrimary  = Units.GameToTile(rectangle.Side(direction));
            int      primaryIncr  = TileInfo.IsMax(direction) ? 1 : -1;

            bool     horizontal = TileInfo.Horizontal(direction);
            TileUnit sMin       = Units.GameToTile(horizontal ? rectangle.Top : rectangle.Left);
            TileUnit sMid       = Units.GameToTile(horizontal ? rectangle.Center.Y : rectangle.Center.X);
            TileUnit sMax       = Units.GameToTile(horizontal ? rectangle.Bottom : rectangle.Right);

            bool                 sPositive      = sMid - sMin < sMax - sMid;
            int                  secondaryIncr  = sPositive ? 1 : -1;
            TileUnit             firstSecondary = sPositive ? sMin : sMax;
            TileUnit             lastSecondary  = sPositive ? sMin : sMax;
            List <CollisionTile> collisionTiles = new List <CollisionTile>();

            for (TileUnit primary = firstPrimary; primary != lastPrimary + primaryIncr; primary = Convert.ToUInt32(Convert.ToInt32(primary) + primaryIncr))
            {
                for (TileUnit secondary = firstSecondary; secondary != lastSecondary + secondaryIncr; secondary = Convert.ToUInt32(Convert.ToInt32(secondary) + secondaryIncr))
                {
                    TileUnit row = !horizontal ? primary : secondary;
                    TileUnit col = horizontal ? primary : secondary;
                    collisionTiles.Add(new CollisionTile(row, col, tiles[Convert.ToInt32(row)][Convert.ToInt32(col)].tileType));
                }
            }
            return(collisionTiles);
        }
示例#2
0
        protected override void OnCollision(TileInfo.SideType side, bool isDeltaDirection, BitArray tileType)
        {
            switch (side)
            {
            case TileInfo.SideType.TopSide:
                if (isDeltaDirection)
                {
                    kinematicsY.velocity = 0;
                    particleTools.FrontSystem.AddNewParticle(new HeadBumpParticle(particleTools.Content, CenterX, kinematicsY.position + collisionRectangle.BoundingBox.Top));
                }
                break;

            case TileInfo.SideType.BottomSide:
                maybeGroundTile = tileType;
                if (isDeltaDirection)
                {
                    kinematicsY.velocity = 0;
                }
                break;

            case TileInfo.SideType.LeftSide:
                if (isDeltaDirection)
                {
                    kinematicsX.velocity = 0;
                }
                break;

            case TileInfo.SideType.RightSide:
                if (isDeltaDirection)
                {
                    kinematicsX.velocity = 0;
                }
                break;
            }
        }
示例#3
0
        /// <summary>
        /// Returns true if projectile is still alive
        /// </summary>
        /// <param name="gameTime"></param>
        /// <returns>True if projectile is still alive</returns>
        public bool Update(GameTime gameTime, Map map, ParticleTools particleTools)
        {
            offset += (float)gameTime.ElapsedGameTime.TotalMilliseconds * ProjectileSpeed;

            TileInfo.SideType    direction      = TileInfo.FromFacing(horizontalDirection, verticalDirection);
            Rectangle            rectangle      = CollisionRectangle;
            List <CollisionTile> collidingTiles = map.GetCollidingTiles(rectangle, direction);

            for (int i = 0; i < collidingTiles.Count; i++)
            {
                TileInfo.SideType side = TileInfo.OppositeSide(direction);
                GameUnit          perpendicularPosition = TileInfo.Vertical(side) ?
                                                          rectangle.Center.X : rectangle.Center.Y;
                GameUnit          leadingPosition  = rectangle.Side(direction);
                bool              shouldTestSlopes = true;
                TestCollisionInfo testInfo         = collidingTiles[i].TestCollision(side, perpendicularPosition,
                                                                                     leadingPosition, shouldTestSlopes);
                if (testInfo.isColliding)
                {
                    GameUnit collisionX;
                    if (TileInfo.Vertical(side))
                    {
                        collisionX = perpendicularPosition;
                    }
                    else
                    {
                        collisionX = testInfo.position;
                    }
                    GameUnit collisionY;
                    if (TileInfo.Vertical(side))
                    {
                        collisionY = testInfo.position;
                    }
                    else
                    {
                        collisionY = perpendicularPosition;
                    }
                    particleTools.FrontSystem.AddNewParticle(ProjectileWallParticle.Create(particleTools.Content,
                                                                                           collisionX - Units.HalfTile, collisionY - Units.HalfTile));
                    return(false);
                }
            }
            if (!alive)
            {
                return(false);
            }
            else if (offset >= ProjectileMaxOffsets[gunLevel - 1])
            {
                particleTools.FrontSystem.AddNewParticle(ProjectileStarParticle.Create(particleTools.Content, X, Y));
                return(false);
            }
            else
            {
                return(true);
            }
        }
示例#4
0
        private void Update(ICollisionRectangle collisionRectangle,
                            IAccelerator accelerator,
                            Kinematics kinematicsX, Kinematics kinematicsY,
                            GameTime gameTime, Map map,
                            BitArray maybeGroundTile,
                            Kinematics kinematics, AxisType axis)
        {
            Func <Map, Rectangle, TileInfo.SideType, BitArray, CollisionInfo?> testMapCollisionFunc;

            if (collisionType == CollisionType.BouncingCollision)
            {
                testMapCollisionFunc = TestMapBouncingCollision;
            }
            else
            {
                testMapCollisionFunc = TestMapStickyCollision;
            }

            accelerator.UpdateVelocity(kinematics, gameTime);
            GameUnit delta = kinematics.velocity * (float)gameTime.ElapsedGameTime.TotalMilliseconds;

            TileInfo.SideType direction = axis == AxisType.XAxis ?
                                          (delta > 0 ? TileInfo.SideType.RightSide : TileInfo.SideType.LeftSide) :
                                          (delta > 0 ? TileInfo.SideType.BottomSide : TileInfo.SideType.TopSide);
            CollisionInfo?maybeInfo = testMapCollisionFunc(map,
                                                           collisionRectangle.Collision(direction, kinematicsX.position, kinematicsY.position, delta),
                                                           direction, maybeGroundTile);

            if (maybeInfo.HasValue)
            {
                kinematics.position = maybeInfo.Value.position - collisionRectangle.BoundingBox.Side(direction);
                debugCollidingTiles.Add(maybeInfo.Value.tilePosition);
                OnCollision(direction, true, maybeInfo.Value.tileType);
            }
            else
            {
                kinematics.position += delta;
                OnDelta(direction);
            }

            maybeInfo = null;
            TileInfo.SideType oppositeDirection = TileInfo.OppositeSide(direction);
            maybeInfo = testMapCollisionFunc(map,
                                             collisionRectangle.Collision(oppositeDirection, kinematicsX.position, kinematicsY.position, 0),
                                             oppositeDirection, null);

            if (maybeInfo.HasValue)
            {
                kinematics.position = maybeInfo.Value.position - collisionRectangle.BoundingBox.Side(oppositeDirection);
                debugOppositeCollidingTiles.Add(maybeInfo.Value.tilePosition);
                OnCollision(oppositeDirection, false, maybeInfo.Value.tileType);
            }
        }
示例#5
0
 protected override void OnCollision(TileInfo.SideType side, bool isDeltaDirection, BitArray tileType)
 {
     if (side == TileInfo.SideType.TopSide)
     {
         kinematicsY.velocity = 0;
     }
     else if (side == TileInfo.SideType.BottomSide)
     {
         kinematicsY.velocity = -BounceSpeed;
     }
     else
     {
         kinematicsX.velocity *= -1;
     }
 }
 public Rectangle Collision(TileInfo.SideType side, GameUnit x, GameUnit y, GameUnit delta)
 {
     if (side == TileInfo.SideType.LeftSide)
     {
         return(LeftCollision(x, y, delta));
     }
     if (side == TileInfo.SideType.RightSide)
     {
         return(RightCollision(x, y, delta));
     }
     if (side == TileInfo.SideType.TopSide)
     {
         return(TopCollision(x, y, delta));
     }
     return(BottomCollision(x, y, delta));
 }
 public static int Side(this Rectangle rectangle, TileInfo.SideType side)
 {
     if (side == TileInfo.SideType.LeftSide)
     {
         return(rectangle.Left);
     }
     if (side == TileInfo.SideType.RightSide)
     {
         return(rectangle.Right);
     }
     if (side == TileInfo.SideType.TopSide)
     {
         return(rectangle.Top);
     }
     return(rectangle.Bottom);
 }
示例#8
0
        protected override void OnDelta(TileInfo.SideType side)
        {
            switch (side)
            {
            case TileInfo.SideType.TopSide:
            case TileInfo.SideType.BottomSide:
                maybeGroundTile = null;
                break;

            case TileInfo.SideType.LeftSide:
                break;

            case TileInfo.SideType.RightSide:
                break;
            }
        }
示例#9
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="side">The side of the tile that is being collided with</param>
        /// <param name="perpendicularPosition">The position on the tile on the opposite axis of side</param>
        /// <param name="leadingPosition">Position of the leading edge of the colliding entity</param>
        /// <param name="shouldTestSlopes">whether slopes should be considered for collision</param>
        /// <returns>
        /// isColliding is true if there was a collision
        /// Returns the position of the collision on the same axis of side
        /// </returns>
        public TestCollisionInfo TestCollision(TileInfo.SideType side, GameUnit perpendicularPosition,
                                               GameUnit leadingPosition, bool shouldTestSlopes)
        {
            TestCollisionInfo info = new TestCollisionInfo(false, leadingPosition);

            if (tileType[(int)TileInfo.TileFlag.Wall])
            {
                info.isColliding = true;
                if (side == TileInfo.SideType.TopSide)
                {
                    info.position = Units.TileToGame(row);
                }
                else if (side == TileInfo.SideType.BottomSide)
                {
                    info.position = Units.TileToGame(row + 1);
                }
                else if (side == TileInfo.SideType.LeftSide)
                {
                    info.position = Units.TileToGame(col);
                }
                else
                {
                    info.position = Units.TileToGame(col + 1);
                }
            }
            else if (shouldTestSlopes && tileType[(int)TileInfo.TileFlag.Slope] &&
                     !tileType[(int)TileInfo.SlopeFlagFromSide(side)])
            {
                GameUnit row                = Units.TileToGame(this.row);
                GameUnit col                = Units.TileToGame(this.col);
                float    slope              = GetSlope(tileType);
                GameUnit offset             = GetOffset(tileType);
                GameUnit calculatedPosition = TileInfo.Vertical(side) ?
                                              slope * (perpendicularPosition - col) + offset + row :
                                              (perpendicularPosition - row - offset) / slope + col;

                bool isColliding = TileInfo.IsMax(side) ?
                                   leadingPosition <= calculatedPosition :
                                   leadingPosition >= calculatedPosition;

                info.isColliding = isColliding;
                info.position    = calculatedPosition;
            }
            return(info);
        }
示例#10
0
        CollisionInfo?TestMapStickyCollision(Map map, Rectangle rectangle,
                                             TileInfo.SideType direction, BitArray maybeGroundTile)
        {
            List <CollisionTile> tiles = map.GetCollidingTiles(rectangle, direction);

            for (int i = 0; i < tiles.Count; i++)
            {
                TileInfo.SideType side = TileInfo.OppositeSide(direction);
                GameUnit          perpendicularPosition;
                if (TileInfo.Vertical(side))
                {
                    perpendicularPosition = rectangle.Center.X;
                }
                else
                {
                    perpendicularPosition = rectangle.Center.Y;
                }
                GameUnit          leadingPosition  = rectangle.Side(direction);
                bool              shouldTestSlopes = TileInfo.Vertical(side);
                TestCollisionInfo testInfo         = tiles[i].TestCollision(side, perpendicularPosition,
                                                                            leadingPosition, shouldTestSlopes);
                if (testInfo.isColliding)
                {
                    CollisionInfo info = new CollisionInfo(testInfo.position, tiles[i].Position, tiles[i].TileType);
                    return(info);
                }
                else if (maybeGroundTile != null && direction == TileInfo.SideType.BottomSide)
                {
                    BitArray tallSlope = TileInfo.CreateTileType();
                    tallSlope.Set((int)TileInfo.TileFlag.Slope, true);
                    tallSlope.Set((int)TileInfo.TileFlag.TallSlope, true);
                    if ((maybeGroundTile[(int)TileInfo.TileFlag.Slope] && tiles[i].TileType[(int)TileInfo.TileFlag.Slope]) ||
                        (maybeGroundTile[(int)TileInfo.TileFlag.Wall] &&
                         (tallSlope.And(tiles[i].TileType).Equals(tallSlope))))
                    {
                        CollisionInfo info = new CollisionInfo(testInfo.position, tiles[i].Position, tiles[i].TileType);
                        return(info);
                    }
                }
            }
            return(null);
        }
示例#11
0
        CollisionInfo?TestMapBouncingCollision(Map map, Rectangle rectangle,
                                               TileInfo.SideType direction, BitArray maybeGroundTile)
        {
            List <CollisionTile> tiles  = map.GetCollidingTiles(rectangle, direction);
            CollisionInfo?       result = null;

            for (int i = 0; i < tiles.Count; i++)
            {
                TileInfo.SideType side = TileInfo.OppositeSide(direction);
                GameUnit          perpendicularPosition;
                if (TileInfo.Vertical(side))
                {
                    perpendicularPosition = rectangle.Center.X;
                }
                else
                {
                    perpendicularPosition = rectangle.Center.Y;
                }
                GameUnit          leadingPosition  = rectangle.Side(direction);
                bool              shouldTestSlopes = TileInfo.Vertical(side);
                TestCollisionInfo testInfo         = tiles[i].TestCollision(side, perpendicularPosition,
                                                                            leadingPosition, shouldTestSlopes);
                if (testInfo.isColliding)
                {
                    bool shouldReplaceResult = true;
                    if (result.HasValue)
                    {
                        shouldReplaceResult = TileInfo.IsMin(side) ?
                                              testInfo.position <result.Value.position :
                                                                 testInfo.position> result.Value.position;
                    }
                    if (shouldReplaceResult)
                    {
                        CollisionInfo info = new CollisionInfo(testInfo.position, tiles[i].Position, tiles[i].TileType);
                        result = info;
                    }
                }
            }
            return(result);
        }
示例#12
0
 protected override void OnDelta(TileInfo.SideType side)
 {
 }
示例#13
0
 protected abstract void OnDelta(TileInfo.SideType side);
示例#14
0
 protected abstract void OnCollision(TileInfo.SideType side, bool isDeltaDirection, BitArray tileType);