public void Update(GameTime gameTime) { List <Entity> garbageEntities = new List <Entity>(); //Update static entities foreach (Entity e in Entities) { if (!e.Active) { garbageEntities.Add(e); } if (e is CoinPickup) { CoinPickup c = (CoinPickup)e; c.Update(gameTime); } if (e is HealthPickup) { HealthPickup h = (HealthPickup)e; h.Update(gameTime); } } foreach (Entity e in Traps) { if (e is SpearTrap) { SpearTrap s = (SpearTrap)e; s.Update(gameTime); } if (e is TurretEnemy) { TurretEnemy t = (TurretEnemy)e; t.Update(gameTime); } } foreach (Entity e in garbageEntities) { Entities.Remove(e); } }
/// <summary> /// Updates player collision and input states. /// </summary> /// <param name="gameTime">Provides a snapshot of timing values.</param> /// <param name="keyboardState">Provides a snapshot of inputs.</param> /// <param name="prevKeyboardState">Provides a snapshot of the previous frame's inputs.</param> public void Update(GameTime gameTime, KeyboardState keyboardState, KeyboardState prevKeyboardState) { float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds; Alive = Game1.PlayerStats.IsAlive; previousChunk = Game1.Generator.GetEntityChunkID(new Vector2(Position.X - 3 * Game1.TILE_SIZE, Position.Y)); nextChunk = Game1.Generator.GetEntityChunkID(new Vector2(Position.X + 3 * Game1.TILE_SIZE, Position.Y)); //Check collision booleans Grounded = CheckCardinalCollision(new Vector2(0, 3), CurrentChunk); if (nextChunk != null && nextChunk != CurrentChunk && Rect.X + Rect.Width > nextChunk.Rect.Left) { walledLeft = CheckCardinalCollision(new Vector2(-6, 0), CurrentChunk) || CheckCardinalCollision(new Vector2(-6, 0), nextChunk); } else { walledLeft = CheckCardinalCollision(new Vector2(-6, 0), CurrentChunk); } if (previousChunk != null && previousChunk != CurrentChunk && Rect.X < previousChunk.Rect.Right) { walledRight = CheckCardinalCollision(new Vector2(6, 0), CurrentChunk) || CheckCardinalCollision(new Vector2(6, 0), previousChunk); } else { walledRight = CheckCardinalCollision(new Vector2(6, 0), CurrentChunk); } Walled = walledLeft || walledRight; //Determine canStartJump states (Yes, this is necessary) isJumping = (keyboardState.IsKeyDown(Keys.Space) || keyboardState.IsKeyDown(Keys.W) || keyboardState.IsKeyDown(Keys.Up)); canStartJump = (keyboardState.IsKeyDown(Keys.Space) || keyboardState.IsKeyDown(Keys.W) || keyboardState.IsKeyDown(Keys.Up)) && !(prevKeyboardState.IsKeyDown(Keys.Space) || prevKeyboardState.IsKeyDown(Keys.W) || prevKeyboardState.IsKeyDown(Keys.Up)) && !wallJumped; if (canStartJump && Grounded) { Sound.PlayerJump.Play(); MakeJumpParticles(new Vector2(0, 1)); } else if (canStartJump && Walled) { Sound.PlayerWallJump.Play(); } if (!Alive) { Walled = false; canStartJump = false; } //Stuff that happens when you hit the ground if (!Grounded && !Walled) { airTime += elapsed; } else if (Grounded && velocity.Y >= maxFallSpeed / 4) { Game1.Camera.ScreenShake(airTime * 7.5f, airTime * 1.5f); airTime = 0; if (velocity.Y > 1000) { MakeJumpParticles(new Vector2(0, 2), 10); Sound.PlayerLandHard.Play(); } else { MakeJumpParticles(new Vector2(0, 1), 2); Sound.PlayerLandSoft.Play(); } } else if (Grounded && !Walled) { airTime = 0; } else { airTime = 0; } //At the apex if (previousVelocity.Y < 0 && (velocity.Y > 0 || velocity.Y == 0)) { airTime = 0; } if (Walled && !wallJumped) { maxFallSpeed = 125; } else { maxFallSpeed = 1500; } //Apply the physics ApplyPhysics(gameTime, keyboardState); //Clear the jumping state isJumping = false; //Create particles if necessary, also do some sound stuff dynamicParticleTimer += elapsed; particleTimer += elapsed; if (particleTimer >= particleFrequency) { bool canSpawnBottom = CollisionHelper.IsCollidingWithChunk(CurrentChunk, new Rectangle(Rect.X, Rect.Center.Y, 1, Rect.Height / 2 + 1)) && CollisionHelper.IsCollidingWithChunk(CurrentChunk, new Rectangle(Rect.Right, Rect.Center.Y, 1, Rect.Height / 2 + 1)); bool canSpawnLeft = CollisionHelper.IsCollidingWithChunk(CurrentChunk, new Rectangle(Rect.Center.X - (Rect.Width / 2 + 1), Rect.Top, Rect.Width / 2 + 1, 1)) && CollisionHelper.IsCollidingWithChunk(CurrentChunk, new Rectangle(Rect.Center.X - (Rect.Width / 2 + 1), Rect.Bottom, Rect.Width / 2 + 1, 1)); bool canSpawnRight = CollisionHelper.IsCollidingWithChunk(CurrentChunk, new Rectangle(Rect.Center.X, Rect.Top, Rect.Width / 2 + 1, 1)) && CollisionHelper.IsCollidingWithChunk(CurrentChunk, new Rectangle(Rect.Center.X, Rect.Bottom, Rect.Width / 2 + 1, 1)); if ((canSpawnLeft || canSpawnRight) && velocity.Y != 0) { if (wallSlideSound.State == SoundState.Stopped) { wallSlideSound.Play(); } Game1.Camera.ScreenShake(0.5f, 0.25f); } else { wallSlideSound.Stop(); } if (canSpawnBottom && velocity.X != 0) { if (walkSound.State == SoundState.Stopped) { walkSound.Play(); } } else { walkSound.Stop(); } if (Grounded && canSpawnBottom && velocity.X != 0) { if (!IsTouchingTile(18)) { particles.Add(new Particle(Graphics.Effect_PlayerParticlesBottom[Game1.RandomObject.Next(0, Graphics.Effect_PlayerParticlesBottom.Length)], new Vector2(Position.X, Position.Y + Game1.PIXEL_SCALE * 7), particleLifetime + (float)Game1.RandomObject.NextDouble() * particleLifetime)); } if (dynamicParticleTimer >= dynamicParticleFrequency) { MakeJumpParticles(new Vector2(0, 1), 2); } } else if (walledLeft && canSpawnLeft && velocity.Y != 0) { if (!IsTouchingTile(18)) { particles.Add(new Particle(Graphics.Effect_PlayerParticlesLeft[Game1.RandomObject.Next(0, Graphics.Effect_PlayerParticlesLeft.Length)], new Vector2(Position.X - Game1.PIXEL_SCALE * 2, Position.Y), particleLifetime + (float)Game1.RandomObject.NextDouble() * particleLifetime)); } if (dynamicParticleTimer >= dynamicParticleFrequency) { MakeJumpParticles(new Vector2(1, 0), 2); } } else if (walledRight && canSpawnRight && velocity.Y != 0) { if (!IsTouchingTile(18)) { particles.Add(new Particle(Graphics.Effect_PlayerParticlesRight[Game1.RandomObject.Next(0, Graphics.Effect_PlayerParticlesRight.Length)], new Vector2(Position.X + Game1.PIXEL_SCALE * 4, Position.Y), particleLifetime + (float)Game1.RandomObject.NextDouble() * particleLifetime)); } if (dynamicParticleTimer >= dynamicParticleFrequency) { MakeJumpParticles(new Vector2(-1, 0), 2); } } particleTimer = 0; } //Update positions of sticky projectiles foreach (Bullet b in stickies) { if (prevFacing != facing) { b.Flip(); } b.Position = (Center + b.relativePosition) + new Vector2((b.Position.X - b.Origin.X), 0); } for (int i = particles.Count - 1; i >= 0; i--) { particles[i].Update(gameTime); if (!particles[i].Active) { particles.Remove(particles[i]); } } //Collect coins if necessary if (CurrentChunk != null) { foreach (Entity e in CurrentChunk.Entities) { if (e is CoinPickup) { CoinPickup c = (CoinPickup)e; if (c != null && Rect.Intersects(c.Rect)) { c.Collect(); } } else if (e is HealthPickup) { HealthPickup hp = (HealthPickup)e; if (hp != null && Rect.Intersects(hp.Rect)) { hp.Collect(); } } } foreach (Entity e in CurrentChunk.Traps) { if (e is SpearTrap) { SpearTrap s = (SpearTrap)e; //If the player is touching this spike... if (s != null && Rect.Intersects(s.Rect)) { //Take damage Game1.PlayerStats.TakeDamage(1, s); } } else if (e is Spike) { Spike s = (Spike)e; //If the player is touching this spike... if (s != null && Rect.Intersects(s.HitRectangle)) { //Take damage Game1.PlayerStats.TakeDamage(1, s); } } } } ResolveDynamicEntityCollisions(); }