5
\$\begingroup\$

I know this code needs some organization like classes, enums, methods, arrays or something but I just want to know if I could have created a character movement script, thereby shortening the code without using enums, methods, array etc. (keep it the same). Is there any ways to shorten this?

  namespace rpgProject  
{

public class Game1 : Microsoft.Xna.Framework.Game


 {


    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;

    Texture2D Character; 

    Vector2 characterPos = new Vector2(400,240);
    float speed1 = 2;

    float speed2 = 2;

    Point frameSize = new Point(32,63); 

    Point CurrentFrame = new Point(0, 0);

    Point sheetSize = new Point(6, 4);  

    int timePassed;

    int timeLimit=43; 

    bool right = true;

    bool left = true;  

    bool up = true;

    bool glitch = true;

    bool down = true;

    SpriteFont font1;

    SpriteFont font2;

    public Game1()
    {
        graphics = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";
    }


    protected override void Initialize()
    {


        base.Initialize();
    }


    protected override void LoadContent()
    {

        spriteBatch = new SpriteBatch(GraphicsDevice);
        Character = Content.Load<Texture2D>("Sprites/test");
        font1 = Content.Load<SpriteFont>("fonts/SpriteFont1");
        font2 = Content.Load<SpriteFont>("fonts/SpriteFont1");

    }


    protected override void UnloadContent()
    {

    }


    protected override void Update(GameTime gameTime)
    {
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            this.Exit();

        if (characterPos.X < 0 || characterPos.X > Window.ClientBounds.Width - Character.Width)//to make sure it does not colide with edge of the screen
        {
            if (characterPos.X < 0)
            {
                characterPos.X = 0;

            }
            else
            {
                characterPos.X = Window.ClientBounds.Width - Character.Width;

            }
        }
        if (characterPos.Y < 0 || characterPos.Y >= Window.ClientBounds.Height - Character.Height)
        {


            if (characterPos.Y < 0)
            {
                characterPos.Y = 0;

            }
            else
            {
                characterPos.Y = Window.ClientBounds.Height - Character.Height;

            }

        }




        timePassed += gameTime.ElapsedGameTime.Milliseconds;

        KeyboardState charMovement = Keyboard.GetState();





        if (timePassed >= timeLimit)
        {

            timePassed -=timeLimit;
            if (right==true)
            {

                if (charMovement.IsKeyDown(Keys.Right))
                {


                    left = false;
                    up = false;
                    down = false;

                    characterPos.X += speed1;
                    sheetSize.Y = 3;
                    CurrentFrame.Y = sheetSize.Y;
                    ++CurrentFrame.X;
                    if (CurrentFrame.X >= sheetSize.X)
                    {
                        CurrentFrame.X = 0;
                        Console.WriteLine("stage 4");
                    }

                }

                else
                {
                    glitch = true;
                    right = false;
                    left = true;
                    up = true;
                    down = true;
                    CurrentFrame.X = 0;

                }
            }


            if (left == true)
            {

                if (charMovement.IsKeyDown(Keys.Left))
                {

                    right = false;
                    up = false;
                    down = false;
                    characterPos.X -= speed1;
                    sheetSize.Y = 1;

                    CurrentFrame.Y = sheetSize.Y;
                    ++CurrentFrame.X;
                    if (CurrentFrame.X >= sheetSize.X)
                    {
                        CurrentFrame.X = 0;
                        Console.WriteLine("stage 3");

                    }
                }
                else
                {
                    left = false;
                    right = true;
                    up = true;
                    down = true;
                    CurrentFrame.X = 0;
                }


            }

            if (up == true)
            {
                if (charMovement.IsKeyDown(Keys.Up))
                {

                    left = false;
                    right = false;
                    down = false;
                    characterPos.Y -= speed2;
                    sheetSize.Y = 2;
                    CurrentFrame.Y = sheetSize.Y;
                    CurrentFrame.X++;
                    if (CurrentFrame.X >= sheetSize.X)
                    {
                        Console.WriteLine("stage 1");
                        CurrentFrame.X = 0;

                    }

                }
                else
                {
                    up = false;
                    left = true;
                    right = true;
                    down = true;
                    CurrentFrame.X = 0;
                }
            }

            if (down == true)
            {
                if (charMovement.IsKeyDown(Keys.Down))
                {

                    left = false;
                    right = false;
                    up = false;
                    characterPos.Y += speed2;
                    sheetSize.Y = 0;
                    CurrentFrame.Y = sheetSize.Y;
                    CurrentFrame.X++;
                    if (CurrentFrame.X >= sheetSize.X)
                    {
                        Console.WriteLine("stage 2");
                        CurrentFrame.X = 0;

                    }

                }
                else
                {
                    down = false;
                    up = true;
                    left = true;
                    right = true;
                    down = true;
                    CurrentFrame.X = 0;
                }
            }    




            base.Update(gameTime);

        }
    }


    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.White);

        spriteBatch.Begin();
        spriteBatch.Draw(Character/*spritesheet */, characterPos,new Rectangle(CurrentFrame.X * frameSize.X,
            CurrentFrame.Y * frameSize.Y, frameSize.X, frameSize.Y), Color.White,0,Vector2.Zero,1,SpriteEffects.None,0);

        spriteBatch.DrawString(font1, "hi", new Vector2(49, 49), Color.Black);
        spriteBatch.DrawString(font2,"bye", new Vector2(100, 200), Color.Black);
        spriteBatch.End();

        base.Draw(gameTime);
    }
}

}
\$\endgroup\$
4
\$\begingroup\$

I've seen InputHandler classes very similar to this one created by Robb O'Driscoll

You could cut your Game1.cs down by a fair bit using it, make the following changes:

InputHandler inputHandler;
public Game1()
{
    graphics = new GraphicsDeviceManager(this);
    Content.RootDirectory = "Content";
    inputHandler = new InputHandler();
}

At the starting of your Update method add:

inputHandler.Update(gameTime);

You can then use:

if(inputHandler.KeyPressed(Keys.Right))
{
    //Move Character right
}

I am not 100% sure what you're doing with the boolean left,right,up,down so I didn't put much effort into changing your actual code.

The majority of your code is setting the four direction booleans back and forth though, perhaps simplifying what you are trying to do there will have a bigger impact.

The input handler linked should get you on the right path for pulling out the movement handling.

\$\endgroup\$
3
\$\begingroup\$

There are a lot of ways to shorten this, my favourite is to create a Character or Player class and move the movement code into it.

For example, I have a world class that has an Update method as follows:

public void Update(MouseState mState, GameTime gameTime, bool hasFocus)
{
    Vector2F vector = new Vector2F();
    float movementSpeed = 0f;

    if (_MainPlayer != null && hasFocus)
    {
        movementSpeed = MovementProperties.GetMovementSpeed(_MainPlayer.EntityProperties.Age, _MainPlayer.EntityProperties.Weight, 0, 0);
        movementSpeed = movementSpeed * (gameTime.ElapsedGameTime.Milliseconds / 1000f * 100);

        if (KeyStateMan.KeyStateNow.IsKeyDown(Keys.W))
            vector += new Vector2F(0f, 0f - movementSpeed);
        if (KeyStateMan.KeyStateNow.IsKeyDown(Keys.S))
            vector += new Vector2F(0f, movementSpeed);
        if (KeyStateMan.KeyStateNow.IsKeyDown(Keys.A))
            vector += new Vector2F(0f - movementSpeed, 0f);
        if (KeyStateMan.KeyStateNow.IsKeyDown(Keys.D))
            vector += new Vector2F(movementSpeed, 0f);

        if (_MainPlayer.Position.X + vector.X < 0)
            vector.X -= vector.X - _MainPlayer.Position.X;
        if (_MainPlayer.Position.Y + vector.Y < 0)
            vector.Y -= vector.Y - _MainPlayer.Position.Y;

        UpdateState uState = new UpdateState();
        uState.Force = vector;
        _MainPlayer.Update(uState);
    }

    base.Update(gameTime.ElapsedGameTime);
}

