예제 #1
0
 private void SpawnTentacles()
 {
     if (tentacles.Alive == 0)
     {
         tentacles.Spawn((t) => t.Spawn(proximity_hits, this), 4);
     }
 }
예제 #2
0
        public Burst_Plant(EntityPreset preset, Player p) : base(preset, preset.Position, "burst_plant", 16, 16, Drawing.DrawOrder.ENTITIES, 0.7f)
        {
            AddAnimation("idle", CreateAnimFrameArray(0));
            AddAnimation("charging", CreateAnimFrameArray(0, 1), 8);
            AddAnimation("shoot", CreateAnimFrameArray(3));
            Play("idle");
            immovable = true;

            _bullets = new(8, () => new());

            _state = new StateMachineBuilder()
                     .State <TimerState>("Initial")
                     .Enter((s) => s.AddTimer(0.4f, "goToIdle"))
                     .Event("goToIdle", (s) => _state.ChangeState("Idle"))
                     .End()
                     .State <TimerState>("Idle")
                     .Enter((s) =>
            {
                Play("idle");
                s.Reset();
                s.AddTimer(0.4f + (float)GlobalState.RNG.NextDouble(), "idleTimer");
            })
                     .Event("idleTimer", (s) => _state.ChangeState("Charging"))
                     .End()
                     .State <ChargeState>("Charging")
                     .Enter((s) => Play("charging"))
                     .Event("Fire", (s) =>
            {
                int sign      = MathUtilities.OneRandomOf(-1, 1);
                float max_vel = 10 + 30 * (float)GlobalState.RNG.NextDouble();
                _bullets.Spawn((b) => b.SpawnToPlayer(this, max_vel, p));         //one straight to the player
                _bullets.Spawn((b) => b.Spawn(this, max_vel, sign), 7);
                Play("shoot");
                SoundManager.PlaySoundEffect("bubble_triple");
                _state.ChangeState("BulletsFlying");
            })
                     .End()
                     .State("BulletsFlying")
                     .Condition(() => _bullets.Alive == 0, (s) => _state.ChangeState("Idle"))
                     .End()
                     .Build();
            _state.ChangeState("Initial");
        }
예제 #3
0
        public SteamPipe(EntityPreset preset, Player player)
            : base(preset.Position, "steam_pipe", 16, 16, DrawOrder.ENTITIES)
        {
            _player = player;

            Vector2 startPos = Vector2.Zero;

            SetFrame(preset.Frame);

            switch (GetFrame())
            {
            case 0:
                width = 10;

                offset   = new Vector2(3, 16);
                startPos = Position + new Vector2(2, 10);

                facing = Facing.DOWN;
                break;

            case 1:
                height = 10;

                offset   = new Vector2(14, 5);
                startPos = Position + new Vector2(14, 5);

                facing = Facing.RIGHT;
                break;

            case 2:
                width = 10;

                offset   = new Vector2(3, -4);
                startPos = Position + new Vector2(3, -2);

                facing = Facing.UP;
                break;

            case 3:
                height = 10;

                offset   = new Vector2(-6, 3);
                startPos = Position + new Vector2(-6, 3);

                facing = Facing.LEFT;
                break;
            }
            Position += offset;

            _steam = new EntityPool <Steam>(6, () => new Steam(startPos, this));

            _steam.Spawn(s => s.Spawn(), 6);
        }
예제 #4
0
        public Frog(EntityPreset preset, Player p) : base(preset, preset.Position, "frog", 16, 16, Drawing.DrawOrder.ENTITIES, 0.7f)
        {
            AddAnimation("idle", CreateAnimFrameArray(0, 1), 2, true);
            AddAnimation("shoot_d", CreateAnimFrameArray(3), 3, false);
            AddAnimation("shoot_r", CreateAnimFrameArray(4), 3, false);
            AddAnimation("shoot_l", CreateAnimFrameArray(4), 3, false);
            AddAnimation("shoot_u", CreateAnimFrameArray(5), 3, false);
            Play("idle");
            immovable = true;
            _player   = p;

            int i = 0;

            _bullets = new(3, () => new(i++));

            _state = new StateMachineBuilder()
                     .State <TimerState>("Initial")
                     .Enter((s) =>
            {
                s.Reset();
                s.AddTimer(0.8f, "goToIdle");
            })
                     .Event("goToIdle", (s) => _state.ChangeState("Idle"))
                     .End()
                     .State("Idle")
                     .Enter((s) =>
            {
                Play("idle");
            })
                     .Condition(() => (Center - _player.Center).LengthSquared() < 64 * 64, (s) =>
            {
                _bullets.Spawn((b) => b.Spawn(this, _player), 3);
                FaceTowards(_player.Center);
                PlayFacing("shoot");
                SoundManager.PlaySoundEffect("bubble_triple");
                _state.ChangeState("BulletsFlying");
            })
                     .End()
                     .State("BulletsFlying")
                     .Condition(() => _bullets.Alive == 0, (s) => _state.ChangeState("Idle"))
                     .End()
                     .Build();
            _state.ChangeState("Initial");
        }
