Пример #1
0
        // Check if an exact coordinate has a Blocking Square (Ground, BlockTile, HorizontalWall, etc.)
        public static bool IsBlockingCoord(TilemapLevel tilemap, int posX, int posY, DirCardinal dir)
        {
            short gridX = (short)(posX / (byte)TilemapEnum.TileWidth);
            short gridY = (short)(posY / (byte)TilemapEnum.TileHeight);

            return(CollideTile.IsBlockingSquare(tilemap, gridX, gridY, dir));
        }
Пример #2
0
        private void RunTickForObjectGroup(Dictionary <int, GameObject> objectGroup)
        {
            // Loop through each object in the dictionary, run it's tick:
            foreach (var obj in objectGroup)
            {
                obj.Value.RunTick();

                // Run Tile Detection for the Object
                CollideTile.RunTileCollision(obj.Value);
            }
        }
Пример #3
0
        // Identical to "RunTickForObjectGroup", but with an extra overlap test for Characters.
        // RunTileCollision only detects what you're moving INTO, not what you're on top of.
        // Characters need the additional check to know what they're on top of, such as for Chests, Doors, NPCs, etc.
        private void RunTickForCharacterGroup(Dictionary <int, GameObject> objectGroup)
        {
            foreach (var obj in objectGroup)
            {
                Character character = (Character)obj.Value;

                // If the character is frozen from a reset, prevent them from running any actions.
                if (character.frozenFrame >= Systems.timer.Frame)
                {
                    // If we're on the release frame, provide a sound:
                    if (character.frozenFrame == Systems.timer.Frame)
                    {
                        character.room.PlaySound(Systems.sounds.pop, 0.7f, Systems.camera.posX + Systems.camera.halfWidth, Systems.camera.posY + Systems.camera.halfHeight);
                    }

                    continue;
                }

                character.RunTick();

                CollideTile.RunTileCollision(character);

                // Determine Tiles Potentially Touched
                short gridX  = character.GridX;
                short gridY  = character.GridY;
                short gridX2 = character.GridX2;
                short gridY2 = character.GridY2;

                // Run Collision Tests on any tiles beneath the Character (to identify Chests, Doors, NPCs, etc).
                CollideTile.RunGridTest(character, gridX, gridY, DirCardinal.Center);

                if (gridX != gridX2)
                {
                    CollideTile.RunGridTest(character, gridX2, gridY, DirCardinal.Center);

                    if (gridY != gridY2)
                    {
                        CollideTile.RunGridTest(character, gridX, gridY2, DirCardinal.Center);
                        CollideTile.RunGridTest(character, gridX2, gridY2, DirCardinal.Center);
                    }
                }
                else if (gridY != gridY2)
                {
                    CollideTile.RunGridTest(character, gridX, gridY2, DirCardinal.Center);
                }
            }
        }
Пример #4
0
        // Detect interactions with 4 Grid Squares, with object's X,Y in the Top-Left square.
        public static void RunTileCollision(GameObject actor)
        {
            // Don't run collision if the actor is designated not to collide.
            if (actor.CollideVal <= CollideEnum.NoTileCollide)
            {
                return;
            }

            // Determine Tiles Potentially Touched
            short gridX  = actor.GridX;
            short gridY  = actor.GridY;
            short gridX2 = actor.GridX2;
            short gridY2 = actor.GridY2;

            bool vertOnly = gridX == gridX2;

            // If the object is only interacting with vertical squares:
            if (vertOnly)
            {
                if (actor.physics.velocity.Y < 0)
                {
                    CollideTile.RunGridTest(actor, gridX, gridY, DirCardinal.Up);
                }
                else
                {
                    CollideTile.RunGridTest(actor, gridX, gridY2, DirCardinal.Down);
                }
                return;
            }

            bool horOnly = gridY == gridY2;

            // If the object is only interacting between two tiles (left and right).
            if (horOnly)
            {
                if (actor.physics.velocity.X >= 0)
                {
                    CollideTile.RunGridTest(actor, gridX2, gridY, DirCardinal.Right);
                }
                else
                {
                    CollideTile.RunGridTest(actor, gridX, gridY, DirCardinal.Left);
                }
                return;
            }

            // If the object is interacting with all four tiles (Top-Left to Bottom-Right).
            FInt velX = actor.physics.velocity.X;
            FInt velY = actor.physics.velocity.Y;

            // If moving downward:
            if (velY > 0)
            {
                // If moving DOWN-RIGHT.
                if (velX > 0)
                {
                    // Compare against BOTTOM-LEFT (vs. up) and TOP-RIGHT (vs. left)
                    bool down  = CollideTile.RunGridTest(actor, gridX, gridY2, DirCardinal.Down);
                    bool right = CollideTile.RunGridTest(actor, gridX2, gridY, DirCardinal.Right);

                    // Test against corner if neither of the above collided. Direction of collision based on momentum.
                    if (!down && !right)
                    {
                        int yOverlap = actor.posY + actor.bounds.Bottom - (gridY2 * (byte)TilemapEnum.TileHeight);                         // Returns POSITIVE value
                        if (yOverlap > velY.RoundInt)
                        {
                            CollideTile.RunGridTest(actor, gridX2, gridY2, DirCardinal.Right); return;
                        }

                        int xOverlap = actor.posX + actor.bounds.Right - (gridX2 * (byte)TilemapEnum.TileWidth);                         // Returns POSITIVE value
                        if (xOverlap > velX.RoundInt)
                        {
                            CollideTile.RunGridTest(actor, gridX2, gridY2, DirCardinal.Down);
                        }
                    }
                }

                // If moving DOWN-LEFT:
                else if (velX < 0)
                {
                    // Compare against BOTTOM-RIGHT (vs.up) and TOP-LEFT (vs. right)
                    bool down = CollideTile.RunGridTest(actor, gridX2, gridY2, DirCardinal.Down);
                    bool left = CollideTile.RunGridTest(actor, gridX, gridY, DirCardinal.Left);

                    // Test against corner if neither of the above collided. Direction of collision based on momentum.
                    if (!down && !left)
                    {
                        int yOverlap = actor.posY + actor.bounds.Bottom - (gridY2 * (byte)TilemapEnum.TileHeight);                         // Returns POSITIVE value
                        if (yOverlap > velY.RoundInt)
                        {
                            CollideTile.RunGridTest(actor, gridX, gridY2, DirCardinal.Left); return;
                        }

                        int xOverlap = actor.posX + actor.bounds.Left - (gridX2 * (byte)TilemapEnum.TileWidth);                         // Returns NEGATIVE value
                        if (xOverlap < velX.RoundInt)
                        {
                            CollideTile.RunGridTest(actor, gridX, gridY2, DirCardinal.Down);
                        }
                    }
                }

                // If moving DOWN:
                else
                {
                    // Get Overlaps
                    int xOverlapLeft  = actor.posX + actor.bounds.Left - (gridX2 * (byte)TilemapEnum.TileWidth);
                    int xOverlapRight = actor.posX + actor.bounds.Right - (gridX2 * (byte)TilemapEnum.TileWidth);

                    // Compare against BOTTOM HALF (vs. up). No corner test.
                    if (xOverlapLeft < 0)
                    {
                        CollideTile.RunGridTest(actor, gridX, gridY2, DirCardinal.Down);
                    }
                    if (xOverlapRight > 0)
                    {
                        CollideTile.RunGridTest(actor, gridX2, gridY2, DirCardinal.Down);
                    }
                }
            }

            // If moving upward:
            else
            {
                // If moving UP-RIGHT:
                if (velX > 0)
                {
                    // Compare against TOP-LEFT (vs. down) and BOTTOM-RIGHT (vs. left)
                    bool up    = CollideTile.RunGridTest(actor, gridX, gridY, DirCardinal.Up);
                    bool right = CollideTile.RunGridTest(actor, gridX2, gridY2, DirCardinal.Right);

                    // Test against corner if neither of the above collided. Direction of collision based on momentum.
                    if (!up && !right)
                    {
                        int yOverlap = actor.posY + actor.bounds.Top - (gridY2 * (byte)TilemapEnum.TileHeight);                         // Returns NEGATIVE value
                        if (yOverlap < velY.RoundInt)
                        {
                            CollideTile.RunGridTest(actor, gridX2, gridY, DirCardinal.Right); return;
                        }

                        int xOverlap = actor.posX + actor.bounds.Right - (gridX2 * (byte)TilemapEnum.TileWidth);                         // Returns POSITIVE value
                        if (xOverlap > velX.RoundInt)
                        {
                            CollideTile.RunGridTest(actor, gridX2, gridY, DirCardinal.Up);
                        }
                    }
                }

                // If moving UP-LEFT:
                else if (velX < 0)
                {
                    // Compare against TOP-RIGHT (vs. down) and BOTTOM-LEFT (vs. right)
                    bool up   = CollideTile.RunGridTest(actor, gridX2, gridY, DirCardinal.Up);
                    bool left = CollideTile.RunGridTest(actor, gridX, gridY2, DirCardinal.Left);

                    // Test against corner if neither of the above collided. Direction of collision based on momentum.
                    if (!up && !left)
                    {
                        int yOverlap = actor.posY + actor.bounds.Top - (gridY2 * (byte)TilemapEnum.TileHeight);                         // Returns NEGATIVE value
                        if (yOverlap < velY.RoundInt)
                        {
                            CollideTile.RunGridTest(actor, gridX, gridY, DirCardinal.Left); return;
                        }

                        int xOverlap = actor.posX + actor.bounds.Left - (gridX2 * (byte)TilemapEnum.TileWidth);                         // Returns NEGATIVE value
                        if (xOverlap < velX.RoundInt)
                        {
                            CollideTile.RunGridTest(actor, gridX, gridY, DirCardinal.Up);
                        }
                    }
                }

                // If moving UP:
                else
                {
                    // Get Overlaps
                    int xOverlapLeft  = actor.posX + actor.bounds.Left - (gridX2 * (byte)TilemapEnum.TileWidth);
                    int xOverlapRight = actor.posX + actor.bounds.Right - (gridX2 * (byte)TilemapEnum.TileWidth);

                    // Compare against TOP HALF (vs. down). No corner test.
                    if (xOverlapLeft < 0)
                    {
                        CollideTile.RunGridTest(actor, gridX, gridY, DirCardinal.Up);
                    }
                    if (xOverlapRight > 0)
                    {
                        CollideTile.RunGridTest(actor, gridX2, gridY, DirCardinal.Up);
                    }
                }
            }
        }