Exemplo n.º 1
0
 // Draws the specified rectangle.
 public void DrawRectangle(Rectangle2F rect, float thickness, Color color, float depth = 0.0f)
 {
     DrawLine(new Line2F(rect.Point, rect.Point + new Vector2F(rect.Width - 1, 0.0f)), thickness, color, depth);
     DrawLine(new Line2F(rect.Point, rect.Point + new Vector2F(0.0f, rect.Height - 1)), thickness, color, depth);
     DrawLine(new Line2F(rect.Point + rect.Size - Vector2F.One, rect.Point + new Vector2F(rect.Width - 1, 0.0f)), thickness, color, depth);
     DrawLine(new Line2F(rect.Point + rect.Size - Vector2F.One, rect.Point + new Vector2F(0.0f, rect.Height - 1)), thickness, color, depth);
 }
Exemplo n.º 2
0
 // Draws the specified filled rectangle.
 public void FillRectangle(Rectangle2F rect, Color color, double depth = 0.0)
 {
     rect.X = GMath.Round(rect.X);
     rect.Y = GMath.Round(rect.Y);
     DrawImage(white1x1, rect, Vector2F.Zero, 0.0, color, SpriteEffects.None, depth);
     //DrawImage(white1x1, rect.Center + 0.5, new Vector2D(0.5, 0.5), rect.Size, 0, color, SpriteEffects.None, depth);
 }