예제 #5
0
        public override void LoadContent()
        {
            ContentManager content = ScreenManager.Game.Content;

            map = content.Load <Map>("map");
            MapObject spawn = ((MapObjectLayer)map.GetLayer("spawn")).Objects[0];

            camera        = new Camera(ScreenManager.Game.RenderWidth, ScreenManager.Game.RenderHeight, map);
            camera.Target = new Vector2(ScreenManager.Game.RenderWidth, ScreenManager.Game.RenderHeight) / 2f;

            heroPool = new EntityPool(100,
                                      sheet => new Hero(sheet, new Rectangle(0, 0, 10, 10), new Vector2(0, -5)),
                                      content.Load <Texture2D>("testhero"));
            heroPool.BoxCollidesWith.Add(heroPool);

            rotBoxPool = new EntityPool(100,
                                        sheet => new RotBox(sheet, new Rectangle(0, 0, 32, 32), null, Vector2.Zero),
                                        ScreenManager.blankTexture);
            rotBoxPool.PolyCollidesWith.Add(rotBoxPool);

            rotBoxPool.Spawn(entity =>
            {
                entity.Position = new Vector2(100, 100);
            });
            rotBoxPool.Spawn(entity =>
            {
                entity.Position = new Vector2(140, 100);
            });

            particleController.LoadContent(content);

            // TimerController.Instance.Create("shake", () => camera.Shake(500, 2f), 3000, true);

            TweenController.Instance.Create("spintext", TweenFuncs.SineEaseInOut, (tween) =>
            {
                textScale = 0.8f + (tween.Value * 0.4f);
            }, 3000, true, true);

            //// More crazy tween examples
            //TweenController.Instance.Create("spincam", TweenFuncs.Linear, (tween) =>
            //{
            //    camera.Rotation = MathHelper.TwoPi * tween.Value;
            //}, 10000, false, true, TweenDirection.Reverse);

            //TweenController.Instance.Create("zoomcam", TweenFuncs.Bounce, (tween) =>
            //{
            //    camera.Zoom = 1f + tween.Value;
            //}, 3000, true, true);

            particleController.Add(new Vector2(195, 150),
                                   Vector2.Zero,
                                   0, 1000, 0,
                                   false, false,
                                   new Rectangle(18, 0, 100, 100),
                                   Color.White,
                                   ParticleFunctions.PermaLight,
                                   1f, 0f,
                                   1, ParticleBlend.Multiplicative);

            base.LoadContent();
        }
