Search code examples
c#xnaspritegame-physics

Severe Movement Lag - C#, XNA


I'm very new to programming C#, and well, programming anything. This is my third 2D game, I've encountered a problem. For some reason, the game gets laggy extremely fast when I'm attempting to move my sprite, and I can't figure out why.

Here's the Sheep class:

using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace IdeaLess
{
class Sheep
{
    //-//-//-//-//-//
    public Texture2D SheepTexture;
    public const float SheepSpeed = 0.5f;
    public Vector2 SheepPosition;
    public int Width
    {
        get { return SheepTexture.Width; }
    }
    public int Height
    {
        get { return SheepTexture.Height; }
    }
    //-//-//-//-//-//
    public void Initialize(Texture2D texture, Vector2 position)
    {
        SheepTexture = texture;
        SheepPosition = position;
    }

    public void Update()
    {
    }

    public void Draw(SpriteBatch spriteBatch)
    {
        spriteBatch.Draw(SheepTexture, SheepPosition, null, Color.White, 0f,      Vector2.Zero, 1f, SpriteEffects.None, 0f);
    }
}
}

And the Game1.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace IdeaLess
{
public class Game1 : Microsoft.Xna.Framework.Game
{
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;

    //CLASS OBJECTS
    Sheep sheep;
    Pig pig;

    //SHEEP
    float SheepMoveSpeed;
    //PIG
    float PigMoveSpeed;

    //KEYBOARDSTATES
    KeyboardState currentKeyboardState;
    KeyboardState previousKeyboardState;

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

    protected override void Initialize()
    {
        sheep = new Sheep();
        pig = new Pig();
        SheepMoveSpeed = 5f;
        PigMoveSpeed = 4f;
        base.Initialize();
    }
    protected override void LoadContent()
    {
        spriteBatch = new SpriteBatch(GraphicsDevice);
        Vector2 sheepPosition = new Vector2(20, 30);
        Vector2 pigPosition = new Vector2(20, 400);
        sheep.Initialize(Content.Load<Texture2D>("Sheep"), sheepPosition);
        pig.Initialize(Content.Load<Texture2D>("Pig"), pigPosition);
    }
    protected override void UnloadContent()
    {
    }
    protected override void Update(GameTime gameTime)
    {
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            this.Exit();

        previousKeyboardState = currentKeyboardState;
        currentKeyboardState = Keyboard.GetState();
        UpdateSheep(gameTime);
        UpdatePig(gameTime);

        base.Update(gameTime);
    }
    private void UpdateSheep(GameTime gameTime)
    {
        if (currentKeyboardState.IsKeyDown(Keys.Left))
            sheep.SheepPosition.X -= SheepMoveSpeed;
        if (currentKeyboardState.IsKeyDown(Keys.Right))
            sheep.SheepPosition.X += SheepMoveSpeed;
    }
    private void UpdatePig(GameTime gameTime)
    {
        if (currentKeyboardState.IsKeyDown(Keys.A))
            pig.PigPosition.X -= PigMoveSpeed;
        if (currentKeyboardState.IsKeyDown(Keys.D))
            pig.PigPosition.X += PigMoveSpeed;
    }

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

        spriteBatch.Begin();

        sheep.Draw(spriteBatch);
        pig.Draw(spriteBatch);

        spriteBatch.End();

        base.Draw(gameTime);
    }
}
}

So far the game is made up of nothing but a player class (Sheep) and the Game1.cs. There is also a pig class; identical to the sheep one.

Basically, whenever I hold 'Right Arrow', the sprite moves jerky and unevenly, sometimes slowing down to almost stationary, and sometimes it moves normally for a moment before lagging again.

It's not just the sprite movement, but it's the FPS. I know this because I've encountered this lag on a previous game and it caused the background music to stop and the timer from ticking.

Any ideas what might be causing this?


Solution

  • Well good news, it looks like it is nothing major! A thing I always encourage new XNA programmers to do, is add Elapsed time! Basicly, depending on how fast your system is running at a given time, may effect how fast your sprite moves depending on how many frames per seconds you have. If you tried this on a different computer it may run at a completely different speed.

    To correct this you need to modify your UpdateAnimal() Methods

    private void UpdateSheep(GameTime gameTime)
    {
            //How much time has passed since the last frame, incase we lag and skip a frame, or take too long, we can process accordingly
            float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
    
            if (currentKeyboardState.IsKeyDown(Keys.Left))
                sheep.SheepPosition.X -= SheepMoveSpeed * elapsed; // Multiply by elapsed!
            if (currentKeyboardState.IsKeyDown(Keys.Right))
                sheep.SheepPosition.X += SheepMoveSpeed * elapsed;
    }
    

    Now, depending on your computer specs, elapsed will be a very small fraction of 1 (second) so you will need to increase your SheepMoveSpeed until your sprite starts moving.

    If this dosen't work, you can try using a profiler to see what is causing lag, or add an fps timer to see if it is really "laggy" or just a matter of not moving properly.

    I would also encourage you to create an Animal class, and create other classes that inherit from it.