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.

I taking my first steps with XNA. I'm building the old 2D tutorial that used to be posted on the XNA website. I got to the part where I display the cannon, but its not showing. Can someone please take a look and say what is wrong. The background texture is displaying fine.

Main class:

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 XNA2DTutorial
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        Texture2D backgroundTexture;
        Rectangle viewportRect;
        GameObject cannon;

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

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here

            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            backgroundTexture = Content.Load<Texture2D>("Sprites\\background");

            cannon = new GameObject(Content.Load<Texture2D>("Sprites\\cannon"));
            cannon.position = new Vector2(120, graphics.GraphicsDevice.Viewport.Height - 80);

            viewportRect = new Rectangle(0, 0, 
                graphics.GraphicsDevice.Viewport.Width, 
                graphics.GraphicsDevice.Viewport.Height);
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();
#if !xbox
            KeyboardState keyboardState = Keyboard.GetState();
            if (keyboardState.IsKeyDown(Keys.Right))
            {
                cannon.rotation -= 0.1f;
            }
            if (keyboardState.IsKeyDown(Keys.Left))
            {
                cannon.rotation += 0.1f;
            }
#endif
            cannon.rotation = MathHelper.Clamp(cannon.rotation, -MathHelper.PiOver2, 0);

            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
            spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend);
            spriteBatch.Draw(backgroundTexture, viewportRect, Color.White);

            spriteBatch.Draw(cannon.sprite, 
                cannon.position, 
                null, 
                Color.White, 
                cannon.rotation, 
                cannon.center, 
                1.0f, 
                SpriteEffects.None, 
                0);

            spriteBatch.End();

            base.Draw(gameTime);
        }
    }
}

Game object class:

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 XNA2DTutorial
{
    public class GameObject
    {
        #region Attributes
        public Texture2D sprite;
        public Vector2 position;
        public float rotation;
        public Vector2 center;
        #endregion Attributes

        #region Constructors
        public GameObject(Texture2D loadedTexture)
        {
            rotation = 0.0f;
            position = Vector2.Zero;
            sprite = loadedTexture;
            center = new Vector2(sprite.Width / 2, sprite.Height / 2);
        }
        #endregion Constructors

        #region Methods
        #endregion Methods
    }
}
share|improve this question
add comment

1 Answer

up vote 3 down vote accepted

The problem comes from your spriteBatch.Begin call.

You're passing SpriteSortMode.BackToFront and since both of your layerDepths are equal to 0, I'd guess that the order would get mixed up when the sprites get drawn on the spriteBatch.End call, therefore drawing the background on top of the cannon.

Try passing SpriteSortMode.Deferred instead. This will draw the sprites immediately when you call spriteBatch.Draw and should draw them in the proper order. Works for me at least.

share|improve this answer
1  
You should use SpriteSortMode.Deferred (the default) in XNA 4.0 unless you are doing "tricky things" (reference). –  Andrew Russell Jun 7 '11 at 4:06
    
@Andrew Russell: Ahhh I knew BackToFront had to change but I didn't know to what... I searched a little bit in the hope of finding an article explaining such things but couldn't find any. Thank you for pointing it out. –  Jesse Emond Jun 7 '11 at 4:36
2  
Both worked but I'll stick with Deferred. Thanks. –  Yoav Jun 7 '11 at 18:17
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.