예제 #6
0
        public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
        {
            camera.Update(gameTime);

            heroPool.Update(gameTime, map);
            rotBoxPool.Update(gameTime);

            // This stuff is all example - camera follows random Hero and zooms in when following
            //if (Helper.Random.Next(200) == 0)
            //{
            //    List<Entity> activeHeroes = heroPool.Entities.Where(hero => hero.Active).ToList();
            //    if (activeHeroes.Count > 0) followingHero = (Hero) activeHeroes[Helper.Random.Next(activeHeroes.Count)];
            //}
            //if (Helper.Random.Next(200) == 1 && followingHero != null) followingHero = null;

            //if (followingHero != null && followingHero.Active)
            //{
            //    camera.Target = followingHero.Position;
            //    if (camera.Zoom < 2.5f) camera.Zoom += 0.05f;
            //}
            //else
            //{
            //    camera.Target = new Vector2(ScreenManager.Game.RenderWidth, ScreenManager.Game.RenderHeight)/2f;
            //    if (camera.Zoom > 1f) camera.Zoom -= 0.05f;
            //}
            //////////////////



            particleController.Update(gameTime, map);

            if (Helper.Random.Next(100) == 0)
            {
                heroPool.Spawn(entity =>
                {
                    entity.Position        = new Vector2(Helper.Random.Next(ScreenManager.Game.RenderWidth - 64) + 32, 32);
                    ((Hero)entity).FaceDir = Helper.Random.Next(2) == 0 ? -1 : 1;
                });
            }

            particleController.Add(new Vector2(17, 40),
                                   new Vector2(Helper.RandomFloat(2f), -1.5f),
                                   100, 3000, 1000,
                                   true, true,
                                   new Rectangle(0, 0, 2, 2),
                                   new Color(new Vector3(1f, 0f, 0f) * (0.25f + Helper.RandomFloat(0.5f))),
                                   ParticleFunctions.FadeInOut,
                                   1f, 0f,
                                   1, ParticleBlend.Alpha);

            particleController.Add(new Vector2(150, 176),
                                   new Vector2(-0.05f + Helper.RandomFloat(0.1f), -0.1f),
                                   1000, Helper.Random.NextDouble() * 3000, Helper.Random.NextDouble() * 3000,
                                   false, false,
                                   new Rectangle(0, 0, 16, 16),
                                   new Color(new Vector3(1f) * (0.25f + Helper.RandomFloat(0.5f))),
                                   ParticleFunctions.Smoke,
                                   0.1f, 0f,
                                   1, ParticleBlend.Additive);

            particleController.Add(new Vector2(250, 50),
                                   new Vector2(-1f + Helper.RandomFloat(2f), -1f + Helper.RandomFloat(2f)),
                                   100, 500, 1000,
                                   false, false,
                                   new Rectangle(0, 0, 16, 16),
                                   Color.White,
                                   ParticleFunctions.FadeLight,
                                   Helper.RandomFloat(0.5f), 0f,
                                   1, ParticleBlend.Multiplicative);


            base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
        }
예제 #7
0
        public GasGuy(EntityPreset preset, Player player)
            : base(preset, preset.Position, "gas_guy", 16, 24, DrawOrder.ENTITIES, 0.6f, true)
        {
            _player = player;

            AddAnimation("float", CreateAnimFrameArray(0, 1), 2, true);
            AddAnimation("release_gas", CreateAnimFrameArray(2), 20, true);
            Play("float");

            drag = new Vector2(30);

            soundDelay    = 0;
            soundDelayMax = (float)(1.5 + GlobalState.RNG.NextDouble());

            gasClouds = new EntityPool <Gas>(3, () => new Gas());

            _state = new StateMachineBuilder()
                     .State <TimerState>("InitialLatency")
                     .Enter((state) =>
            {
                state.Reset();
                state.AddTimer(1.5f, "StartTimer");
                _inDelay = true;
            })
                     .Event("StartTimer", (state) =>
            {
                _state.ChangeState("Normal");
            })
                     .Exit((state) =>
            {
                _inDelay = false;
            })
                     .End()
                     .State <TimerState>("Normal")
                     .Enter((state) =>
            {
                state.Reset();
                state.AddTimer(_didFirstShot ? 5f : 1f, "PreShootTimer");
                Play("float");
            })
                     .Event("PreShootTimer", (state) =>
            {
                Play("release_gas");
                _state.ChangeState("Shoot");
                _didFirstShot = true;
            })
                     .End()
                     .State <TimerState>("Shoot")
                     .Enter((state) =>
            {
                state.Reset();
                state.AddTimer(1.2f, "ShootTimer");
            })
                     .Event("ShootTimer", (state) =>
            {
                Play("shoot");
                _state.ChangeState("Normal");
                SoundManager.PlaySoundEffect("gasguy_shoot");
                gasClouds.Spawn((s) => s.Spawn(this, _player), 3, true);
            })
                     .End()
                     .Build();

            _state.ChangeState("InitialLatency");
        }
예제 #8
0
        public Annoyer(EntityPreset preset, Player player)
            : base(preset.Position, "annoyer", 16, 16, DrawOrder.ENTITIES)
        {
            MapInteraction = false;
            _preset        = preset;
            _target        = player;
            Solid          = false;
            height         = 7;
            width          = 8;
            offset.X       = 3;
            offset.Y       = 2;

            explosion = new Explosion(Position)
            {
                exists = false
            };

            if (GlobalState.IsCell)
            {
                AddAnimation("flap", CreateAnimFrameArray(6, 7), 4, true);
            }
            else
            {
                int i = preset.Frame == T_SUPER ? 12 : 0;
                AddAnimation("flap", CreateAnimFrameArray(i, i + 1, i + 2, i + 3, i + 4, i + 5), 8, true);
            }
            Play("flap");

            if (preset.Frame == T_SUPER)
            {
                _health = 2;
            }

            fireballs = new EntityPool <Fireball>(preset.Frame == T_SUPER ? 4 : 0, () => new Fireball());

            _state = new StateMachineBuilder()
                     .State <ActiveState>("Active")
                     .Enter((state) => {
                velocity = Vector2.Zero;
                state.ChangeState(start_state);
                start_state = "Approach";         //TODO: Add way of entering nested states(see ChangeState in Hit, needs to go to Approach, not Wait)
            })
                     .Event <CollisionEvent <Player> >("Player", (state, p) => p.entity.ReceiveDamage(1))
                     .Event <CollisionEvent <Broom> >("Hit", (state, b) => {
                velocity = FacingDirection(b.entity.facing) * 150;
                if (velocity.Y < 0)
                {
                    velocity.X = GlobalState.RNG.Next(-30, 31);
                }
                _state.ChangeState("Hit");
            })

                     .Event("Fire", (state) => fireballs.Spawn((f) => f.Spawn(this, _target)))

                     .State <TimerState>("Wait")
                     .Enter((state) =>
            {
                state.Reset();
                state.AddTimer(0.25f, "ApproachCheck");
            })
                     .Event("ApproachCheck", (state) =>
            {
                if ((Position - _target.Position).Length() < 64)
                {
                    state.Parent.ChangeState("Approach");
                }
            })
                     .End()

                     .State("Approach")
                     .Update((state, time) => {
                MathUtilities.MoveTo(ref Position.X, ApproachTarget.X, 36);
                MathUtilities.MoveTo(ref Position.Y, ApproachTarget.Y, 36);
            })
                     .Condition(() => (Position - ApproachTarget).Length() < 2, (state) => state.Parent.ChangeState("Circle"))
                     .Exit((state) => velocity = Vector2.Zero)
                     .End()

                     .State <CirclingState>("Circle")
                     .Enter((state) => state.angle = 0)
                     .Update((state, time) =>
            {
                Position = _target.VisualCenter + new Vector2((float)Math.Cos(state.angle), (float)Math.Sin(state.angle)) * rotation_radius;
            })
                     .Event("Swoop", (state) => state.Parent.ChangeState("Swoop"))
                     .End()

                     .State <SwoopState>("Swoop")
                     .Enter((state) => state.target = Position + 3 * (_target.Position - Position))
                     .Update((state, time) => {   //TODO: make it possible for this to be a Condition
                if (MathUtilities.MoveTo(ref Position.X, state.target.X, 2.5f * 60) & MathUtilities.MoveTo(ref Position.Y, state.target.Y, 2.5f * 60))
                {
                    state.Parent.ChangeState("Approach");
                }
            })
                     .End()
                     .End()

                     .State <TimerState>("Hit")
                     .Enter((state) =>
            {
                SoundManager.PlaySoundEffect("player_hit_1");
                state.Reset();
                Flicker(0.2f);
                if (--_health <= 0)
                {
                    Solid = true;
                    state.AddTimer(0.25f, "Die");
                }
                else
                {
                    state.AddTimer(0.4f, "EndKnockback");
                }
            })
                     .Event("EndKnockback", (state) => _state.ChangeState("Active"))
                     .Event("Die", (state) => {
                exists             = _preset.Alive = false;
                explosion.exists   = true;
                explosion.Position = Position;
                SoundManager.PlaySoundEffect("hit_wall");
            })
                     .Exit((state) =>
            {
                Solid = false;
            })
                     .End()

                     .Build();
            _state.ChangeState("Active");
        }
예제 #9
0
 /// <summary>
 /// Shortcut to spawning prefab from a pool
 /// </summary>
 public Entity InstantiateFromPool(Vector3?position = null, Quaternion?rotation = null)
 {
     return(EntityPool.Spawn(PackToEntity(), position, rotation));
 }
