• entries
44
44
• views
36835

# Orange pants man likes weird control schemes

247 views

In my head it seemed like a good idea to have the player face and move forward with [W], face and move right with [D] and so on. This is the basic control scheme of most standard 2D games.

It turns out this a absolutely foolish move in 3d. It is impossibly difficult to predict how WSAD will effect the player is the perspective is 3rd person (3d). Of course I only discovered this after spending 3 hours writing some very very very nice movement code. It's a work of art! The player rotates to face the direction of movement, and can decide whether it would be faster to rotate clockwise or counter-clockwise. but its a dumb and useless control scheme

(cries) :(

code (it deserves at least this much, I'm so proud of it)
abstract class physics_player: animation_none    {        #region fields        private Vector3 friction = new Vector3(-1f, -1f, -1f);        private Vector3 acceleration = Vector3.Zero;        private Vector3 accelerationRate = new Vector3(.001f);        private Vector3 deccelerationRate = new Vector3(.001f);        private Vector3 maximumAcceleration = new Vector3(.5f);        private float maxSpeed = .1f;        private float maxReverseSpeed = .1f;        private float walkSpeed = 1.5f;        private float newFacingDirection = 0f;        private float turnRate=3f;               public enum WalkState        {            neutral,            forward,            backward,            left,            right        }        public WalkState walkState = WalkState.neutral;        private WalkState previousWalkState = WalkState.neutral;        public enum Posture        {            neutral,            crouch,            jump,            prone,        }        #endregion        //--------------------------------------------------------------------        //applyAcceleration.         //--------------------------------------------------------------------        private void applyAcceleration(float elapsedTime)        {            if (acceleration.X > maximumAcceleration.X)                acceleration = maximumAcceleration;            if (acceleration.X < (maximumAcceleration.X * -1))                acceleration = (maximumAcceleration * -1);            if (velocity.X > maxSpeed)                velocity.X = maxSpeed;            if (velocity.X < -maxReverseSpeed)                velocity.X = -maxReverseSpeed;        }        //-------------------------------------------------------------------        //-------------------------------------------------------------------        //applyGravityAndNormals        private void applyGravityAndNormals(float elapsedTime)        {            float height;            Vector3 normals;            terrainManager.heightMapInfo.GetHeightAndNormal(position, out height, out normals);            //handles gravity            if (position.Y > height)            {               // acceleration.Y -= (accelerationRate.Y * elapsedTime);            }            else            {                acceleration.Y = 0;                position.Y = height;            }            orientation = Matrix.CreateRotationY(facingDirection);            //if object is near ground, orient it towards the ground            if (position.Y > height - .05 && position.Y < height + 0.5)                orientation.Up = normals;            orientation.Right = Vector3.Cross(orientation.Forward, orientation.Up);            orientation.Right = Vector3.Normalize(orientation.Right);            orientation.Forward = Vector3.Cross(orientation.Up, orientation.Right);            orientation.Forward = Vector3.Normalize(orientation.Forward);        }        //-------------------------------------------------------------------        //--------------------------------------------------------------------        //applyFriction        //--------------------------------------------------------------------        private void applyFriction(float elapsedTime)        {            velocity *= .9995f;            if (velocity.X > -.01 && velocity.X < .01)                velocity.X = 0;        }        //---------------------------------------------------------------------        //---------------------------------------------------------------------        //applyTurn        //---------------------------------------------------------------------        private void applyTurn(float elapsedTime)        {            if (facingDirection > newFacingDirection + .05)            {                facingDirection -= (turnRate * elapsedTime);            }            else if (facingDirection < newFacingDirection - .05)            {                facingDirection += (turnRate * elapsedTime);            }            else            {                //facingDirection is close to newFacingDirection                facingDirection = newFacingDirection;            }        }        //--------------------------------------------------------------------        //---------------------------------------------------------------------        //applyWalkState  unique player movement        //---------------------------------------------------------------------        private void applyWalkState(float elapsedTime)        {            if (walkState == WalkState.neutral)            {                velocity.X = 0;                velocity.Z = 0;               // newFacingDirection = 0f; better if facing direction isn't reset            }            else if (walkState == WalkState.forward && previousWalkState!=WalkState.forward)            {                velocity.Z = walkSpeed;                velocity.X = 0;                newFacingDirection = 0f;            }            else if (walkState == WalkState.backward && previousWalkState != WalkState.backward)            {                velocity.Z = -walkSpeed; //model rotates counterclockwise                velocity.X = 0;                newFacingDirection = 3.14f;                if (utility.near(facingDirection, -1.57f, .5f))                    newFacingDirection = -3.14f;            }            else if (walkState == WalkState.left && previousWalkState != WalkState.left)            {                velocity.X = walkSpeed;                velocity.Z = 0;                newFacingDirection = 1.57f;                            }            else if (walkState == WalkState.right && previousWalkState != WalkState.right)            {                velocity.X = -walkSpeed;                velocity.Z = 0;                newFacingDirection = -1.57f;                if (utility.near(facingDirection, 3.14f, .5f))                    newFacingDirection = 4.71f;            }                previousWalkState = walkState;        }        //---------------------------------------------------------------------        public void updatePhysics(float elapsedTime)        {            applyWalkState(elapsedTime);            applyTurn(elapsedTime);            //applyAcceleration(elapsedTime);//gets the new acceleration and applys it to the velocity            applyGravityAndNormals(elapsedTime);            velocity += acceleration;            applyFriction(elapsedTime);//applys friction            position += (velocity * elapsedTime);        }        }

edit: heh my "//applys friction" comment at the end there is embarrassing. I'm not sure why I felt a method named "applyFriction" needed clarification. I must have been drunk

edit 2: and no, I don't think that friction is one dimensional, I just haven't gotten around to applying it to Z (Y will probably never get it, as I'm not simulating the friction of air).

There are no comments to display.