And a KeyboardStateManager property like:

public static KeyboardStateManager KeyStateMan { get; set; }

Which KeyboardStateManager has the following implementation (from my GitHub): KeyboardStateManager

UpdateState looks like:

public class UpdateState
{
    public Vector2F Force { get; set; }
}

And the Player.Update method like:

public virtual void Update(UpdateState updateState)
{
    Move(updateState.Force);
}

public virtual void Move(Vector2F vector)
{
    if (vector.R > 0)
        _IsMoving = true;
    else
        _IsMoving = false;

    float r = Math.Max(Math.Abs(vector.X), Math.Abs(vector.Y));
    vector = Vector2F.FromRTheta(r, vector.Theta);
    Position = new Evbpc.Framework.Drawing.PointF(Position.X + vector.X, Position.Y + vector.Y);

    if (vector.R > 0)
    {
        if (Math.Abs(vector.Theta) <= Math.PI * 0.25f)
            Direction = Direction.Right;
        else if (Math.Abs(vector.Theta) >= Math.PI * 0.75f)
            Direction = Direction.Left;
        else if (vector.Theta >= Math.PI * 0.25f && vector.Theta < Math.PI * 0.75f)
            Direction = Direction.Down;
        else
            Direction = Direction.Up;
    }
}

The idea being, you can separate the movement logic out of the game update method, and do something like:

gameWorld.Update(mState, gameTime, true);

You could, of course, do just the minimum:

public class Character
{
    private Texture2D _texture; 
    private Vector2 _position = new Vector2(400,240);

    public property Texture2D Texture { get { return _texture; } }
    public property Vector2 Position { get { return _position; } }

    public Character(Texture2D texture, Vector2 position)
    {
        this._texture = texture;
        this._position = position;
    }

    public void Update(KeyboardState keyboardState, MouseState mouseState)
    {
        // Place your movement code here
    }
}

Then, in your game, a simple character.Update(Keyboard.GetState(), Mouse.GetState()); would suffice to update your character.

This also makes it much easier to manage in the future. Rather than search a long, monolithic Update method for your movement code, it's all in a nice, tight little Update method on the actual Character or Player - where it should be. :)


If you don't want to go to the extent of making a separate class for it, there's not a whole lot that can be done.

\$\endgroup\$
2
\$\begingroup\$

Your direction booleans shouldn't be class level variables, in all reality I think that you should get rid of them. then you will enable your character to move up and right at the same time. Eventually you will have to figure out if you need to handle a situation where the user/player is trying to break the system by holding the up/down or right/left keys at the same time. other than that I don't think that you need to have those booleans.

This

            if (charMovement.IsKeyDown(Keys.Right))
            {


                left = false;
                up = false;
                down = false;

                characterPos.X += speed1;
                sheetSize.Y = 3;
                CurrentFrame.Y = sheetSize.Y;
                ++CurrentFrame.X;
                if (CurrentFrame.X >= sheetSize.X)
                {
                    CurrentFrame.X = 0;
                    Console.WriteLine("stage 4");
                }

            }

            else
            {
                glitch = true;
                right = false;
                left = true;
                up = true;
                down = true;
                CurrentFrame.X = 0;

            }

Will start looking more like this

if (charMovement.IsKeyDown(Keys.Right))
{
    characterPos.X += speed1;
    sheetSize.Y = 3;
    CurrentFrame.Y = sheetSize.Y;
    ++CurrentFrame.X;
    if (CurrentFrame.X >= sheetSize.X)
    {
        CurrentFrame.X = 0;
        Console.WriteLine("stage 4");
    }
}
else
{
    CurrentFrame.X = 0;
}

When I get home I will take a look at my game and share some more about movement code

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.