From 459e43186ad9ca89a2704dffce3e248f3bc1ed15 Mon Sep 17 00:00:00 2001 From: Colin McMillen Date: Fri, 17 Jan 2020 21:07:32 -0500 Subject: [PATCH] refactor Player input/state handling to be less tangled GitOrigin-RevId: 68bd79b722d7fcf2ef8abaf644e2b13544a08ae8 --- Shared/Player.cs | 112 ++++++++++++++++++++--------------------------- 1 file changed, 47 insertions(+), 65 deletions(-) diff --git a/Shared/Player.cs b/Shared/Player.cs index 7d8cd86..3dab114 100644 --- a/Shared/Player.cs +++ b/Shared/Player.cs @@ -1,29 +1,27 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; -using System; using System.Collections.Generic; namespace SemiColinGames { class Player { - enum Facing { Left, Right }; enum Pose { Walking, Standing, Crouching, Stretching, SwordSwing, Jumping }; - enum AirState { Jumping, Ground, Falling }; + + private const int moveSpeed = 180; + private const int jumpSpeed = -600; + private const int gravity = 2400; private Texture2D texture; private const int spriteSize = 48; private const int spriteWidth = 7; - private const int moveSpeed = 180; - private const int jumpSpeed = 600; - private const int gravity = 2400; private Point position = new Point(64, 16); + private int jumps = 0; private Facing facing = Facing.Right; - private Pose pose = Pose.Standing; - private AirState airState = AirState.Ground; + private Pose pose = Pose.Jumping; private double swordSwingTime = 0; private double jumpTime = 0; - private double ySpeed = 0; + private float ySpeed = 0; public Player(Texture2D texture) { this.texture = texture; @@ -37,8 +35,8 @@ namespace SemiColinGames { public void Update(GameTime time, History input, List collisionTargets) { Point oldPosition = position; - AirState oldAirState = airState; - HandleInput(time, input); + Vector2 movement = HandleInput(time, input); + position = new Point((int) (oldPosition.X + movement.X), (int) (oldPosition.Y + movement.Y)); Rectangle oldBbox = Bbox(oldPosition); Rectangle playerBbox = Bbox(position); @@ -63,7 +61,7 @@ namespace SemiColinGames { int diff = playerBbox.Top - rect.Bottom; position.Y -= diff; } else { - airState = AirState.Ground; + standingOnGround = true; int diff = playerBbox.Bottom - rect.Top; position.Y -= diff; } @@ -77,72 +75,55 @@ namespace SemiColinGames { } } } - if (oldAirState != AirState.Ground && standingOnGround) { - airState = AirState.Ground; - ySpeed = 0.0; - } - if (airState == AirState.Ground && !standingOnGround) { - airState = AirState.Falling; - ySpeed = 0.0; - } - - if (airState == AirState.Ground) { + if (standingOnGround) { + jumps = 1; + ySpeed = 0; Debug.AddRect(playerBbox, Color.Red); - } else if (airState == AirState.Jumping) { - Debug.AddRect(playerBbox, Color.Orange); } else { - Debug.AddRect(playerBbox, Color.Yellow); - } - } - - void HandleInput(GameTime time, History input) { - if (input[0].Jump && !input[1].Jump && airState == AirState.Ground) { - pose = Pose.Jumping; - airState = AirState.Jumping; - jumpTime = 0.5; - ySpeed = -jumpSpeed; - return; + jumps = 0; + Debug.AddRect(playerBbox, Color.Orange); } - if (input[0].Attack && !input[1].Attack && swordSwingTime <= 0) { - pose = Pose.SwordSwing; - swordSwingTime = 0.3; - return; - } - - if (input[0].Motion.X < 0) { - facing = Facing.Left; - pose = Pose.Walking; - position.X -= (int) (moveSpeed * time.ElapsedGameTime.TotalSeconds); - } else if (input[0].Motion.X > 0) { + if (movement.X > 0) { facing = Facing.Right; + } else if (movement.X < 0) { + facing = Facing.Left; + } + if (swordSwingTime > 0) { + pose = Pose.SwordSwing; + } else if (jumps == 0) { + pose = Pose.Jumping; + } else if (movement.X != 0) { pose = Pose.Walking; - position.X += (int) (moveSpeed * time.ElapsedGameTime.TotalSeconds); - } else if (input[0].Motion.Y < 0) { - pose = Pose.Crouching; } else if (input[0].Motion.Y > 0) { pose = Pose.Stretching; + } else if (input[0].Motion.Y < 0) { + pose = Pose.Crouching; } else { pose = Pose.Standing; } + } + + // Returns the desired (dx, dy) for the player to move this frame. + Vector2 HandleInput(GameTime time, History input) { + Vector2 result = new Vector2(); + result.X = (int) (input[0].Motion.X * moveSpeed * time.ElapsedGameTime.TotalSeconds); - if (jumpTime > 0) { - jumpTime -= time.ElapsedGameTime.TotalSeconds; - } - if (swordSwingTime > 0) { - swordSwingTime -= time.ElapsedGameTime.TotalSeconds; - pose = Pose.SwordSwing; + if (input[0].Jump && !input[1].Jump && jumps > 0) { + jumpTime = 0.3; + jumps--; + ySpeed = jumpSpeed; } - if (airState == AirState.Jumping || airState == AirState.Falling) { - position.Y += (int) (ySpeed * time.ElapsedGameTime.TotalSeconds); - ySpeed += gravity * (float) time.ElapsedGameTime.TotalSeconds; + if (input[0].Attack && !input[1].Attack && swordSwingTime <= 0) { + swordSwingTime = 0.3; } - if (airState == AirState.Jumping && pose != Pose.SwordSwing) { - pose = Pose.Jumping; - } - - position.X = Math.Max(position.X, 0 + spriteWidth); + + result.Y = ySpeed * (float) time.ElapsedGameTime.TotalSeconds; + ySpeed += gravity * (float) time.ElapsedGameTime.TotalSeconds; + jumpTime -= time.ElapsedGameTime.TotalSeconds; + swordSwingTime -= time.ElapsedGameTime.TotalSeconds; + return result; } private int SpriteIndex(Pose pose, GameTime time) { @@ -156,9 +137,9 @@ namespace SemiColinGames { case Pose.Stretching: return 18 + frameNum; case Pose.Jumping: - if (jumpTime > 0.25) { + if (jumpTime > 0.2) { return 15; - } else if (jumpTime > 0) { + } else if (jumpTime > 0.1) { return 16; } else { return 17; @@ -181,6 +162,7 @@ namespace SemiColinGames { public void Draw(SpriteBatch spriteBatch, Camera camera, GameTime time) { int index = SpriteIndex(pose, time); + Debug.Toast("" + index); Rectangle textureSource = new Rectangle(index * spriteSize, 0, spriteSize, spriteSize); Vector2 spriteCenter = new Vector2(spriteSize / 2, spriteSize / 2); SpriteEffects effect = facing == Facing.Right ?