Exemplo n.º 3
0
        public bool CanDodgeCollision(Rectangle2F block, int direction)
        {
            if (Math.Abs(velocity.X) > 0.001f && Math.Abs(velocity.Y) > 0.001f)
            {
                return(false);                // Only dodge when moving horizontally or vertically.
            }
            float       dodgeDist = autoDodgeDistance;
            Rectangle2F objBox    = PositionedCollisionBox;
            Vector2F    pos       = entity.Position;
            Vector2F    dirVect   = Directions.ToVector(direction);

            for (int side = 0; side < 2; side++)
            {
                int   moveDir  = (direction + (side == 0 ? 1 : 3)) % 4;
                float distance = Math.Abs(objBox.GetEdge((moveDir + 2) % 4) - block.GetEdge(moveDir));

                if (distance <= dodgeDist)
                {
                    Vector2F checkPos = pos + dirVect + (Directions.ToVector(moveDir) * distance);
                    Vector2F gotoPos  = GMath.Round(pos) + Directions.ToVector(moveDir);

                    if (!IsPlaceMeetingSolid(checkPos, collisionBox) &&
                        !IsPlaceMeetingSolid(gotoPos, collisionBox))
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
Exemplo n.º 4
0
        public virtual void Update()
        {
            UpdateMovement();
            if (!isMoving)
            {
                CheckSurfaceTile();
            }

            // Check if hurting the player.
            if (HasFlag(TileFlags.HurtPlayer) && roomControl.Player.IsOnGround)
            {
                Rectangle2F playerBox = roomControl.Player.Physics.PositionedCollisionBox;
                Rectangle2F hurtBox   = tileData.TileData.HurtArea;
                hurtBox.Point += Position;
                if (hurtBox.Intersects(playerBox))
                {
                    roomControl.Player.Hurt(new DamageInfo(tileData.TileData.HurtDamage)
                    {
                        ApplyKnockBack     = true,
                        KnockbackDuration  = 14,
                        InvincibleDuration = 35,
                        FlickerDuration    = 35,
                        HasSource          = true,
                        SourcePosition     = Center
                    });
                }
            }
        }
Exemplo n.º 5
0
        //-----------------------------------------------------------------------------
        // Collisions
        //-----------------------------------------------------------------------------

        // Collide with the inside edges of a rectangle.
        // NOTE: At the moment, this is only used when player is doomed to fall in a hole.
        public void PerformInsideEdgeCollisions(Rectangle2F collisionBox, Rectangle2F rect)
        {
            Rectangle2F myBox = Rectangle2F.Translate(collisionBox, entity.Position);

            if (myBox.Left < rect.Left)
            {
                isColliding = true;
                entity.X    = rect.Left - collisionBox.Left;
                velocity.X  = 0;
            }
            else if (myBox.Right > rect.Right)
            {
                isColliding = true;
                entity.X    = rect.Right - collisionBox.Right;
                velocity.X  = 0;
            }
            if (myBox.Top < rect.Top)
            {
                isColliding = true;
                entity.Y    = rect.Top - collisionBox.Top;
                velocity.Y  = 0;
            }
            else if (myBox.Bottom > rect.Bottom)
            {
                isColliding = true;
                entity.Y    = rect.Bottom - collisionBox.Bottom;
                velocity.Y  = 0;
            }
        }
Exemplo n.º 6
0
        //-----------------------------------------------------------------------------
        // Debug drawing
        //-----------------------------------------------------------------------------

        // Draw a collision model as a solid color.
        public void DrawCollisionModel(CollisionModel model, Vector2F position, Color color)
        {
            for (int i = 0; i < model.Boxes.Count; i++)
            {
                FillRectangle(Rectangle2F.Translate(model.Boxes[i], position), color);
            }
        }
Exemplo n.º 7
0
        //-----------------------------------------------------------------------------
        // Static Collision Test Methods
        //-----------------------------------------------------------------------------

        // Perform a collision test between two entities.
        public static CollisionInfo PerformCollisionTest(Entity entity, Entity other, CollisionTestSettings settings)
        {
            CollisionInfo collisionInfo = new CollisionInfo();

            // Check that the other entity meets the collision requirements.
            if ((entity != other) &&
                (settings.RequiredType == null || settings.RequiredType.IsAssignableFrom(other.GetType())) &&
                (settings.RequiredFlags == 0 || other.Physics.Flags.HasFlag(settings.RequiredFlags)) &&
                (settings.MaxZDistance < 0.0f || Math.Abs(entity.ZPosition - other.ZPosition) <= settings.MaxZDistance))
            {
                // Setup the collision boxes.
                Rectangle2F cbox1 = settings.GetCollisionBox1(entity);
                cbox1.Point += entity.Position;
                Rectangle2F cbox2 = settings.GetCollisionBox2(other);
                cbox2.Point += other.Position;

                // Perform the collision test.
                if (cbox1.Intersects(cbox2))
                {
                    collisionInfo.SetEntityCollision(other, 0);
                }
            }

            return(collisionInfo);
        }
Exemplo n.º 8
0
        //-----------------------------------------------------------------------------
        // Internal methods
        //-----------------------------------------------------------------------------

        private void Explode()
        {
            BombExplosion bombExplosion = new BombExplosion();

            RoomControl.SpawnEntity(bombExplosion, Center, zPosition);
            AudioSystem.PlaySound(GameData.SOUND_BOMB_EXPLODE);

            // Explode nearby top tiles.
            if (zPosition < 4)
            {
                Rectangle2F tileExplodeArea = Rectangle2F.Zero.Inflated(12, 12);
                tileExplodeArea.Point += Center;

                Rectangle2I area = RoomControl.GetTileAreaFromRect(tileExplodeArea);

                for (int x = area.Left; x < area.Right; x++)
                {
                    for (int y = area.Top; y < area.Bottom; y++)
                    {
                        Tile        tile     = RoomControl.GetTopTile(x, y);
                        Rectangle2F tileRect = new Rectangle2F(x * 16, y * 16, 16, 16);
                        if (tile != null && tileRect.Intersects(tileExplodeArea))
                        {
                            tile.OnBombExplode();
                        }
                    }
                }
            }

            DestroyAndTransform(bombExplosion);
        }
Exemplo n.º 9
0
        public override void Update()
        {
            Point2I loc = (Point2I)(Physics.PositionedCollisionBox.Center / GameSettings.TILE_SIZE);

            // Check if tile location has changed.
            if (loc != tileLocation)
            {
                Rectangle2F rect = new Rectangle2F(loc * GameSettings.TILE_SIZE,
                                                   new Vector2F(GameSettings.TILE_SIZE, GameSettings.TILE_SIZE));

                // Only change tile locations if the collision box is fully contained inside the tile.
                if (rect.Contains(physics.PositionedCollisionBox))
                {
                    tileLocation = loc;

                    // Check for seed bouncers in the new location.
                    foreach (Tile tile in RoomControl.TileManager.GetTilesAtLocation(tileLocation))
                    {
                        TileSeedBouncer seedBouncer = tile as TileSeedBouncer;
                        if (seedBouncer != null)
                        {
                            OnCollideTile(seedBouncer, false);
                            break;
                        }
                    }
                }
            }

            base.Update();
        }
Exemplo n.º 10
0
 public bool IsSoftMeetingEntity(Entity other, Rectangle2F collisionBox, int maxZDistance = 10)
 {
     collisionBox.Point += entity.Position;
     if (CanCollideWithEntity(other) && GMath.Abs(entity.ZPosition - other.ZPosition) < maxZDistance)
     {
         return(collisionBox.Intersects(other.Physics.PositionedSoftCollisionBox));
     }
     return(false);
 }
Exemplo n.º 11
0
 public CollisionTestSettings(Type entityType, Rectangle2F myBox, CollisionBoxType otherBoxType, float maxZDistance = 10)
 {
     this.requiredType      = entityType;
     this.collisionBox1     = myBox;
     this.collisionBoxType1 = CollisionBoxType.Custom;
     this.collisionBoxType2 = otherBoxType;
     this.requiredFlags     = PhysicsFlags.None;
     this.maxZDistance      = maxZDistance;
 }
Exemplo n.º 12
0
 // Translates the rectangle based on the translation and precision settings.
 private Rectangle NewRect(Rectangle2F destinationRect)
 {
     if (useTranslation)
     {
         return(UseIntegerPrecision ? (Rectangle) new Rectangle2F(GMath.Round(destinationRect.Point + translation), GMath.Round(destinationRect.Size)) : (Rectangle)(destinationRect + translation));
     }
     else
     {
         return((Rectangle)destinationRect);
     }
 }
Exemplo n.º 13
0
        // Return an enumerable list of tiles touching the given rectangular bounds.
        public IEnumerable <Tile> GetTilesTouching(Rectangle2F bounds, TileLayerOrder layerOrder = TileLayerOrder.LowestToHighest)
        {
            Rectangle2I area = GetTileAreaFromRect(bounds);

            foreach (Tile tile in GetTilesInArea(area, layerOrder))
            {
                if (tile.Bounds.Intersects(bounds))
                {
                    yield return(tile);
                }
            }
        }
Exemplo n.º 14
0
        // inflateAmount inflates the output rectangle.
        public Rectangle2I GetTileAreaFromRect(Rectangle2F rect, int inflateAmount = 0)
        {
            Rectangle2I area;

            area.Point = (Point2I)GMath.Floor(rect.TopLeft / tileGridCellSize);
            area.Size  = (Point2I)GMath.Ceiling(rect.BottomRight / tileGridCellSize) - area.Point;
            if (inflateAmount != 0)
            {
                area.Inflate(inflateAmount, inflateAmount);
            }
            return(Rectangle2I.Intersect(area, new Rectangle2I(Point2I.Zero, gridDimensions)));
        }
Exemplo n.º 15
0
        // Translates the rectangle based on the translation and precision settings.
        private Rectangle NewRect(Vector2F position, Vector2F size)
        {
            Rectangle2F destinationRect = new Rectangle2F(position, size);

            if (useTranslation)
            {
                return(UseIntegerPrecision ? (Rectangle) new Rectangle2F(GMath.Round(destinationRect.Point + translation), GMath.Round(destinationRect.Size + translation)) : (Rectangle)(destinationRect + translation));
            }
            else
            {
                return((Rectangle)destinationRect);
            }
        }
Exemplo n.º 16
0
        // Return an enumerable list of solid tiles colliding with the given collision box.
        public IEnumerable <Tile> GetSolidTilesColliding(Rectangle2F collisionBox, TileLayerOrder layerOrder = TileLayerOrder.LowestToHighest)
        {
            Rectangle2I area = GetTileAreaFromRect(collisionBox);

            foreach (Tile tile in GetTilesInArea(area, layerOrder))
            {
                if (tile.IsSolid && tile.CollisionModel != null &&
                    CollisionModel.Intersecting(tile.CollisionModel, tile.Position, collisionBox))
                {
                    yield return(tile);
                }
            }
        }
Exemplo n.º 17
0
 public void DrawSprite(Sprite sprite, int variantID, Rectangle2F destination, Color color, float depth = 0.0f)
 {
     if (sprite.Image == null)
     {
         return;
     }
     for (Sprite part = sprite; part != null; part = part.NextPart)
     {
         Image image = sprite.Image.GetVariant(variantID);
         destination.Point = NewPos(destination.Point) + (Vector2F)part.DrawOffset;
         spriteBatch.Draw(image, (Rectangle)destination, (Rectangle)part.SourceRect,
                          (XnaColor)color, 0.0f, Vector2.Zero, SpriteEffects.None, depth);
     }
 }
Exemplo n.º 18
0
 public bool CanDodgeCollision(Tile tile, int direction)
 {
     if (!CanCollideWithTile(tile))
     {
         return(false);
     }
     for (int i = 0; i < tile.CollisionModel.Boxes.Count; i++)
     {
         if (CanDodgeCollision(Rectangle2F.Translate(tile.CollisionModel.Boxes[i], tile.Position), direction))
         {
             return(true);
         }
     }
     return(false);
 }
Exemplo n.º 19
0
        public override void Update()
        {
            base.Update();

            Player player = RoomControl.Player;

            int d = ACCEPT_TURN_MIN_DISTANCE_TO_CENTER;

            Rectangle2F[] sideRects = new Rectangle2F[] {
                new Rectangle2F(32, 16, d, 16),
                new Rectangle2F(16, 16 - d, 16, d),
                new Rectangle2F(16 - d, 16, d, 16),
                new Rectangle2F(16, 32, 16, d),
            };

            if (player.IsOnGround)
            {
                int direction = -1;

                for (int dir = 0; dir < Directions.Count; dir++)
                {
                    Rectangle2F sideRect = Rectangle2F.Translate(sideRects[dir], Position);

                    if (player.Physics.PositionedCollisionBox.Intersects(sideRect))
                    {
                        direction = dir;
                        break;
                    }
                }

                if (turnDirection != direction)
                {
                    timer         = 0;
                    turnDirection = direction;
                }

                if (turnDirection >= 0)
                {
                    timer++;
                    if (timer >= ACCEPT_TURN_DELAY)
                    {
                        AudioSystem.PlaySound(GameData.SOUND_CHEST_OPEN);
                        GameControl.PushRoomState(new RoomStateTurnstile(this, direction));
                    }
                }
            }
        }
Exemplo n.º 20
0
        private static void DrawTile(Graphics2D g, Tile tile)
        {
            if (TileDebugInfoMode == TileDrawInfo.CollisionBoxes)
            {
                if (tile.IsSolid && tile.CollisionModel != null)
                {
                    foreach (Rectangle2F box in tile.CollisionModel.Boxes)
                    {
                        Rectangle2F r = Rectangle2F.Translate(box, tile.Position);
                        g.FillRectangle(r, Color.Red);
                        //g.DrawRectangle(r, 1, Color.Maroon);
                    }
                }
            }
            else if (TileDebugInfoMode == TileDrawInfo.GridArea)
            {
                Rectangle2F tileBounds = (Rectangle2F)tile.TileGridArea;
                tileBounds.Point *= GameSettings.TILE_SIZE;
                tileBounds.Size  *= GameSettings.TILE_SIZE;
                Color c = Color.Yellow;
                if (tile.Layer == 1)
                {
                    c = Color.Blue;
                }
                else if (tile.Layer == 2)
                {
                    c = Color.Red;
                }
                g.FillRectangle(tileBounds, c);

                tileBounds = new Rectangle2F(tile.Position, tile.Size * GameSettings.TILE_SIZE);
                c          = Color.Olive;
                if (tile.Layer == 1)
                {
                    c = Color.Cyan;
                }
                else if (tile.Layer == 2)
                {
                    c = Color.Maroon;
                }

                g.DrawLine(new Line2F(tileBounds.TopLeft, tileBounds.BottomRight - new Point2I(1, 1)), 1, c);
                g.DrawLine(new Line2F(tileBounds.TopRight - new Point2I(1, 0), tileBounds.BottomLeft - new Point2I(0, 1)), 1, c);
                g.DrawRectangle(tileBounds, 1, Color.Black);
            }
        }
Exemplo n.º 21
0
        //-----------------------------------------------------------------------------
        // Tile Mutators
        //-----------------------------------------------------------------------------

        // Place a tile in highest empty layer at the given location.
        // Returns true if there was an empty space to place the tile.
        public bool PlaceTileOnHighestLayer(Tile tile, Point2I location)
        {
            Rectangle2F tileBounds = new Rectangle2F(
                location * GameSettings.TILE_SIZE,
                tile.Size * GameSettings.TILE_SIZE);
            Rectangle2I area = GetTileAreaFromRect(tileBounds);

            // Determine which layers are free.
            bool[] freeLayers = new bool[layerCount];
            for (int i = 0; i < layerCount; i++)
            {
                freeLayers[i] = true;
                for (int x = area.Left; x < area.Right && freeLayers[i]; x++)
                {
                    for (int y = area.Top; y < area.Bottom && freeLayers[i]; y++)
                    {
                        Tile t = tiles[x, y, i];
                        if (t != null)
                        {
                            freeLayers[i] = false;
                        }
                    }
                }
            }

            // Choose the highest free layer.
            int layer = -1;

            for (int i = layerCount - 1; i >= 0; i--)
            {
                if (freeLayers[i])
                {
                    layer = i;
                    break;
                }
            }
            if (layer < 0)
            {
                return(false);
            }

            // Place the tile in that layer.
            PlaceTile(tile, location, layer);
            return(true);
        }
Exemplo n.º 22
0
        public override void Update()
        {
            base.Update();

            bool isDown = isCovered;

            // Update the uncovered state.
            if (!isCovered)
            {
                // There is a small delay between being uncovered and becoming unpressed.
                uncoverTimer--;
                if (uncoverTimer > 0)
                {
                    isDown = true;
                }
                else
                {
                    // Raise certain tiles (pots) that are partially covering this button.
                    foreach (Tile tile in tilesCovering)
                    {
                        if (tile.Bounds.Contains(Center) && tile.Properties.GetBoolean("raised_on_buttons", false))
                        {
                            tile.Graphics.RaisedDrawOffset = new Point2I(0, -GameSettings.TILE_BUTTON_TILE_RAISE_AMOUNT);
                        }
                    }
                }
            }

            // Check if the player is on top of this button.
            if (!isDown)
            {
                Rectangle2F pressRect = Rectangle2F.Translate(
                    GameSettings.TILE_BUTTON_PLAYER_PRESS_AREA, Position);
                if (pressRect.Contains(RoomControl.Player.Position))
                {
                    isDown = true;
                }
            }

            // Check if the pressed state needs to be changed.
            if (isPressed != isDown && (isDown || isReleasable))
            {
                SetPressed(isDown);
            }
        }
Exemplo n.º 23
0
        // Return a list of tiles colliding with this entity (solidity is ignored).
        public IEnumerable <Tile> GetTilesMeeting(Vector2F position, CollisionBoxType collisionBoxType)
        {
            // Find the rectangular area of nearby tiles to collide with.
            Rectangle2F myBox = GetCollisionBox(collisionBoxType);

            myBox.Point += position;
            myBox.Inflate(2, 2);
            Rectangle2I area = entity.RoomControl.GetTileAreaFromRect(myBox, 1);

            // Iterate the tiles in the area.
            foreach (Tile t in entity.RoomControl.GetTilesInArea(area))
            {
                if (t.CollisionModel != null &&
                    CollisionModel.Intersecting(t.CollisionModel, t.Position, collisionBox, position))
                {
                    yield return(t);
                }
            }
        }
Exemplo n.º 24
0
        // Return the highest surface tile at the given position.
        public Tile GetSurfaceTileAtPosition(Vector2F position, bool includePlatforms = false)
        {
            // Because tiles may have moved this frame, we need to check a 3x3 area.
            Point2I     location = GetTileLocation(position);
            Rectangle2I area     = new Rectangle2I(location, Point2I.One);

            area.Inflate(1, 1);

            foreach (Tile tile in GetTilesInArea(area, TileLayerOrder.HighestToLowest))
            {
                Rectangle2F tileBounds = tile.Bounds;
                tileBounds.Point -= tile.Velocity;
                if (tileBounds.Contains(position) && (tile.IsSurface || (includePlatforms && tile.IsPlatform)))
                {
                    return(tile);
                }
            }

            return(null);
        }
Exemplo n.º 25
0
        private Point2I ledgeTileLocation;                                      // The tile location of the ledge we are currently passing over, or (-1, -1) if not passing over ledge.


        //-----------------------------------------------------------------------------
        // Constructors
        //-----------------------------------------------------------------------------

        // By default, physics are disabled.
        public PhysicsComponent(Entity entity)
        {
            this.isEnabled                = false;
            this.flags                    = PhysicsFlags.None;
            this.entity                   = entity;
            this.velocity                 = Vector2F.Zero;
            this.zVelocity                = 0.0f;
            this.previousVelocity         = Vector2F.Zero;
            this.previousZVelocity        = 0.0f;
            this.gravity                  = GameSettings.DEFAULT_GRAVITY;
            this.maxFallSpeed             = GameSettings.DEFAULT_MAX_FALL_SPEED;
            this.collisionBox             = new Rectangle2F(-1, -1, 2, 2);
            this.softCollisionBox         = new Rectangle2F(-1, -1, 2, 2);
            this.topTile                  = null;
            this.isColliding              = false;
            this.autoDodgeDistance        = 6;
            this.autoDodgeSpeed           = 1.0f;
            this.hasLanded                = false;
            this.reboundVelocity          = Vector2F.Zero;
            this.ledgeAltitude            = 0;
            this.ledgeTileLocation        = new Point2I(-1, -1);
            this.roomEdgeCollisionBoxType = CollisionBoxType.Hard;

            this.crushMaxGapSize = 0;
            this.edgeClipAmount  = 1;

            this.collisionInfo         = new CollisionInfo[Directions.Count];
            this.previousCollisionInfo = new CollisionInfo[Directions.Count];
            for (int i = 0; i < Directions.Count; i++)
            {
                collisionInfo[i].Clear();
                previousCollisionInfo[i].Clear();
            }

            this.MovementCollisions = new bool[4];
            this.ClipCollisionInfo  = new CollisionInfoNew[4];
            for (int i = 0; i < 4; i++)
            {
                ClipCollisionInfo[i] = new CollisionInfoNew();
            }
        }
Exemplo n.º 26
0
        // Return the closest solid tile positioned directly in front of the entity (if there is one).
        public Tile GetFacingSolidTile(int direction, float distance = 1.0f)           // TODO: return closest tile.
        {
            Rectangle2F entityBox = PositionedCollisionBox;

            entityBox.ExtendEdge(direction, distance);

            Tile  closestTile     = null;
            int   alignAxis       = 1 - Directions.ToAxis(direction);
            float closestDistance = -1.0f;

            foreach (Tile tile in entity.RoomControl.TileManager.GetTilesTouching(entityBox))
            {
                if (CanCollideWithTile(tile))
                {
                    foreach (Rectangle2F box in tile.CollisionModel.Boxes)
                    {
                        Rectangle2F solidBox = box;
                        solidBox.Point += tile.Position;

                        if (entityBox.Intersects(solidBox) &&
                            !IsSafeClippingInDirection(solidBox, (direction + 1) % 4) &&
                            !IsSafeClippingInDirection(solidBox, (direction + 2) % 4) &&
                            !IsSafeClippingInDirection(solidBox, (direction + 3) % 4) &&
                            !CanDodgeCollision(solidBox, direction))
                        {
                            float distToEdge = Math.Max(
                                entityBox.TopLeft[alignAxis] - solidBox.BottomRight[alignAxis],
                                solidBox.TopLeft[alignAxis] - entityBox.BottomRight[alignAxis]);
                            if (closestTile == null || distToEdge < closestDistance)
                            {
                                closestTile     = tile;
                                closestDistance = distToEdge;
                                break;
                            }
                        }
                    }
                }
            }
            return(closestTile);
        }
Exemplo n.º 27
0
        public override void Update()
        {
            // Return to normal if not in a hole.
            if (!monster.Physics.IsInHole)
            {
                monster.BeginNormalState();
                return;
            }

            // Slip toward the hole's center.
            float       slipSpeed    = 0.2f;
            Point2I     tileLocation = monster.RoomControl.GetTileLocation(monster.Position);
            Vector2F    tilePosition = tileLocation * GameSettings.TILE_SIZE;
            Vector2F    tileCenter   = tilePosition + new Vector2F(8, 8);
            Rectangle2F holeRect     = new Rectangle2F(tilePosition.X + 6, tilePosition.Y + 8, 4, 6);

            bool fallInHole = holeRect.Contains(monster.Position);

            Vector2F trajectory = tileCenter - monster.Center;

            if (trajectory.Length > slipSpeed)
            {
                monster.Physics.Velocity = (tileCenter - monster.Center).Normalized * slipSpeed;
            }
            else
            {
                fallInHole = true;
                monster.Physics.Velocity = Vector2F.Zero;
                monster.SetPositionByCenter(tileCenter);
            }

            if (fallInHole)
            {
                monster.RoomControl.SpawnEntity(new EffectFallingObject(), monster.Center);
                AudioSystem.PlaySound(GameData.SOUND_OBJECT_FALL);
                monster.Destroy();
            }
        }
Exemplo n.º 28
0
        // Remove a tile from the room.
        public void RemoveTile(Tile tile)
        {
            Rectangle2I area = tile.TileGridArea;

            for (int x = area.Left; x < area.Right; x++)
            {
                for (int y = area.Top; y < area.Bottom; y++)
                {
                    tiles[x, y, tile.Layer] = null;
                }
            }
            tile.IsAlive = false;
            tile.OnRemoveFromRoom();

            // Check for uncovered tiles.
            Rectangle2F tileBounds = tile.Bounds;

            foreach (Tile t in GetTilesTouching(tileBounds))
            {
                t.OnUncoverBegin(tile);
                t.OnUncoverComplete(tile);
            }
        }
Exemplo n.º 29
0
        /** <summary> Returns the width and height of a string. </summary> */
        public Rectangle2F MeasureStringBounds(string text, Align alignment)
        {
            Rectangle2F stringBounds = new Rectangle2F(Vector2F.Zero, spriteFont.MeasureString(text));
            bool        intAlign     = (alignment & Align.Int) != 0;

            if (((alignment & Align.Left) != 0) == ((alignment & Align.Right) != 0))
            {
                stringBounds.X -= (intAlign ? (int)(stringBounds.Width / 2.0f) : (stringBounds.Width / 2.0f));
            }
            else if ((alignment & Align.Right) != 0)
            {
                stringBounds.X -= stringBounds.Width;
            }
            if (((alignment & Align.Top) != 0) == ((alignment & Align.Bottom) != 0))
            {
                stringBounds.Y -= (intAlign ? (int)(stringBounds.Height / 2.0f) : (stringBounds.Height / 2.0f));
            }
            else if ((alignment & Align.Bottom) != 0)
            {
                stringBounds.Y -= stringBounds.Height;
            }
            return(stringBounds);
        }
Exemplo n.º 30
0
        // Return true if the entity would collide with a solid object using the
        // given collision box if it were placed at the given position.
        public bool IsPlaceMeetingSolid(Vector2F position, Rectangle2F collisionBox)
        {
            Room room = entity.RoomControl.Room;

            // Find the rectangular area of nearby tiles to collide with.
            Rectangle2F myBox = collisionBox;

            myBox.Point += position;
            myBox.Inflate(2, 2);

            int x1 = (int)(myBox.Left / (float)GameSettings.TILE_SIZE);
            int y1 = (int)(myBox.Top / (float)GameSettings.TILE_SIZE);
            int x2 = (int)(myBox.Right / (float)GameSettings.TILE_SIZE) + 1;
            int y2 = (int)(myBox.Bottom / (float)GameSettings.TILE_SIZE) + 1;

            Rectangle2I area;

            area.Point = (Point2I)(myBox.TopLeft / (float)GameSettings.TILE_SIZE);
            area.Size  = ((Point2I)(myBox.BottomRight / (float)GameSettings.TILE_SIZE)) + Point2I.One - area.Point;
            area.Inflate(1, 1);
            area = Rectangle2I.Intersect(area, new Rectangle2I(Point2I.Zero, room.Size));

            myBox.Inflate(-2, -2);

            foreach (Tile t in entity.RoomControl.GetTilesInArea(area))
            {
                if (CanCollideWithTile(t))
                {
                    if (CollisionModel.Intersecting(t.CollisionModel, t.Position, collisionBox, position))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }