Beispiel #1
0
        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();
            }
        }