public void Update() { updateCount++; if (grabbed) { // Snap to player position.X = Game1.currentRoom.Runner.movedLeft ? Game1.currentRoom.Runner.hitBox.Left - 16 : Game1.currentRoom.Runner.hitBox.Right - 16; position.Y = (int)Game1.currentRoom.Runner.position.Y + 24; UpdateHitBox(); } else { // Update position and velocity velocity += acceleration; position += velocity; if (platform != null) position += platform.velocity; UpdateHitBox(); // Wall collisions platform = null; foreach (Wall w in Game1.currentRoom.Walls) { if (w is PlatformWall) continue; if (w is FloatingPlatform && this.groundBox.Intersects(w.Bounds)) { if (groundBox.Intersects(w.Bounds)) platform = (FloatingPlatform)w; } if (this.hitBox.Intersects(w.Bounds)) { List<Vector2> resolutions = new List<Vector2>(); // Resolve Y if (!(this.hitBox.Bottom <= w.Bounds.Top || this.hitBox.Top >= w.Bounds.Bottom)) { if (this.hitBox.Top < w.Bounds.Bottom) resolutions.Add(new Vector2(0, w.Bounds.Bottom - this.hitBox.Top)); if (this.hitBox.Bottom > w.Bounds.Top) resolutions.Add(new Vector2(0, w.Bounds.Top - this.hitBox.Bottom)); } // Resolve X if (!(this.hitBox.Right <= w.Bounds.Left || this.hitBox.Left >= w.Bounds.Right)) { if (this.hitBox.Right > w.Bounds.Left) resolutions.Add(new Vector2(w.Bounds.Left - this.hitBox.Right, 0)); if (this.hitBox.Left < w.Bounds.Right) resolutions.Add(new Vector2(w.Bounds.Right - this.hitBox.Left, 0)); } // Find smallest overlap while (resolutions.Count > 1) { if (resolutions[0].Length() > resolutions[1].Length()) resolutions.RemoveAt(0); else resolutions.RemoveAt(1); } // Set new velocity and position Vector2 resV = resolutions[0]; if (resV.X != 0) { if (resV.X > 0 && velocity.X < 0 || resV.X < 0 && velocity.X > 0) { if (w is DeathWall) { velocity = Vector2.Zero; position = startPosition; } else this.velocity.X = 0; } } else { if (resV.Y > 0 && velocity.Y < 0 || resV.Y < 0 && velocity.Y > 0) { if (w is DeathWall) { velocity = Vector2.Zero; position = startPosition; } else { this.velocity.Y = 0; float temp = this.velocity.X; this.velocity.X += Math.Sign(velocity.X) * -1 * 0.5f; if (Math.Sign(temp) != Math.Sign(velocity.X)) velocity.X = 0; } } } this.position += resV; UpdateHitBox(); } } // Box collisions foreach (Box b in Game1.currentRoom.Boxes) { if (this == b) continue; if (this.groundBox.Intersects(b.hitBox)) { this.position.Y = b.position.Y - 32; this.position.X += b.velocity.X; this.velocity.Y = 0; float temp = this.velocity.X; this.velocity.X += Math.Sign(velocity.X) * -1 * 0.5f; if (Math.Sign(temp) != Math.Sign(velocity.X)) velocity.X = 0; if (b.platform != null && this.platform == null) this.platform = b.platform; UpdateHitBox(); } } // Used to block platforms crushed = false; foreach (Wall w in Game1.currentRoom.Walls) { if (!(w is PlatformWall) && this.hitBox.Intersects(w.Bounds)) { crushed = true; break; } } foreach (Box b in Game1.currentRoom.Boxes) { if (this.groundBox.Intersects(b.hitBox)) { crushed = true; break; } } // Send back to starting position if fallen off screen if (this.position.Y > Game1.currentRoom.roomHeight) { velocity = Vector2.Zero; position = startPosition; } UpdateHitBox(); } }
public void Update() { // Update animation current.Update(); // Update health regen if (health < 10 && health > 0) { healthTracker++; if (healthTracker >= HEALTHINTERVAL) { healthTracker = 0; health++; } } else healthTracker = 0; if (health > 10) health = 10; // If something is slowing you down, stop it from speeding you up in the opposite direction if (Math.Sign(velocity.X + acceleration.X) != Math.Sign(velocity.X) && velocity.X != 0) { acceleration.X = 0; velocity.X = 0; } else { // Cap speed if (Math.Abs(velocity.X + acceleration.X) < 8.0f || velocity.X * acceleration.X < 0) velocity.X += acceleration.X; } // Apply accel to velocity and velocity to position velocity.Y += acceleration.Y; position += velocity; if (platform != null) { // Fix retarded platform switching direction and making you spazz out glitch if (!(Math.Sign(platform.velocity.Y) != Math.Sign(prevPlatSpeed) && prevPlatSpeed > 0)) position += platform.velocity; prevPlatSpeed = platform.velocity.Y; } UpdateHitBox(); // Stay inside screen if (hitBox.Left < 0) { velocity.X = 0; position.X = -16; UpdateHitBox(); } else if (hitBox.Right > Game1.currentRoom.roomWidth) { velocity.X = 0; position.X = Game1.currentRoom.roomWidth - 48; UpdateHitBox(); } // Die if character falls below room bounds if (hitBox.Top > Game1.currentRoom.roomHeight) health = 0; // Reset flags isTouchingGround = false; isTouchingWall = false; bool isOnPlatform = false; // Iterate through walls foreach (Wall w in Game1.currentRoom.Walls) { // Make sure wall effects player if (w is PlatformWall || (!w.Bounds.Intersects(Game1.currentRoom.ViewBox) && !Game1.currentRoom.Freeroam)) continue; // If you're standing on it, apply ground friction and say that you're standing if (isSliding && !(w is DeathWall)) { if (w.Bounds.Intersects(groundHitBox)) { isZipping = false; isTouchingGround = true; if (w is FloatingPlatform) { if (platform == null) { platform = (FloatingPlatform)w; if (Game1.currentRoom.recorder.playing ? !Game1.currentRoom.recorder.keystates[Settings.controls["MoveLeft"]] && !Game1.currentRoom.recorder.keystates[Settings.controls["MoveRight"]] : !Keyboard.GetState().IsKeyDown(Settings.controls["MoveLeft"]) && !Keyboard.GetState().IsKeyDown(Settings.controls["MoveRight"])) velocity.X = 0; } isOnPlatform = true; } } else if (w.Bounds.Intersects(leftWallBox) && !(w is Mirror)) { canWallToRight = true; isTouchingWall = true; } else if (w.Bounds.Intersects(rightWallBox) && !(w is Mirror)) { canWallToLeft = true; isTouchingWall = true; } } // Apply other wall collisions if (this.hitBox.Intersects(w.Bounds)) { List<Vector2> resolutions = new List<Vector2>(); // Resolve Y if (!(this.hitBox.Bottom <= w.Bounds.Top || this.hitBox.Top >= w.Bounds.Bottom)) { if (this.hitBox.Top < w.Bounds.Bottom) resolutions.Add(new Vector2(0, w.Bounds.Bottom - this.hitBox.Top)); if (this.hitBox.Bottom > w.Bounds.Top) resolutions.Add(new Vector2(0, w.Bounds.Top - this.hitBox.Bottom)); } // Resolve X if (!(this.hitBox.Right <= w.Bounds.Left || this.hitBox.Left >= w.Bounds.Right)) { if (this.hitBox.Right > w.Bounds.Left) resolutions.Add(new Vector2(w.Bounds.Left - this.hitBox.Right, 0)); if (this.hitBox.Left < w.Bounds.Right) resolutions.Add(new Vector2(w.Bounds.Right - this.hitBox.Left, 0)); } // Find smallest overlap while (resolutions.Count > 1) { if (resolutions[0].Length() > resolutions[1].Length()) resolutions.RemoveAt(0); else resolutions.RemoveAt(1); } // Set new velocity and position Vector2 resV = resolutions[0]; if (resV.X != 0) { if (resV.X > 0 && velocity.X < 0 || resV.X < 0 && velocity.X > 0) { if (w is DeathWall && health > 0) { Game1.damage.Play(0.5f * Settings.soundVol, 0f, 0f); this.velocity.X = Math.Sign(velocity.X) * -6; health -= 9; } else this.velocity.X = 0; } } else { if (resV.Y > 0 && velocity.Y < 0 || resV.Y < 0 && velocity.Y > 0) { if (w is DeathWall && health > 0) { Game1.damage.Play(0.5f * Settings.soundVol, 0f, 0f); this.velocity.Y = Math.Sign(velocity.Y) * -6; health -= 9; } else { if (Math.Abs(this.velocity.Y) >= 3) Game1.collide.Play(0.3f * Settings.soundVol, 0f, 0f); this.velocity.Y = 0; } } } this.position += resV; UpdateHitBox(); } // If you're standing on it, apply ground friction and say that you're standing if (!isSliding) { if (w.Bounds.Intersects(groundHitBox)) { isZipping = false; isTouchingGround = true; if (w is FloatingPlatform) { if (platform == null) { platform = (FloatingPlatform)w; if (Game1.currentRoom.recorder.playing ? !Game1.currentRoom.recorder.keystates[Settings.controls["MoveLeft"]] && !Game1.currentRoom.recorder.keystates[Settings.controls["MoveRight"]] : !Keyboard.GetState().IsKeyDown(Settings.controls["MoveLeft"]) && !Keyboard.GetState().IsKeyDown(Settings.controls["MoveRight"])) velocity.X = 0; } isOnPlatform = true; } groundFriction.X = Math.Sign(velocity.X) * -1 * 0.5f; } else if (w.Bounds.Intersects(leftWallBox) && !(w is Mirror)) { canWallToRight = true; isTouchingWall = true; } else if (w.Bounds.Intersects(rightWallBox) && !(w is Mirror)) { canWallToLeft = true; isTouchingWall = true; } } } // Land on boxes if (velocity.Y > 0 && !isTouchingGround) { foreach (Box b in Game1.currentRoom.Boxes) { if (groundHitBox.Intersects(b.hitBox) && groundHitBox.Y < b.hitBox.Y + 12) { position.Y = b.position.Y - 64; velocity.Y = 0; if (b.platform != null) { if (platform == null) { platform = b.platform; if (Game1.currentRoom.recorder.playing ? !Game1.currentRoom.recorder.keystates[Settings.controls["MoveLeft"]] && !Game1.currentRoom.recorder.keystates[Settings.controls["MoveRight"]] : !Keyboard.GetState().IsKeyDown(Settings.controls["MoveLeft"]) && !Keyboard.GetState().IsKeyDown(Settings.controls["MoveRight"])) velocity.X = 0; } isOnPlatform = true; } if (!isSliding) groundFriction.X = Math.Sign(velocity.X) * -1 * 0.5f; else groundFriction.X = 0; isTouchingGround = true; } } } // Check for crushing bool iscrushed = false; foreach (Wall w in Game1.currentRoom.Walls) { if (!(w is PlatformWall) && this.hitBox.Intersects(w.Bounds)) { if (!(isSliding || staySliding)) { staySliding = true; break; } crushCount++; if (crushCount >= 3) health = 0; iscrushed = true; break; } } if (!iscrushed) crushCount = 0; if (health <= 0) controllable = false; // Apply platform velocity when leaving platform if (!isOnPlatform && platform != null) { velocity += platform.velocity; platform = null; } // Apply booster acceleration foreach (Booster b in Game1.currentRoom.Boosters) if (b.HitBox.Intersects(this.hitBox)) { Game1.boost.Play(0.5f * Settings.soundVol, 0f, 0f); velocity += b.Acceleration; } // Check for rocket collision foreach (RocketLauncher r in Game1.currentRoom.Launchers) if (r.rocket.hitBox.Intersects(this.hitBox)) { this.health -= 6; this.velocity += r.rocket.velocity * 1.5f; } // Check for fire collision foreach (Flamethrower f in Game1.currentRoom.Flamethrowers) { bool brk = false; foreach (Flamethrower.Flame fl in f.flames) { if (!fl.drawBox.Intersects(Game1.currentRoom.ViewBox)) continue; if (fl.drawBox.Intersects(this.hitBox)) { health -= 0.6f; velocity += fl.velocity * 0.06f; brk = true; break; } } if (brk) break; } // Check if level finish reached if (Game1.currentRoom.Finish != null && !Game1.currentRoom.Finished) if (this.hitBox.Intersects(Game1.currentRoom.Finish.HitBox)) { Game1.finish.Play(Settings.soundVol, 0f, 0f); Game1.currentRoom.Finished = true; } // Remove ground friction if midair if (!isTouchingGround) { Game1.run.Stop(); if (health <= 0) current = deadMidair; else current = midair; groundFriction = Vector2.Zero; } else { // Change to normal animation if standing still if (health <= 0) current = deadGround; else if (velocity.X == 0) current = normal; } // Reset space key if (Game1.currentRoom.recorder.playing ? !Game1.currentRoom.recorder.keystates[Settings.controls["Jump"]] : !Keyboard.GetState().IsKeyDown(Settings.controls["Jump"])) { if (heldBox != null) jumppresscheck = false; if (isTouchingGround) jumppresscheck = false; else if (canWallToLeft || canWallToRight) wallpresscheck = false; } if ((Game1.currentRoom.recorder.playing ? Game1.currentRoom.recorder.keystates[Settings.controls["Jump"]] : Keyboard.GetState().IsKeyDown(Settings.controls["Jump"])) && controllable) { // Jumping if (isTouchingGround && !staySliding && !jumppresscheck) { Game1.jump.Play(Settings.soundVol, 0f, 0f); velocity.Y = -10.0f; current = midair; isTouchingGround = false; jumppresscheck = true; wallpresscheck = true; } // Wall jumping else if (!wallpresscheck && !isTouchingGround && isTouchingWall) { Game1.jump.Play(Settings.soundVol, 0f, 0f); velocity.X = canWallToRight ? 8 : -8; movedLeft = !movedLeft; if (velocity.Y > -7.5f) velocity.Y = -7.5f; wallpresscheck = true; jumppresscheck = true; canWallToRight = false; canWallToLeft = false; } // Box jumping else if (heldBox != null && !isTouchingGround && !jumppresscheck) { Game1.jump.Play(Settings.soundVol, 0f, 0f); velocity.Y = -10.0f; current = midair; jumppresscheck = true; wallpresscheck = true; heldBox.velocity.Y = 4; heldBox.velocity.X = this.velocity.X; heldBox.grabbed = false; heldBox = null; } } // If ziplining, update according to zipline's values if (zippingLine != null) { current = ziplining; position.Y = zippingLine.GetY(ziplineBox.Center.X); acceleration = zippingLine.Acceleration * (Math.Abs(zippingLine.Slope) > 1.5f ? 1 : 3); velocity = zippingLine.GetNewVelocity(velocity); movedLeft = velocity.X < 0; } // Check for whether or not ziplining if control is being held if ((Game1.currentRoom.recorder.playing ? Game1.currentRoom.recorder.keystates[Settings.controls["Slide"]] : Keyboard.GetState().IsKeyDown(Settings.controls["Slide"])) && controllable && !isTouchingGround) { bool zipping = false; foreach (ZipLine z in Game1.currentRoom.ZipLines) { if ((z.pos1.X < z.pos2.X ? (ziplineBox.Left >= z.pos1.X && ziplineBox.X <= z.pos2.X) : (ziplineBox.Left <= z.pos1.X && ziplineBox.X >= z.pos2.X)) && ziplineBox.Contains(ziplineBox.Center.X, (int)z.GetY(ziplineBox.Center.X))) { zipping = true; isZipping = true; if (zippingLine == null) { zippingLine = z; current = ziplining; position.Y = z.GetY(ziplineBox.Center.X); acceleration = z.Acceleration * 3; velocity = z.GetNewVelocity(velocity); movedLeft = velocity.X < 0; } break; } } // If not hitting a zipline, turn off zipling variables if (!zipping) { zippingLine = null; isZipping = false; acceleration.Y = 0.4f; } } else { zippingLine = null; isZipping = false; acceleration.Y = 0.4f; } // Check for picking up boxes if (Game1.currentRoom.recorder.playing ? Game1.currentRoom.recorder.keystates[Settings.controls["Box"]] : Keyboard.GetState().IsKeyDown(Settings.controls["Box"])) { if (isTouchingGround && heldBox == null) foreach (Box b in Game1.currentRoom.Boxes) { if (b.hitBox.Intersects(rightWallBox) && !movedLeft || b.hitBox.Intersects(leftWallBox) && movedLeft) { b.grabbed = true; heldBox = b; break; } } } else { if (heldBox != null) { heldBox.grabbed = false; heldBox.velocity = this.velocity; heldBox = null; } } // Slide when holding control isSliding = ((Game1.currentRoom.recorder.playing ? Game1.currentRoom.recorder.keystates[Settings.controls["Slide"]] : Keyboard.GetState().IsKeyDown(Settings.controls["Slide"])) || staySliding) && controllable && isTouchingGround; // Don't get up if sliding under low ceiling bool flag = true; if (isSliding || staySliding) { foreach (Wall w in Game1.currentRoom.Walls) { if (w.Bounds.Left < hitBox.Right && w.Bounds.Right > hitBox.Left && w.Bounds.Bottom + 32 > hitBox.Top && w.Bounds.Top < hitBox.Top) { staySliding = true; flag = false; break; } } } if (flag) staySliding = false; // Move right if ((Game1.currentRoom.recorder.playing ? Game1.currentRoom.recorder.keystates[Settings.controls["MoveRight"]] : Keyboard.GetState().IsKeyDown(Settings.controls["MoveRight"])) && !isSliding && !isZipping && controllable) { canWallToRight = false; acceleration.X = isTouchingGround ? 1.0f : 0.5f; movedLeft = false; if (isTouchingGround) current = running; if (Game1.currentRoom.recorder.playing ? Game1.currentRoom.recorder.keystates[Settings.controls["MoveLeft"]] : Keyboard.GetState().IsKeyDown(Settings.controls["MoveLeft"])) { acceleration.X = 0.0f; movedLeft = true; current = normal; } } // Move left else if ((Game1.currentRoom.recorder.playing ? Game1.currentRoom.recorder.keystates[Settings.controls["MoveLeft"]] : Keyboard.GetState().IsKeyDown(Settings.controls["MoveLeft"])) && !isSliding && !isZipping && controllable) { canWallToLeft = false; acceleration.X = isTouchingGround ? -1.0f : -0.5f; movedLeft = true; if (isTouchingGround) current = running; } // Slow down if no keys are being held else acceleration.X = 0.0f; if (Math.Abs(velocity.X) > 8.0f && !isSliding && isTouchingGround) { if (acceleration.X < 0 && velocity.X < 0) velocity.X++; else if (acceleration.X > 0 && velocity.X > 0) velocity.X--; } // Set sliding animation if sliding if (isSliding && isTouchingGround) { canWallToLeft = false; canWallToRight = false; acceleration.X = 0.0f; groundFriction.X = 0.0f; current = sliding; } // Apply ground friction to horizontal acceleration acceleration.X += groundFriction.X; // Update midair animation based on vertical speed int midairFrame = (int)velocity.Y * 2 + 3; if (midairFrame < 0) midairFrame = 0; if (midairFrame > 8) midairFrame = 8; midair.Frame = midairFrame; // Play sounds if (current == running) { Game1.slide.Stop(); if (Game1.run.State != SoundState.Playing) Game1.run.Play(); } else if (current == ziplining || current == sliding) { Game1.run.Stop(); if (Game1.slide.State != SoundState.Playing && velocity.X != 0) Game1.slide.Play(); } else { Game1.run.Stop(); Game1.slide.Stop(); } }