예제 #10
0
        IEnumerator State()
        {
            y_push = sprite.Height;
            player.grid_entrance = MapUtilities.GetRoomUpperLeftPos(GlobalState.CurrentMapGrid) + Vector2.One * 20;

            GlobalState.SpawnEntity(new VolumeEvent(0, 3));

            while (MapUtilities.GetInGridPosition(player.Position).X < 48)
            {
                yield return(null);
            }

            GlobalState.Dialogue = Dialogue.DialogueManager.GetDialogue("redboss", "before_fight");

            float push_timer = 0f;

            loopSFX = true;
            while (!GlobalState.LastDialogueFinished)
            {
                push_timer += GameTimes.DeltaTime;
                if (push_timer >= push_tick_max)
                {
                    push_timer = 0f;
                    if (y_push > 0)
                    {
                        GlobalState.screenShake.Shake(0.021f, 0.1f);
                        y_push--;
                    }
                }
                yield return(null);
            }
            loopSFX = false;

            SoundManager.PlaySong("redcave-boss");
            Play("bob");

            IState state = new StateMachineBuilder()
                           .State <SplashState>("Splash")
                           .Enter((s) => amp = 5)
                           .Event("Splash", (s) =>
            {
                splash_bullets.Spawn(b => b.Spawn(), 4);
            })
                           .Event("Tentacles", (s) =>
            {
                SpawnTentacles();
                if (proximity_hits != Touching.NONE)
                {
                    s.got_too_close++;
                    if (s.got_too_close == 2)
                    {
                        s.got_too_close = 0;
                        s.Parent.ChangeState("Stun");
                    }
                }
            })
                           .End()
                           .State <DashState>("Dash")
                           .Enter((s) =>
            {
                amp      = 0;
                velocity = new Vector2(30, 20);
                Play("bob");
            })
                           .Update((s, _) =>
            {
                Drawing.Effects.ScreenShake.Directions dirs = new();
                Vector2 tl = MapUtilities.GetInGridPosition(Position);
                Vector2 br = MapUtilities.GetInGridPosition(Position + new Vector2(width, height));
                if (tl.Y < 2 * 16)
                {
                    velocity.Y = 60;
                    dirs      |= Drawing.Effects.ScreenShake.Directions.Vertical;
                }
                else if (br.Y > 16 * 8)
                {
                    velocity.Y = -60;
                    dirs      |= Drawing.Effects.ScreenShake.Directions.Vertical;
                }

                if (tl.X < 2 * 16)
                {
                    velocity.X = 60;
                    dirs      |= Drawing.Effects.ScreenShake.Directions.Horizontal;
                }
                else if (br.X > 16 * 8)
                {
                    velocity.X = -60;
                    dirs      |= Drawing.Effects.ScreenShake.Directions.Horizontal;
                }
                GlobalState.screenShake.Shake(0.05f, 0.1f, dirs);
            })
                           .Event("Tentacles", (s) =>
            {
                SpawnTentacles();
                if (proximity_hits != Touching.NONE)
                {
                    s.got_too_close++;
                    if (s.got_too_close == 2)
                    {
                        s.got_too_close = 0;
                        s.Parent.ChangeState("Splash");
                    }
                }
            })
                           .Event("EndDash", (s) =>
            {
                s.Parent.ChangeState("Stun");
            })
                           .Exit((s) => velocity = Vector2.Zero)
                           .End()
                           .State <StunState>("Stun")
                           .Enter((s) => s.stateLogic = StunStateLogic())
                           .Update((s, _) =>
            {
                if (!s.stateLogic.MoveNext())
                {
                    s.Parent.ChangeState("Dash");
                }
            })
                           .End()
                           .Build();

            state.ChangeState("Splash");
            state.TriggerEvent("Splash"); //First time instantly fires splash bullets

            while (health > 0)
            {
                state.Update(GameTimes.DeltaTime);

                pushdown_timer += GameTimes.DeltaTime * 3;
                y_push          = (int)(amp + MathF.Sin(pushdown_timer) * amp);
                yield return(null);
            }

            velocity = Vector2.Zero;

            SoundManager.StopSong();
            GlobalState.Dialogue = Dialogue.DialogueManager.GetDialogue("redboss", "after_fight");
            GlobalState.screenShake.Shake(0.05f, 0.1f);
            GlobalState.flash.Flash(1f, Color.Red);

            while (!GlobalState.LastDialogueFinished)
            {
                yield return(null);
            }

            Play("die");
            SoundManager.PlaySoundEffect("redboss_death");
            GlobalState.wave.active = true;

            y_push = 0;

            while (y_push < sprite.Height)
            {
                MathUtilities.MoveTo(ref ripple.opacity, 0, 0.3f);

                push_timer += GameTimes.DeltaTime;
                if (push_timer >= push_tick_max)
                {
                    push_timer = 0f;
                    y_push++;
                }
                yield return(null);
            }

            float final_timer = 2f;

            while (final_timer > 0f)
            {
                final_timer -= GameTimes.DeltaTime;
                yield return(null);
            }

            preset.Alive            = exists = false;
            GlobalState.wave.active = false;
            SoundManager.PlaySong("redcave");
            GlobalState.events.BossDefeated.Add("REDCAVE");
            yield break;
        }