Example #1
0
        public override void Update(GameTime gameTime)
        {
            Console.WriteLine(gameTime.ElapsedGameTime.TotalSeconds);

            /*
             * Input State refresh
             */
            #region [System Status Refresh]

            KeyboardState kState = Keyboard.GetState();
            MouseState    mState = Mouse.GetState();

            #endregion

            /*
             * First of all, we update the player
             * and other sprites velocity vectors
             */
            #region [Update Sprites Velocity and Position]

            player.UpdateMotion(gameTime, kState);

            foreach (Sprite s in enemies)
            {
                if (s.Body.Tag == "turtlex")
                {
                    TurtleX t             = (TurtleX)s;
                    float   inflictDamage = t.UpdateMov(gameTime, player);

                    if (inflictDamage > 0f)
                    {
                        TriggerPlayerHurt(gameTime, t, inflictDamage);
                        t.Kill();
                    }

                    if (inflictDamage == -1f)
                    {
                        t.Kill();
                        camera.ActivateShake(gameTime, 400f, 6, 0.01f, true, -0.02f);
                    }

                    continue;
                }

                s.Update(gameTime);

                if (s.Alive)
                {
                    if (Physics.Overlap(s, player) && !player.IsBlinking)  // when blinking, take no damage
                    {
                        TriggerPlayerHurt(gameTime, s);
                    }
                }
            }

            #endregion

            /*
             * Because the hazards may cause velocity changes,
             * we overlap the player with them, BEFORE checking
             * for collisions with the world.
             */
            #region [Hazards Overlap]

            if (!player.IsBlinking)
            {
                foreach (Tile spike in spikesPointingDown)
                {
                    if (Physics.Overlap(spike, player))
                    {
                        TriggerPlayerHurt(gameTime, spike);
                        break;  // breaking at the first overlap
                                // avoids various knockback forces
                                // being applied.
                                // this solved the issue (as far as I tested)
                                // of glitching through the solid tiles
                    }
                }
                foreach (Tile spike in spikesPointingUp)
                {
                    if (Physics.Overlap(spike, player))
                    {
                        TriggerPlayerHurt(gameTime, spike);
                        break;
                    }
                }
            }

            /*
             * Player Projectiles
             */
            player.UpdateProjectiles(gameTime, kState);

            foreach (Bullet b in player.Bullets)
            {
                if (b.Alive)
                {
                    foreach (Tile t in level.CollidableTiles)
                    {
                        if (Physics.Overlap(b, t))
                        {
                            b.Kill();
                        }
                    }
                    foreach (Sprite s in enemies)
                    {
                        if (s.Alive)
                        {
                            if (Physics.Overlap(b, s))
                            {
                                b.Kill();
                                s.ReceiveDamage(b.Damage);
                                s.StartBlinking(gameTime);

                                if (!s.Alive)
                                {
                                    camera.ActivateShake(gameTime, 150, 6, 0.015f, true, -0.01f);
                                }
                            }
                        }
                    }
                }
            }

            /*
             * Enemies Projectiles
             */
            foreach (Sprite p in enemies)
            {
                if (p.Alive)
                {
                    if (p.GetType() == typeof(PufferFish))
                    {
                        PufferFish puf = (PufferFish)p;

                        foreach (Bullet b in puf.Bullets)
                        {
                            if (b.Alive)
                            {
                                foreach (Tile t in level.CollidableTiles)
                                {
                                    if (Physics.Overlap(b, t))
                                    {
                                        b.Kill();
                                    }
                                }

                                if (player.Alive)
                                {
                                    if (Physics.Overlap(b, player) && !player.IsBlinking)
                                    {
                                        TriggerPlayerHurt(gameTime, b);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            #endregion

            /*
             * Next up, we have the world collisions
             * and resolution.
             */
            #region [World Collisions]

            bool cameraShakeResponse = player.UpdateCollisions(gameTime, level);

            RepositionOutOfBoundsPlayer(gameTime);

            #endregion

            /*
             * Particle Emitters, background assets, UI, etc..
             */
            #region [ Secondary Assets ]

            // water waves
            float count = 1f;
            foreach (Tile t in topWaterTiles)
            {
                float x          = (float)gameTime.TotalGameTime.TotalMilliseconds;
                float phaseShift = (count / topWaterTiles.Count) * (float)Math.PI * 19.7f;
                float freq       = 0.005f;
                float amp        = 1f;

                // low freq motion, sin wave 1
                t.Body.Y = Math2.SinWave((x * freq - phaseShift), amp);

                count++;
            }

            foreach (ParticleEmitter p in backgroundParticles)
            {
                p.Update(gameTime);
                p.ForEachParticle(KillOutOfBoundsParticle);
            }

            foreach (GoldFish g in goldenFishs)
            {
                g.Update(gameTime);

                if (Physics.Overlap(g, player))
                {
                    g.Kill();
                }
            }

            energyBar.SetPercent((int)(player.Energy * 100f / player.MaxEnergy));
            healthBar.SetPercent((int)(player.Health * 100f / player.MaxHealth));

            if (cameraShakeResponse && !camera.Shaking)
            {
                //camera.ActivateShake(gameTime, 250f, 4f, 0.05f, true, 0.01f); // static
                camera.ActivateShake(gameTime, 250f, Math.Abs(player.Body.DeltaY()) * 3, 0.05f, true, 0.01f); // based on delta
                //Console.WriteLine(Math.Abs(player.Body.DeltaY()));
            }

            camera.Position = new Vector2(player.Body.Position.X + player.Body.Bounds.HalfWidth, player.Body.Position.Y + player.Body.Bounds.HalfHeight);

            // clamp camera position
            float halfscreenwidth  = Graphics.PreferredBackBufferWidth / 2f;
            float halfscreenheight = Graphics.PreferredBackBufferHeight / 2f;
            camera.Position.X = MathHelper.Clamp(camera.Position.X, halfscreenwidth / camera.Zoom, (level.Width * level.TileWidth) - (halfscreenwidth / camera.Zoom));
            camera.Position.Y = MathHelper.Clamp(camera.Position.Y, -1000f, (level.Height * level.TileHeight) - (halfscreenheight / camera.Zoom));

            camera.Update(gameTime, Graphics.GraphicsDevice);

            #endregion

            /*
             * Game resolution
             */
            #region [ Game Resolution and other checks ]

            if (!player.Alive)
            {
                // show end game screen
                // now we will just restart this state
                StateManager.Instance.StartGameState("Level1State");
                return;
            }

            foreach (Trigger t in triggers)
            {
                if (Physics.Overlap(player.Body.Bounds, t))
                {
                    StateManager.Instance.StartGameState(t.Value);
                    return;
                }
            }

            #endregion
        }
Example #2
0
        public override void Update(GameTime gameTime)
        {
            //stopwatch = Stopwatch.StartNew();

            /*
             * Input State refresh
             */
            #region [System Status Refresh]

            KeyboardState kState = Keyboard.GetState();
            MouseState    mState = Mouse.GetState();

            if (Karma.startTime <= 0)
            {
                Karma.startTime = gameTime.TotalGameTime.TotalSeconds;
            }

            Karma.totalTime = gameTime.TotalGameTime.TotalSeconds;

            #endregion

            /*
             * First of all, we update the player
             * and other sprites velocity vectors
             */
            #region [Update Sprites Velocity and Position]



            player.UpdateMotion(gameTime, kState);

            foreach (SpeedBox s in speedBoxes)
            {
                if (Physics.Overlap(player.Body.Bounds, s.Bounds))
                {
                    s.ApplySpeed(gameTime, player);
                }
            }

            foreach (Sprite s in enemies)
            {
                if (s.Body.Tag == "turtlex")
                {
                    TurtleX t             = (TurtleX)s;
                    float   inflictDamage = t.UpdateMov(gameTime, player);

                    if (inflictDamage > 0f)
                    {
                        TriggerPlayerHurt(gameTime, t, inflictDamage);
                        t.Kill();
                    }

                    if (inflictDamage == -1f)
                    {
                        t.Kill();
                        camera.ActivateShake(gameTime, 400f, 6, 0.01f, true, -0.02f);
                    }

                    continue;
                }

                s.Update(gameTime);

                if (s.Alive)
                {
                    if (Physics.Overlap(s, player) && !player.IsBlinking)  // when blinking, take no damage
                    {
                        TriggerPlayerHurt(gameTime, s);
                    }
                }
            }

            #endregion

            /*
             * Because the hazards may cause velocity changes,
             * we overlap the player with them, BEFORE checking
             * for collisions with the world.
             */
            #region [Hazards Overlap]

            if (!player.IsBlinking)
            {
                foreach (Tile spike in spikesPointingDown)
                {
                    if (Physics.Overlap(spike, player))
                    {
                        TriggerPlayerHurt(gameTime, spike);
                        break;  // breaking at the first overlap
                                // avoids various knockback forces
                                // being applied.
                                // this solved the issue (as far as I tested)
                                // of glitching through the solid tiles
                    }
                }
                foreach (Tile spike in spikesPointingUp)
                {
                    if (Physics.Overlap(spike, player))
                    {
                        TriggerPlayerHurt(gameTime, spike);
                        break;
                    }
                }

                foreach (Tile spike in spikesPointingLeft)
                {
                    if (Physics.Overlap(spike, player))
                    {
                        TriggerPlayerHurt(gameTime, spike);
                        break;
                    }
                }

                foreach (Tile spike in spikesPointingRight)
                {
                    if (Physics.Overlap(spike, player))
                    {
                        TriggerPlayerHurt(gameTime, spike);
                        break;
                    }
                }
            }

            /*
             * Player Projectiles
             */
            player.UpdateProjectiles(gameTime, kState);

            foreach (Bullet b in player.Bullets)
            {
                if (b.Alive)
                {
                    foreach (Sprite s in enemies)
                    {
                        if (s.Alive)
                        {
                            if (Physics.Overlap(b, s))
                            {
                                b.Kill();
                                s.ReceiveDamage(b.Damage);
                                s.StartBlinking(gameTime);
                                Karma.ReduceKarma(1f);
                                Karma.AddPlayerDamage(1f);

                                if (!s.Alive)
                                {
                                    camera.ActivateShake(gameTime, 150, 6, 0.015f, true, -0.01f);
                                }
                            }
                        }
                    }
                }
            }

            /*
             * Enemies Projectiles
             */
            foreach (Sprite p in enemies)
            {
                if (p.Alive)
                {
                    if (p.GetType() == typeof(PufferFish))
                    {
                        PufferFish puf = (PufferFish)p;

                        foreach (Bullet b in puf.Bullets)
                        {
                            if (b.Alive)
                            {
                                if (player.Alive)
                                {
                                    if (Physics.Overlap(b, player) && !player.IsBlinking)
                                    {
                                        TriggerPlayerHurt(gameTime, b);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            #endregion

            /*
             * Next up, we have the world collisions
             * and resolution.
             */
            #region [World Collisions]

            // build loop on only the on screen tiles

            Vector2 screenTopLeftCornerToWorldCoords = camera.GetScreenToWorldPosition(Vector2.Zero);

            int topTileXIndex = (int)screenTopLeftCornerToWorldCoords.X / level.TileWidth;
            int topTileYIndex = (int)screenTopLeftCornerToWorldCoords.Y / level.TileHeight;

            int ammountOfTilesWidthOnScreen  = (int)(Graphics.PreferredBackBufferWidth / camera.Zoom / level.TileWidth);
            int ammountOfTilesHeightOnScreen = (int)(Graphics.PreferredBackBufferHeight / camera.Zoom / level.TileHeight);

            for (int y = topTileYIndex; y < ammountOfTilesHeightOnScreen + topTileYIndex; y++)
            {
                for (int x = topTileXIndex; x < ammountOfTilesWidthOnScreen + topTileXIndex; x++)
                {
                    // layer 1 is the one we are using for collisions
                    if (y >= 0 && y < level.Layers[1].TileMap.GetLength(0) &&
                        x >= 0 && x < level.Layers[1].TileMap.GetLength(1))
                    {
                        Tile currentTile = level.Layers[1].TileMap[y, x];

                        if (currentTile == null)
                        {
                            continue;
                        }

                        if (!currentTile.Body.Enabled)
                        {
                            continue;
                        }

                        // collide player projectiles

                        foreach (Bullet b in player.Bullets)
                        {
                            if (b.Alive)
                            {
                                if (Physics.Overlap(b, currentTile))
                                {
                                    b.Kill();
                                }
                            }
                        }

                        // enemies projectiles

                        foreach (Sprite p in enemies)
                        {
                            if (p.Alive)
                            {
                                if (p.GetType() == typeof(PufferFish))
                                {
                                    PufferFish puf = (PufferFish)p;

                                    foreach (Bullet b in puf.Bullets)
                                    {
                                        if (b.Alive)
                                        {
                                            if (Physics.Overlap(b, currentTile))
                                            {
                                                b.Kill();
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            // apply player velocities and collide
            // in order to avoid wall sticking
            // it's necessary to first move in x
            // and solve and then move in y and solve again

            #region [Player World Collisions]

            bool cameraShakeResponse = false;

            player.Body.PreCollisionUpdate(gameTime);
            player.Body.PreMovementUpdate(gameTime);

            // apply x velocity
            player.Body.X += player.Body.Velocity.X;

            for (int y = topTileYIndex; y < ammountOfTilesHeightOnScreen + topTileYIndex; y++)
            {
                for (int x = topTileXIndex; x < ammountOfTilesWidthOnScreen + topTileXIndex; x++)
                {
                    // layer 1 is the one we are using for collisions
                    int xLength = level.Layers[1].TileMap.GetLength(1);
                    int yLength = level.Layers[1].TileMap.GetLength(0);

                    if (y >= 0 && y < yLength &&
                        x >= 0 && x < xLength)
                    {
                        Tile currentTile = level.Layers[1].TileMap[y, x];

                        if (currentTile == null)
                        {
                            continue;
                        }

                        if (!currentTile.Body.Enabled)
                        {
                            continue;
                        }

                        // solve x collisions
                        Physics.Collide(player, currentTile, 0); // collide in x
                    }
                }
            }

            // apply y velocity
            player.Body.Y += player.Body.Velocity.Y;

            for (int y = topTileYIndex; y < ammountOfTilesHeightOnScreen + topTileYIndex; y++)
            {
                for (int x = topTileXIndex; x < ammountOfTilesWidthOnScreen + topTileXIndex; x++)
                {
                    // layer 1 is the one we are using for collisions
                    int xLength = level.Layers[1].TileMap.GetLength(1);
                    int yLength = level.Layers[1].TileMap.GetLength(0);

                    if (y >= 0 && y < yLength &&
                        x >= 0 && x < xLength)
                    {
                        Tile currentTile = level.Layers[1].TileMap[y, x];

                        if (currentTile == null)
                        {
                            continue;
                        }

                        if (!currentTile.Body.Enabled)
                        {
                            continue;
                        }

                        // solve y collisions
                        bool collided = Physics.Collide(player, currentTile, 1); // collide in y

                        //if the player was moving down:
                        if (collided && player.Body.MovingDown)
                        {
                            cameraShakeResponse = true;
                            SoundEffect fall;
                            SFX.TryGetValue("fall", out fall);
                            fall?.Play();
                        }
                    }
                }
            }

            // bound to world
            if (player.Body.Y < -16f)
            {
                player.Body.Y = -16f;
            }

            player.Body.Update(gameTime);

            #endregion


            //bool cameraShakeResponse = player.UpdateCollisions(gameTime, level);

            RepositionOutOfBoundsPlayer(gameTime);

            #endregion

            /*
             * Particle Emitters, background assets, UI, etc..
             */
            #region [ Secondary Assets ]

            // water waves
            float count = 1f;
            foreach (Tile t in topWaterTiles)
            {
                float x          = (float)gameTime.TotalGameTime.TotalMilliseconds;
                float phaseShift = (count / 30) * (float)Math.PI * 19.7f;
                float freq       = 0.005f;
                float amp        = 1f;

                // low freq motion, sin wave 1
                t.Body.Y = Math2.SinWave((x * freq - phaseShift), amp);

                count++;
            }

            foreach (ParticleEmitter p in backgroundParticles)
            {
                p.Update(gameTime);
                p.ForEachParticle(KillOutOfBoundsParticle);
            }

            foreach (GoldFish g in goldenFishs)
            {
                if (g.Alive)
                {
                    g.Update(gameTime);

                    if (Physics.Overlap(g, player) & g.Alive)
                    {
                        g.Kill();
                        Karma.AddCollectable();

                        SoundEffect gold;
                        SFX.TryGetValue("goldenFish", out gold);
                        gold?.Play(1f, 0f, 0f);
                    }
                }
            }

            energyBar.SetPercent((int)(player.Energy * 100f / player.MaxEnergy));
            //healthBar.SetPercent((int)(player.Health * 100f / player.MaxHealth));

            if (cameraShakeResponse && !camera.Shaking)
            {
                //camera.ActivateShake(gameTime, 250f, 4f, 0.05f, true, 0.01f); // static
                camera.ActivateShake(gameTime, 250f, Math.Abs(player.Body.DeltaY()) * 3, 0.05f, true, 0.01f); // based on delta
                //Console.WriteLine(Math.Abs(player.Body.DeltaY()));
            }

            camera.Position = new Vector2(player.Body.Position.X + player.Body.Bounds.HalfWidth, player.Body.Position.Y + player.Body.Bounds.HalfHeight);

            // clamp camera position
            float halfscreenwidth  = Graphics.PreferredBackBufferWidth / 2f;
            float halfscreenheight = Graphics.PreferredBackBufferHeight / 2f;
            camera.Position.X = MathHelper.Clamp(camera.Position.X, halfscreenwidth / camera.Zoom, (level.Width * level.TileWidth) - (halfscreenwidth / camera.Zoom));
            camera.Position.Y = MathHelper.Clamp(camera.Position.Y, -1000f, (level.Height * level.TileHeight) - (halfscreenheight / camera.Zoom));

            camera.Update(gameTime, Graphics.GraphicsDevice);

            Vector2 screenTopLeftCornerToWorldCoords2 = camera.GetScreenToWorldPosition(Vector2.Zero);

            camera.Bounds.X = screenTopLeftCornerToWorldCoords2.X + 16f;
            camera.Bounds.Y = screenTopLeftCornerToWorldCoords2.Y + 16f;

            // build loop on only the visible tiles

            //Vector2 screenTopLeftCornerToWorldCoords = camera.GetScreenToWorldPosition(Vector2.Zero);

            //int topTileXIndex = (int)screenTopLeftCornerToWorldCoords.X / level.TileWidth;
            //int topTileYIndex = (int)screenTopLeftCornerToWorldCoords.Y / level.TileHeight;

            //int ammountOfTilesWidthOnScreen = (int)(Graphics.PreferredBackBufferWidth / camera.Zoom / level.TileWidth);
            //int ammountOfTilesHeightOnScreen = (int)(Graphics.PreferredBackBufferHeight / camera.Zoom / level.TileHeight);

            //for (int y = topTileYIndex; y < ammountOfTilesHeightOnScreen + topTileYIndex; y++)
            //{

            //    for (int x = topTileXIndex; x < ammountOfTilesWidthOnScreen + topTileXIndex; x++)
            //    {

            //        // layer 1 is the one we are using for collisions
            //        if(y >= 0 && y < level.Layers[1].TileMap.GetLength(0) &&
            //           x >= 0 && x < level.Layers[1].TileMap.GetLength(1))
            //        {

            //            if(level.Layers[1].TileMap[y, x] != null)
            //            {
            //                level.Layers[1].TileMap[y, x].Tint = new Color(0, 240, 0, 240);
            //            }

            //        }

            //    }

            //}


            #endregion

            /*
             * Game resolution
             */
            #region [ Game Resolution and other checks ]

            if (!player.Alive)
            {
                SoundEffect death;
                SFX.TryGetValue("playerDeath", out death);
                death?.Play(0.5f, 0f, 0f);

                // show end game screen
                // now we will just restart this state
                StateManager.Instance.StartGameState("KarmaScreenState");

                // reboot this level
                //StateManager.Instance.StartGameState(this.Key);

                return;
            }

            foreach (Trigger t in triggers)
            {
                if (Physics.Overlap(player.Body.Bounds, t))
                {
                    MediaPlayer.Play(Globals.JingleSong);

                    Globals.CurrentLevel = t.Value;

                    StateManager.Instance.StartGameState("KarmaScreenState");

                    return;
                }
            }

            #endregion

            //stopwatch.Stop();

            //++tickCount;

            //sumOfMilliseconds += stopwatch.Elapsed.TotalMilliseconds;
            //averageMilliseconds = sumOfMilliseconds / tickCount;

            //maxMills = stopwatch.Elapsed.TotalMilliseconds > maxMills && tickCount > 20 ? stopwatch.Elapsed.TotalMilliseconds : maxMills;
            //minMills = stopwatch.Elapsed.TotalMilliseconds < minMills && tickCount > 20 ? stopwatch.Elapsed.TotalMilliseconds : minMills;

            //Console.WriteLine(
            //    $"RealTime: {stopwatch.Elapsed.TotalMilliseconds:0.0000}, Avg: {averageMilliseconds:0.0000}, Min: {minMills}, Max: {maxMills} "
            //);
        }