Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

Sorry if this has been asked before, but I can't seem to find it here. I'm trying to make an asteroids clone in XNA. I took the Game State Management project and am making new classes for things like the player and placing them in the GameplayScreen class. For some reason my ship isn't being draw correctly.

GameplayScreen's Draw method:

 public override void Draw(GameTime gameTime)
    {
        ScreenManager.GraphicsDevice.Clear(ClearOptions.Target,
                                           Color.CornflowerBlue, 0, 0);

        SpriteBatch spriteBatch = ScreenManager.SpriteBatch;

        spriteBatch.Begin();
        //draw fps
        if(showFPS)
            spriteBatch.DrawString(framerateFont, "FPS: " + frameRate, new Vector2(15, 15), Color.White);


        player.Draw(spriteBatch);

        spriteBatch.End();

        // If the game is transitioning on or off, fade it out to black.
        if (TransitionPosition > 0 || pauseAlpha > 0)
        {
            float alpha = MathHelper.Lerp(1f - TransitionAlpha, 1f, pauseAlpha / 2);

            ScreenManager.FadeBackBufferToBlack(alpha);
        }
    }

And my ship's drawing code:

 public PlayerShip(Game game)
    {
        this.game = game;
        Viewport view = game.GraphicsDevice.Viewport;
        center = new Vector2(view.Width / 2, view.Height /2);
        sourceRectangle = new Rectangle();
        Reset(center);
    }

    public void Reset(Vector2 position)
    {
        this.position = position;
    }

    public void LoadContent()
    {
        ship = game.Content.Load<Texture2D>("ship");
        sourceRectangle = new Rectangle(0, 0, ship.Width,
            ship.Height);
        origin = new Vector2(ship.Width / 2, ship.Height);
    }

    public void Update(GameTime gameTime)
    {
        HandleInput();

    }

    //handles all keyboard input by user. rotates ship based on current rotation.
    private void HandleInput()
    {
        input = Keyboard.GetState();
        float x = position.X;
        float y = position.Y;
        Matrix m = Matrix.CreateRotationZ(rotation);

        if (input.IsKeyDown(Keys.Right))
            rotation += turnFactor;
        else if (input.IsKeyDown(Keys.Left))
            rotation -= turnFactor;
        else if (input.IsKeyDown(Keys.Up))
        {
            x += m.M12 * directionFactor;
            y -= m.M11 * directionFactor;
        }
        else if (input.IsKeyDown(Keys.Down))
        {
            x -= m.M12 * directionFactor;
            y += m.M11 * directionFactor;
        }
        position.X = x;
        position.Y = y;
        Console.WriteLine("Y: {0} ", y);
        Console.WriteLine("X: {0} ", x);
    }

    public void Draw(SpriteBatch sb)
    {
        Vector2 origin = new Vector2(ship.Width / 2, ship.Height);
        sb.Draw(ship, ship.Bounds, null, Color.White, rotation, origin, SpriteEffects.None, 0f);
    }

I hooked the project up to a console window and it seems that the X and Y positions are updating correctly code wise, but not visually. It seems to update where it is rotationally, but going up or down doesn't draw correctly.

Image of what it's doing http://imgur.com/4cKBk

share|improve this question
    
Is it not drawing at all? Or is it drawing, but distorted or in a wrong place? A screenshot of the problem would help. –  Luis Estrada Feb 28 '12 at 23:12
    
@LuisEstrada I edited my post to include a picture and some more code. It's only rotating around the top left corner on the screen, but the X and Y positions are being updated on the console. –  mooles Feb 28 '12 at 23:21
add comment

1 Answer 1

up vote 2 down vote accepted

The problem is that when you're using the following version of SpriteBatch.Draw:

public void Draw (
     Texture2D texture,
     Rectangle destinationRectangle,         // Destination rectangle on _screen_
     Nullable<Rectangle> sourceRectangle,
     Color color,
     float rotation,
     Vector2 origin,
     SpriteEffects effects,
     float layerDepth
)

And calling it with the following parameters:

// Wrong version
sb.Draw(ship, ship.Bounds, null, Color.White, rotation, origin, SpriteEffects.None, 0f);

The second parameter is expecting the destinationRectangle where the sprite should be drawn on screen but you're passing it the sprite's ship.Bounds which is simply a Rectangle like (0, 0, ship.Width, ship.Height). That's why the sprite is always stuck to the corner of the screen.

This is a simple fix. Just change that line to:

// Correct version
sb.Draw(ship, position, null, Color.White, rotation, origin, 1f, SpriteEffects.None, 0f);

And if everything else is correct, it should work. That's just another version of SpriteBatch.Draw that goes like this:

public void Draw (
     Texture2D texture,
     Vector2 position,
     Nullable<Rectangle> sourceRectangle,
     Color color,
     float rotation,
     Vector2 origin,
     float scale,
     SpriteEffects effects,
     float layerDepth
)
share|improve this answer
    
facepalm I uploaded the wrong set of code, that was me testing around with SpriteBatches. I updating the code in the original post with the code that works the most, all of my other tries have made the sprite invisible on the screen. –  mooles Feb 28 '12 at 23:24
    
@mooles Oh okay, I thought it was strange. I see what the problem is on your new code, I'll update my answer. –  David Gouveia Feb 28 '12 at 23:24
    
@mooles Okay, updated. (edited over the previous comment completely). –  David Gouveia Feb 28 '12 at 23:30
    
Ugh, I probably could've figured that out. I was looking over some code from another game and it was using null for the sourceRectangle parameter, so I figured it wasn't important. –  mooles Feb 28 '12 at 23:43
    
@mooles Some clarification. Using null for sourceRectangle is normal. It just means "draw the entire texture". The problem was your misuse of the destinationRectangle parameter, which is basically a way to mix a position and a non-uniform scale into a single value, meaning that you can use it to set the position of your sprite and specify its size at the same time. When you don't need to control the sprite's size explicitly, it's easier to just use the position and scale parameters instead. –  David Gouveia Feb 29 '12 at 0:16
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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