Пример #1
0
        /// <summary>
        /// See return value. Fills hitBlockEntities with all/solid (see param solidOnly) entities hit
        /// </summary>
        /// <param name="box">Box for which to check collisions</param>
        /// <param name="property">Property to check for</param>
        /// <param name="solidOnly">Only checks for solid entities</param>
        /// <param name="pushAway">Solve collisions</param>
        /// <returns>True if an entity solid/not (see param solidOnly) is hit</returns>
        private bool CollisionWithAllEntities_RealTime(CollisionBox box, string property, bool solidOnly = true, bool pushAway = false)
        {
            box.SetParent(this);

            Rectangle boundbox = box.BoxAt(PositionSrc.Position); //calculate boundbox absolute coordinate

            hitBlockEntities_RealTime = new List <Collision>();

            boundbox = CheckEntityCollisions(hitBlockEntities_RealTime, box, boundbox, pushAway, solidOnly);

            return(CheckIfOneEntityHitContainProperty_RealTime(property));
        }
Пример #2
0
        private Rectangle CheckTargetBox(CollisionBox hitbox, Rectangle boundBox, IEntity entity, CollisionComponent coll, CollisionBox targetBox)
        {
            var rect = targetBox.BoxAt(coll.PositionSrc.Position);

            if (boundBox.IntersectsWith(rect))
            {
                coll.Touch(hitbox, targetBox);
                Touch(targetBox, hitbox);
                CollideWith(entity, hitbox, targetBox);
            }
            return(boundBox);
        }
Пример #3
0
        private void CheckEnvironment(List <MapSquare> hitSquares, CollisionBox hitbox, bool pushAway = true)
        {
            Point     offset  = new Point(0, 0);
            Rectangle hitRect = hitbox.BoxAt(PositionSrc.Position);    // Absolute positions of collision box

            // this bounds checking prevents needlessly checking collisions way too far away
            // it's a very effective optimization (brings busy time from ~60% down to 45%!)
            int size = Parent.Screen.TileSize;

            for (int y = hitRect.Top - size; y < hitRect.Bottom; y += size)
            {
                for (int x = hitRect.Left - size; x < hitRect.Right; x += size)
                {
                    var tile = Parent.Screen.SquareAt(x, y);
                    if (tile == null)
                    {
                        continue;
                    }

                    CheckEnvironmentTile(hitSquares, hitbox, hitRect, tile, ref offset, pushAway);
                }

                var rightEdge = Parent.Screen.SquareAt(hitRect.Right, y);
                if (rightEdge != null)
                {
                    CheckEnvironmentTile(hitSquares, hitbox, hitRect, rightEdge, ref offset, pushAway);
                }
            }

            for (int x = hitRect.Left - size; x < hitRect.Right; x += size)
            {
                var tile = Parent.Screen.SquareAt(x, hitRect.Bottom);
                if (tile == null)
                {
                    continue;
                }

                CheckEnvironmentTile(hitSquares, hitbox, hitRect, tile, ref offset, pushAway);
            }

            var lastCorner = Parent.Screen.SquareAt(hitRect.Right, hitRect.Bottom);

            if (lastCorner != null)
            {
                CheckEnvironmentTile(hitSquares, hitbox, hitRect, lastCorner, ref offset, pushAway);
            }
        }
Пример #4
0
        private void ReactForHitbox(List <MapSquare> hitSquares, HashSet <TileProperties> hitTypes, CollisionBox hitbox)
        {
            hitbox.SetParent(this);

            var boundBox = hitbox.BoxAt(PositionSrc.Position);

            if (hitbox.Environment)
            {
                foreach (MapSquare tile in hitSquares)
                {
                    var  tileBox  = tile.BlockBox;
                    bool downonly = (!Parent.Container.IsGravityFlipped && tile.Tile.Properties.Climbable);
                    bool uponly   = (Parent.Container.IsGravityFlipped && tile.Tile.Properties.Climbable);

                    bool hit = (tile.BlockBox != Rectangle.Empty) ? BlockByIntersection(boundBox, tileBox, uponly, downonly) : boundBox.IntersectsWith(tile.BoundBox);

                    if (hitbox.PushAway && (hit || boundBox.IntersectsWith(tile.BoundBox)))    // the environment touched me!
                    {
                        hitTypes.Add(tile.Tile.Properties);
                    }
                }
            }

            // but for entities, we can go ahead and be active aggressors -
            // inflict our effects on the target entity, not the other way around
            foreach (var entity in Parent.Entities.GetAll())
            {
                if (entity == Parent)
                {
                    continue;
                }
                CollisionComponent coll = entity.GetComponent <CollisionComponent>();
                if (coll == null)
                {
                    continue;
                }

                foreach (CollisionBox targetBox in coll.TargetBoxes(hitbox))
                {
                    boundBox = CheckTargetBox(hitbox, boundBox, entity, coll, targetBox);
                }
            }
        }
Пример #5
0
        private void ReactForHitbox(List<MapSquare> hitSquares, HashSet<TileProperties> hitTypes, CollisionBox hitbox)
        {
            hitbox.SetParent(this);

            RectangleF boundBox = hitbox.BoxAt(PositionSrc.Position);

            if (hitbox.Environment)
            {
                foreach (MapSquare tile in hitSquares)
                {
                    RectangleF tileBox = tile.BlockBox;
                    bool downonly = (!Parent.Container.IsGravityFlipped && tile.Tile.Properties.Climbable);
                    bool uponly = (Parent.Container.IsGravityFlipped && tile.Tile.Properties.Climbable);

                    bool hit = (tile.BlockBox != RectangleF.Empty) ? BlockByIntersection(boundBox, tileBox, uponly, downonly) : boundBox.IntersectsWith(tile.BoundBox);

                    if (hitbox.PushAway && (hit || boundBox.IntersectsWith(tile.BoundBox)))    // the environment touched me!
                    {
                        hitTypes.Add(tile.Tile.Properties);
                    }
                }
            }

            // but for entities, we can go ahead and be active aggressors -
            // inflict our effects on the target entity, not the other way around
            foreach (var entity in Parent.Entities.GetAll())
            {
                if (entity == Parent) continue;
                CollisionComponent coll = entity.GetComponent<CollisionComponent>();
                if (coll == null) continue;

                foreach (CollisionBox targetBox in coll.TargetBoxes(hitbox))
                {
                    boundBox = CheckTargetBox(hitbox, boundBox, entity, coll, targetBox);
                }
            }
        }
Пример #6
0
 private RectangleF CheckTargetBox(CollisionBox hitbox, RectangleF boundBox, IEntity entity, CollisionComponent coll, CollisionBox targetBox)
 {
     RectangleF rect = targetBox.BoxAt(coll.PositionSrc.Position);
     if (boundBox.IntersectsWith(rect))
     {
         coll.Touch(hitbox, targetBox);
         Touch(targetBox, hitbox);
         CollideWith(entity, hitbox, targetBox);
     }
     return boundBox;
 }
Пример #7
0
        private void CheckEnvironment(List<MapSquare> hitSquares, CollisionBox hitbox)
        {
            PointF offset = new PointF(0, 0);
            RectangleF hitRect = hitbox.BoxAt(PositionSrc.Position);

            // this bounds checking prevents needlessly checking collisions way too far away
            // it's a very effective optimization (brings busy time from ~60% down to 45%!)
            int size = Parent.Screen.TileSize;

            for (float y = hitRect.Top - size; y < hitRect.Bottom; y += size)
            {
                for (float x = hitRect.Left - size; x < hitRect.Right; x += size)
                {
                    var tile = Parent.Screen.SquareAt(x, y);
                    if (tile == null) continue;

                    CheckEnvironmentTile(hitSquares, hitbox, hitRect, tile, ref offset);
                }

                var rightEdge = Parent.Screen.SquareAt(hitRect.Right, y);
                if (rightEdge != null)
                {
                    CheckEnvironmentTile(hitSquares, hitbox, hitRect, rightEdge, ref offset);
                }
            }

            for (float x = hitRect.Left - size; x < hitRect.Right; x += size)
            {
                var tile = Parent.Screen.SquareAt(x, hitRect.Bottom);
                if (tile == null) continue;

                CheckEnvironmentTile(hitSquares, hitbox, hitRect, tile, ref offset);
            }

            var lastCorner = Parent.Screen.SquareAt(hitRect.Right, hitRect.Bottom);
            if (lastCorner != null)
            {
                CheckEnvironmentTile(hitSquares, hitbox, hitRect, lastCorner, ref offset);
            }
        }
        /// <summary>
        /// See return value. Fills hitBlockEntities with all/solid (see param solidOnly) entities hit
        /// </summary>
        /// <param name="box">Box for which to check collisions</param>
        /// <param name="property">Property to check for</param>
        /// <param name="solidOnly">Only checks for solid entities</param>
        /// <param name="pushAway">Solve collisions</param>
        /// <returns>True if an entity solid/not (see param solidOnly) is hit</returns>
        private bool CollisionWithAllEntities_RealTime(CollisionBox box, string property, bool solidOnly = true, bool pushAway = false)
        {
            box.SetParent(this);

            RectangleF boundbox = box.BoxAt(PositionSrc.Position); //calculate boundbox absolute coordinate
            hitBlockEntities_RealTime = new List<Collision>();

            boundbox = CheckEntityCollisions(hitBlockEntities_RealTime, box, boundbox, pushAway, solidOnly);

            return CheckIfOneEntityHitContainProperty_RealTime(property);
        }