Question

I have the following Game1 class, which I altered a little bit (hehe, and may actually be the reason why this isn't working properly...):

Game1 Class

public class Game1 : Microsoft.Xna.Framework.Game
    {
        //GraphicsDeviceManager graphics;
        SpriteController _spriteController;
        GraphicsDevice graphicsDevice;
        ContentManager _contentManager;

        public Game1()
        {
            _contentManager = new ContentManager(new Chronos.Engine.Infrastructure.ServiceContainer());
            _contentManager.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()
        {
            _spriteController = new SpriteController();



            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()
        {

        }

        /// <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();



            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)
        {
            _spriteController.GraphicsDeviceService.GraphicsDevice.Clear(Color.CornflowerBlue);

            string fileAsset = "pacmansprite";

            _spriteController.AddSprite(
               new Sprite(
                   10,
                   10,
                   fileAsset,
                   _contentManager
               ),
               fileAsset
           );

            _spriteController.Draw(10, 10, fileAsset);

            base.Draw(gameTime);
        }
    }

Additional Information

The sprite controller is simply a class which holds multiple sprites, drawing sprites based on the key specified (i.e., a IDictionary<string, Sprite> is used to contain them). Within the spriteController is a GraphicsDevice reference which may be accessed, along with a content manager which may be returned. Ultimately, I'd like to make it so that the SpriteController is the only field within the Game1 class, as it provides all of the necessary components to do what is necessary to render simple graphics, but I can't do that until I fix this.

The issue happens in the Sprite class' constructor. Here's the method which passes in the data: From the Game1 Class

protected override void Draw(GameTime gameTime)
            {
                _spriteController.GraphicsDeviceService.GraphicsDevice.Clear(Color.CornflowerBlue);

                string fileAsset = "pacmansprite";

                _spriteController.AddSprite(
                   new Sprite(
                       10,
                       10,
                       fileAsset,
                       _contentManager
                   ),
                   fileAsset
               );

                _spriteController.Draw(10, 10, fileAsset);

                base.Draw(gameTime);
            }

From the Sprite Class

public Sprite(float x, float y, string assetName, ContentManager contentManager)
        {
            _position = new Vector2(x, y);
            _texture = contentManager.Load<Texture2D>(assetName); //Error: file not found

        }

The error occurs right here: I need to reference a .png file (which IS loaded in the external Content file, has the same name, and has an importer/processor of Texture), which isn't loading. The fileAsset name, as shown, is "pacmansprite".

Is there anything which anyone can see that I'm doing wrong? I'll post more code if need be, but for now I think this should be sufficient.

Was it helpful?

Solution

The first bug I see in your code, unrelated to your exception: You really should be loading content in LoadContent and not in Draw. Especially considering that you're creating a new sprite object every single frame. You should consider dropping your sprite controller and sprite classes entirely - they seem to be an unnecessary layer of indirection.

The next bug: The way you are setting up your own _contentManager seems to be wrong. The service container you pass in needs to contain a GraphicsDeviceService if you want to load textures. You should pass in Game.Services or, better yet, just use Game.Content instead of creating your own!

Finally, your exception: You haven't provided enough information to determine exactly why you are getting it. But here's how to figure out what's wrong:

First you need to find out the path that it is attempting load your texture from. This is the combination of the RootDirectory and the asset name, plus a .xnb file extension. To me it looks like it is attempting to load Content\pacmansprite.xnb.

So the next step is to look in your build directory (bin\x86\Debug or similar) and see if a file exists at that path. If not, you need to modify your content project so that the content build output appears there.

(The content project needs to be referenced by your game project, and it needs to have its root directory property set correctly. The asset needs to have the correct asset name property (and other settings).)

If you have trouble, one thing that could help is to try creating a new project with the default template and loading and drawing your asset directly. Then work from there.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top