Sign in to follow this  
DavitosanX

Sprite movement lag in XNA

Recommended Posts

Hello. I'm starting out in game programming and programming in general. I had been using C++/SFML for some time, but I decided to try C#/XNA and so far I'm happy with it. I'm using Rob Miles' book (Introduction to programming through game development), as I was kinda lost in C#. So far I think I understand XNA's base classes, and set out to make a small Pong-like game.

So far I've managed to draw the sprites on the screen, get the ball to move around and bounce around the edges of the viewport. Collision with the paddle is still not perfect, but it's functional enough for now.

As an exercise, I tried to add a feature: If you press Space, the paddle becomes "sticky" and you can move the ball along with the paddle, and releasing Space releases the ball as well. It almost works as expected, except that the ball seems to lag a little behind the paddle, and only catches up when the paddle stops moving.

I'm trying to figure out just where this is happening, but I haven't spotted it yet. Any help would be appreciated. Here is the relevant code:

[code]

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

Texture2D barra;
Rectangle barraRect;

Texture2D bola;
Rectangle bolaRect;

int barraYpos;

int bolaX;
int bolaY;

bool bolaHaciaArriba;
bool bolaHaciaAdelante;
bool bolaCanMove;

public void MoverBola()
{
if (bolaHaciaArriba && bolaCanMove)
{
bolaY -=3 ;
}
else if (!bolaHaciaArriba && bolaCanMove)
{
bolaY += 3;
}

if (bolaHaciaAdelante && bolaCanMove)
{
bolaX +=3;
}
else if (!bolaHaciaAdelante && bolaCanMove)
{
bolaX -= 3;
}
}

public void DeterminarDireccionDeLaBola()
{
if (bolaX <= 0)
{
bolaHaciaAdelante = true;
}
else if (bolaX >= 780)
{
bolaHaciaAdelante = false;
}

if (bolaY <= 0)
{
bolaHaciaArriba = false;
}
else if (bolaY >= 460)
{
bolaHaciaArriba = true;
}
}

public void HandleInput()
{
KeyboardState kboard = Keyboard.GetState();

if (kboard.IsKeyDown(Keys.Escape))
{
this.Exit();
}

if (kboard.IsKeyDown(Keys.Down) && barraYpos < 350 && bolaCanMove)
{
barraYpos += 7;
}
else if (kboard.IsKeyDown(Keys.Up) && barraYpos > 10 && bolaCanMove)
{
barraYpos -= 7;
}

if (kboard.IsKeyDown(Keys.Down) && barraYpos < 350 && !bolaCanMove)
{
barraYpos += 7;
bolaY += 7;
}
else if (kboard.IsKeyDown(Keys.Up) && barraYpos > 10 && !bolaCanMove)
{
barraYpos -= 7;
bolaY -= 7;
}

if (kboard.IsKeyDown(Keys.Space) && barraRect.Intersects(bolaRect))
{
bolaCanMove = false;
}
else if (kboard.IsKeyUp(Keys.Space))
{
bolaCanMove = true;
}
}

public void HandleCollision()
{
if (barraRect.Intersects(bolaRect))
{
bolaHaciaAdelante = true;

if ((bolaY+20) < (barraYpos + 3))
{
bolaHaciaArriba = true;
}

if (bolaY > (barraYpos+97))
{
bolaHaciaArriba = false;
}
}
}

protected override void Initialize()
{
barraYpos = 10;
bolaX = 300;
bolaY = 200;
bolaCanMove = true;
barraRect = new Rectangle(10, barraYpos, 35, 110);
bolaRect = new Rectangle(bolaX,bolaY,20,20);
base.Initialize();
}

protected override void Update(GameTime gameTime)
{
bolaRect = new Rectangle(bolaX, bolaY, 20, 20);
DeterminarDireccionDeLaBola();
MoverBola();
HandleInput();
HandleCollision();

barraRect = new Rectangle(10, barraYpos, 35, 110);


// TODO: Add your update logic here

base.Update(gameTime);
}

protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Black);
spriteBatch.Begin();
spriteBatch.Draw(barra, barraRect, Color.White);
spriteBatch.Draw(bola, bolaRect, Color.White);
spriteBatch.End();

// TODO: Add your drawing code here

base.Draw(gameTime);
}

[/code]

Share this post


Link to post
Share on other sites
I'm not sure if it's your problem, but it seems that in your Update() function, you initialize the bolaRect [i]before[/i] updating its position.

Share this post


Link to post
Share on other sites
[quote name='Faelenor' timestamp='1341594119' post='4956376']
I'm not sure if it's your problem, but it seems that in your Update() function, you initialize the bolaRect [i]before[/i] updating its position.
[/quote]

Bingo! Update should be either:

[code]
protected override void Update(GameTime gameTime)
{
DeterminarDireccionDeLaBola();
MoverBola();
HandleInput();
HandleCollision();

barraRect = new Rectangle(10, barraYpos, 35, 110);
bolaRect = new Rectangle(bolaX, bolaY, 20, 20);


// TODO: Add your update logic here

base.Update(gameTime);
}

[/code]

or:

[code]
protected override void Update(GameTime gameTime)
{
barraRect = new Rectangle(10, barraYpos, 35, 110);
bolaRect = new Rectangle(bolaX, bolaY, 20, 20);

DeterminarDireccionDeLaBola();
MoverBola();
HandleInput();
HandleCollision();



// TODO: Add your update logic here

base.Update(gameTime);
}

[/code]

The problem was that I wasn't Updating the value of bolaRect and of barraRect in synchrony.

Thanks a lot, Faelenor [img]http://public.gamedev.net//public/style_emoticons/default/biggrin.png[/img] Edited by DavitosanX

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this