3
\$\begingroup\$

I'm having a bit of trouble getting my sprites in XNA to draw when near the edge of the screen.

Seemingly if you use SpriteBatch to draw then XNA will not draw it if for example (mPosition.X + mSpriteTexture.Width < 0) as it assumes it is offscreen.

However, it seems to make this decision before it applies a rotation. This rotation can mean that, even though (mPosition.X + mSpriteTexture.Width < 0), some of the sprite is still visible on screen.

EDIT: The rotation being a part of the problem is only a hypothesis but to clarify, as the sprite moves towards the edge of the screen at a steady rate (applying a small constant velocity) it will suddenly disappear when it is still partially (usually about half of the sprite) on screen.

My question is, is there a way to get it to draw further outside the viewport or temporarily disable sprite clipping during a certain spriteBatch.draw(...)?

sb.Draw(mSpriteTexture, mPosition,
                new Rectangle(0, 0, mSpriteTexture.Width, mSpriteTexture.Height),
                Color.White, Globals.VectorToAngle(mOrientation), new      Vector2(halfWidth, halfHeight), scale, SpriteEffects.None, 0);
\$\endgroup\$

2 Answers 2

2
\$\begingroup\$

I don't think you assertion that the sprite is clipped is true. I've just tested the following code, which draws part of the sprite after rotation of 7/8's of a circle

   protected override void Draw(GameTime gameTime)
    {
        float rotation = (float)MathHelper.TwoPi * 7.0f / 8.0f;
        Vector2 mPosition = new Vector2(-(mSpriteTexture.Width + 1), 100);

        GraphicsDevice.Clear(Color.CornflowerBlue);
        spriteBatch.Begin();
        spriteBatch.Draw(mSpriteTexture, mPosition, null, Color.White, rotation, Vector2.Zero, 1, SpriteEffects.None, 0);
        spriteBatch.End();
        // TODO: Add your drawing code here

        base.Draw(gameTime);
    }

As you can see, mPosition.X + mSpriteTexture.Width < 0 is true in this case.

In your code, it looks like you are setting sprite origin to be;

new Vector2(mSpriteTexture.Width / 2, mSpriteTexture.Width/2)

Which has the effect of moving the sprite to the left of mPosition by mSpriteTexture.Width / 2, so maybe the sprite is a bit further 'offscreen' than you initially thought.

\$\endgroup\$
5
  • \$\begingroup\$ I'm with you :) \$\endgroup\$
    – Blau
    Nov 26, 2012 at 16:31
  • \$\begingroup\$ I'm not certain if it's related to the rotation but to clarify, as the sprite moves towards the edge of the screen at a steady rate (applying a small constant velocity) it will suddenly disappear when it is still partially (usually about half of the sprite) on screen. \$\endgroup\$
    – Kevin B
    Nov 27, 2012 at 12:06
  • \$\begingroup\$ @KevinB, I can't reproduce this behaviour. If I move my sprite (rotated by -45deg) towards the left, it just moves off the edge of the screen like one would expect. No sudden disappearances. \$\endgroup\$
    – Ken
    Nov 27, 2012 at 14:04
  • \$\begingroup\$ @Ken I'm not sure if it will affect the result but you could try rotating it in the opposite direction. \$\endgroup\$
    – Kevin B
    Nov 27, 2012 at 14:52
  • \$\begingroup\$ @KevinB, doesn't change anything \$\endgroup\$
    – Ken
    Nov 27, 2012 at 14:59
0
\$\begingroup\$

Turns out I was well off the mark, the mPosition variable I used was a part of a translation to do a wrap-around on-screen. When doing a wraparound with the sprites drawn at their centres it is necessary to include the halfWidth and halfHeight of the sprite when calculating wraparound. Final wraparound code looks as follows

            if (mTranslation.X > (Globals.Universe.X - halfWidth)) mTranslation.X -= Globals.Universe.X;
            else if (mTranslation.X < -halfWidth) mTranslation.X += Globals.Universe.X;
            if (mTranslation.Y > (Globals.Universe.Y - halfHeight)) mTranslation.Y -= Globals.Universe.Y;
            else if (mTranslation.Y < -halfHeight) mTranslation.Y += Globals.Universe.Y;
            mPosition = mTranslation;
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .