IRDuck
IRDuck

Reputation: 13

XNA spritesheet animation

Creating a simple RPG game, first time using XNA.

Trying to get my character to face different ways whenever i move in different directions.

The problem is that when i start up i cant even see my texture, the weird thing is that when i walk over a specific position in the game the whole spritesheet becomes visible, same thing for my AI NPC:s.. It's like they're laying there behind the background and the rectangle i'm moving is transparant (so i can see through the background with it).

FrameWidth and FrameHeight is sent in when i create an instance of the class. (height = 0 (starting from the top of the spritesheet), width = spritesheetwidth / 4 (to get that single sprite out).)

Velocity is the speed of which the character moves.

    public override void Update(GameTime gameTime)
    {
        ObjectRectangle = new Rectangle(CurrentFrame * FrameWidth, 0, FrameWidth, FrameHeight);
        Origin = new Vector2(ObjectRectangle.Width / 2, ObjectRectangle.Height / 2);
        Position += Velocity;

        ObjectRectangleX = (int)PositionX;
        ObjectRectangleY = (int)PositionY;

        #region movement
        if (Keyboard.GetState().IsKeyDown(Keys.D) && Pastkey.IsKeyUp(Keys.A) && Pastkey.IsKeyUp(Keys.W) && Pastkey.IsKeyUp(Keys.S))
        {
            AnimateRight(gameTime);
            VelocityX = 2;
        }
        else if (Keyboard.GetState().IsKeyDown(Keys.A) && Pastkey.IsKeyUp(Keys.D) && Pastkey.IsKeyUp(Keys.W) && Pastkey.IsKeyUp(Keys.S))
        {
            AnimateLeft(gameTime);
            VelocityX = -2;
        }
        else if (Keyboard.GetState().IsKeyDown(Keys.W) && Pastkey.IsKeyUp(Keys.A) && Pastkey.IsKeyUp(Keys.D) && Pastkey.IsKeyUp(Keys.S))
        {
            AnimateUp(gameTime);
            VelocityY = -2;
        }
        else if (Keyboard.GetState().IsKeyDown(Keys.S) && Pastkey.IsKeyUp(Keys.A) && Pastkey.IsKeyUp(Keys.W) && Pastkey.IsKeyUp(Keys.D))
        {
            AnimateDown(gameTime);
            VelocityY = 2;
        }
        else
        {
            Velocity = Vector2.Zero;
        }

        Pastkey = Keyboard.GetState();

        #endregion
    }

    #region Animations

    public void AnimateDown(GameTime gameTime)
    {
        CurrentFrame = 2;
    }
    public void AnimateRight(GameTime gameTime)
    {
        CurrentFrame = 3;
    }
    public void AnimateLeft(GameTime gameTime)
    {
        CurrentFrame = 1;
    }
    public void AnimateUp(GameTime gameTime)
    {
        CurrentFrame = 0;
    }

    #endregion

}

Draw method looks like:

    public virtual void Draw(SpriteBatch spriteBatch)
    {

        spriteBatch.Draw(ObjectTexture, Position, ObjectRectangle, Color.White, 0f, Origin, 1.0f, SpriteEffects.None, 0f);
        GameList.Add(this);
    }

(Ignore the List.Add)

So what i need help with is "locking" the texture to the rectangle.

Upvotes: 1

Views: 1241

Answers (2)

GambitSunob
GambitSunob

Reputation: 123

My initial thought is that you're calculating the values before knowing that frames data.

Moving this code

ObjectRectangle = new Rectangle(CurrentFrame * FrameWidth, 0, FrameWidth, FrameHeight);
Origin = new Vector2(ObjectRectangle.Width / 2, ObjectRectangle.Height / 2);
Position += Velocity;

ObjectRectangleX = (int)PositionX;
ObjectRectangleY = (int)PositionY;

To the bottom of your update method will give you better results. Also, it doesn't look like you're updating PositionX, or PositionY. You should instead be using Position.X and Position.Y.

Edit - You're changing the position of the source image. So when you move across the screen your position updates, moving your source rectangle over closer to what it should be. So simply commenting out the two below lines should fix it.

ObjectRectangleX = (int)PositionX;
ObjectRectangleY = (int)PositionY;

Edit 2 - Clarification

To fix both the Source Rectangle, and keep the AI working you need to do the following. In the Update method of both CharacterAnimation.cs and Monster.cs, comment out the two lines

ObjectRectangleX = (int)PositionX;
ObjectRectangleY = (int)PositionY;

Then in Monster.cs in the Enemymovement(CharacterAnimation hero) method modify these lines (45,46)

ObjectcentreX = ObjectRectangle.X + (ObjectTexture.Width / 2);
ObjectcentreY = ObjectRectangle.Y + (ObjectTexture.Height / 2);

to become

ObjectcentreX = (int)PositionX + (ObjectTexture.Width / 2);
ObjectcentreY = (int)PositionY + (ObjectTexture.Height / 2);

Upvotes: 0

Jon
Jon

Reputation: 163

These lines look unneccessary

ObjectRectangleX = (int)PositionX;
ObjectRectangleY = (int)PositionY;

One thing you might look at is the final parameter in the .Draw call. You have it as 0f right now, that is the layer depth and if that value is lower than your terrain then the terrain will be drawn on top...I think, depends on your spritebatch.begin() arguments. You can read a bit more here where a few more bits are explained about layer depth. https://gamedev.stackexchange.com/questions/23619/2d-layerdepth-not-working-xna-4-0

Upvotes: 1

Related Questions