Troubleshooting this TutorialSometimes, even though you try hard to understand the information in a tutorial, things don't work out quite like you want it to. This page is here to help you resolve any problems you might be having with the tutorial on texture atlases in MonoGame. The Common Mistakes section describes common problems that people have when doing the things in this tutorial, and how to resolve them. The Frequently Asked Questions section describes questions that people have that aren't related to mistakes, but rather, trying to understand the stuff better or exploring how it can be used. If your problem or concern isn't addressed here, feel free to add a comment below, so that I know where you're having trouble. I like to keep these pages fairly clean, so I may remove comments that I felt like have been addressed. If I remove your comment and you don't feel like the problem has been fixed, repost the question and we'll take another look at it. If a tutorial has a mistake in it, I will fix the mistake and reply to the comment with a brief explanation. However, after a couple of weeks I'll likely go back and remove the original comment as well as my reply, because, hopefully, the problem will have been fixed, and it won't be a concern any more. |
Common MistakesNone listed yet… |
Frequently Asked QuestionsNone listed yet… |
I keep getting an error. Did I need to open a new project after finishing the sprite batch tutorial. I have a file name wrong or something. The first time I tried, error. So I simply copy and pasted the code in the tutorial. Still wrong. I closed everything out because I just wasted 2 hours trying to figure it out through google and stack overflow. Is there an obvious step that is skipped over in this tutorial? One of the things that didnt match up was a step where I was to add a class. I added one but just figured out how, the steps didnt match up with my visual studio 2010 or 2012. Also should I be writing all of this in my XNA projects and forget about the monogame portion until its finished and I need to port it over to monogame? to avoid having to periodically "pipeline" stuff over to monogame through XNA?
Can't figure out how to edit that comment. I don't have a special login, or admin privileges.
I cooled off and copied the error messages. According to stack overflow it could be 1 of 100000 problems.
Warning 1 The referenced component 'XNAProjectFirstTryContent' could not be found.
Error 2 The type or namespace name 'Net' does not exist in the namespace 'Microsoft.Xna.Framework' (are you missing an assembly reference?) C:\Users\Great Albino\Documents\Visual Studio 2010\Projects\XNAProjectFirstTry\XNAProjectFirstTry\XNAProjectFirstTry\Game1.cs 11 31 TextureAtlas
Error 3 The type or namespace name 'Storage' does not exist in the namespace 'Microsoft.Xna.Framework' (are you missing an assembly reference?) C:\Users\Great Albino\Documents\Visual Studio 2010\Projects\XNAProjectFirstTry\XNAProjectFirstTry\XNAProjectFirstTry\Game1.cs 12 31 TextureAtlas
Nvm it was my references. Solved.
Hi!
I followed the steps on this tutorial but and copying your code but I´m getting this exception:
SharpDX.SharpDXException was unhandled
HResult=-2005270524
Message=HRESULT: [0x887A0004], Module: [Unknown], ApiCode: [Unknown/Unknown], Message: Unknown
Source=SharpDX
StackTrace:
at SharpDX.Result.CheckError()
at SharpDX.Direct3D11.Device.CreateDevice(Adapter adapter, DriverType driverType, DeviceCreationFlags flags, FeatureLevel[] featureLevels)
at SharpDX.Direct3D11.Device..ctor(DriverType driverType, DeviceCreationFlags flags, FeatureLevel[] featureLevels)
at Microsoft.Xna.Framework.Graphics.GraphicsDevice.CreateDeviceResources()
at Microsoft.Xna.Framework.Graphics.GraphicsDevice.PlatformInitialize()
at Microsoft.Xna.Framework.Graphics.GraphicsDevice.Initialize()
at Microsoft.Xna.Framework.Graphics.GraphicsDevice..ctor(GraphicsAdapter adapter, GraphicsProfile graphicsProfile, PresentationParameters presentationParameters)
at Microsoft.Xna.Framework.GraphicsDeviceManager.Initialize()
at Microsoft.Xna.Framework.GraphicsDeviceManager.CreateDevice()
at Microsoft.Xna.Framework.GamePlatform.BeforeInitialize()
at MonoGame.Framework.WinFormsGamePlatform.BeforeInitialize()
at Microsoft.Xna.Framework.Game.DoInitialize()
at Microsoft.Xna.Framework.Game.Run(GameRunBehavior runBehavior)
at Microsoft.Xna.Framework.Game.Run()
at TextureAtlases.Program.Main() in c:\Users\calderon\Dropbox\C#\TextureAtlases\TextureAtlases\Program.cs:line 22
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
Any help here is appreciated, thank you…
what value do i assign columns?
thanks
thats dosnt matter i fixed it
Sorry, where am I placing the Smiley texture? I've put it in my Content folder and imported it in Visual Studio but it doesn't seem to load. It goes on about a not being able to load it as a non-content file.
Select the image in your solution explorer and go down to the file properties area. For "Copy to output directory" select the dropdown option "copy if newer."
I keep getting an error saying "spriteBatch doesn't exist" but I am sure I've declared it properly so can you tell me what is causing it and why?
int row = (int) ((float)currentFrame / (float)Columns);
Just a quick question as im a wee bit confused. But can someone explain what exactly is going on in this line of code.
I can't get my head round the casting here.
Hey Steven! Sorry about the delay in answering.
I can understand why that line is causing issues, looks like gibberish doesn't it?
So, first off, anytime you see the ()'s thats whats called a 'cast', 'type cast', or 'retype cast' - all of those terms are pretty interchangeable (at least as far as I know), and excluding stuff like if statements, which also use ()'s. Basically what we're doing when using a 'cast' is telling the computer what type of variable we want it to use. In the statement you posted:
int row = (int) ((float)currentFrame / (float)Columns);
What we're doing is explicitly telling the computer that currentFrame and Columns are to be treated as floats, and we're also telling it that after we do the division, we want the answer returned in an int. Why on Earth would we want to do that you may ask. Well, in this particular case, it allowed us more precision. Floats can handle fractions of 1, where as ints have to be whole numbers. Such as:
int row=(int)((float)10/(float)3) ->
int row=(int)(10/3) ->
int row=(int)(3.3333~) ->
int row=(int)(3)->
int row=(3)
So basically, doing it this way allows us to use a fractional value that is converted into a whole number and rounded in a single code line. Hope that makes sense. It's just a way to convert from one type of value (float) that holds more precision, into another type of variable (int), that holds less precision (but is what we need for the row value). As a side note, when we are going from a higher precision variable (float) to a lower precision value (int), this is called 'shortening' the value. On the opposite side of the spectrum, when we are going from a lower precision (int) to a higher precision (float), this is called widening.
"May the mercy of His Divine Shadow fall upon you." - Stanley H. Tweedle, Security Guard class IV, The League of 20,000 planets
Hi,
Would you please be able to explain a bit more what's going on here?
int width = Texture.Width / Columns;
int height = Texture.Height / Rows;
int row = (int)((float)currentFrame / (float)Columns);
int column = currentFrame % Columns;
Thanks
So the first two lines compute the width and height in pixels of a single sprite within the texture atlas. The whole atlas is divided into a certain number of rows and a certain number of columns. The width and height of a specific sprite will be equal to the whole texture's width and height, divided by the total number of rows or columns contained in it.
So for example, if the whole sprite is 96 pixels wide and 48 pixels tall, and there are four columns across and two rows, then we'll compute a width of 24 (96 / 4) and a height of 24 (48 / 2).
The last two compute which row and column in our grid the current frame is. It assumes that the first frame is in the top left corner, the second is to the right of that, and so on across the top row, and then drops down to the second row, and then the third, etc. down to the bottom.
Reusing the example of a texture atlas with 8 total frames arranged with 4 columns and 2 rows, we'd run left to right on the top row, then go back to the start of the second/bottom row and go across it.
So if the current frame is 0 (the first one, assuming we're using 0-based indexing) then we would want to draw the image in row 0 and column 0. If the current frame is 1, then we want to draw the section in row 0 and column 1. If the current frame is 2, we want row 0 and column 2. When the current frame is 3, we want row 0 and column 3. When the frame is 4, we want row 1 and go back to column 0. From there, we finish out the second row.
So that math computes the right row and column, based on that pattern. What I did is a relatively common trick for doing this kind of calculation, though I'll admit, if this is the first time you're seeing it, it can be rather confusing.
Let's start with the calculation for column, because it's a little easier to understand.
The % operator (the "mod" operator, or the "remainder" operator) returns the remainder if you divided those numbers. Consider what happens when you use this for 4 columns:
The pattern continues, and you'll see that this code will cause you to start repeating. 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, etc. (If we were using % 10, it would be 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, etc.)
This makes it so the column wraps back around whenever we get to the end, which is exactly what we wanted here.
The calculation for rows also uses some tricks. In particular, it is using some details on converting from floating point math to an integer, which can't have fractional values, and so it uses the floor of the number (the highest whole number less than the floating point number, effectively chopping off and throwing out any fractional value—1.9 becomes 1 as an integer, as does 1.0, 1.1, 1.334475, and even 1.999999).
That code casts both the current frame and the Columns variable to the float type to make sure it uses floating point division (which does allow fractional values). After that division, it casts it back to the int type which does that floor function to get the integer value from it.
So when the current frame is 0, we compute 0.0 / 4.0 and get a value of 0.0, which we then truncate to 0.
When the current frame is 1, we compute 1.0 / 4.0 and get a value of 0.25, which we then also truncate to 0. (0 is the greatest integer less than 0.25.)
When the current frame is 2, we compute 2.0 / 4.0 and get 0.5, which truncates to 0.
When the current frame is 3, we compute 3.0 / 4.0 and get 0.75, which truncates to 0.
When the current frame is 4, we compute 4.0 / 4.0 and get 1.0, which truncates to 1, and so we move down to the next row.
When the current frame is 5, we compute 5.0 / 4.0 and get 1.25, which truncates to 1 again.
And so on.
So that math makes it so that:
Obviously, that code doesn't require just a 4 column by 2 row configuration. The code is flexible enough that it can handle any number of rows and columns. So as an artist, you can make it 4x4, 16x2, 11x3, 2x2, or whatever size you want or need, and the code will wrap as you'd expect.
Hopefully that provides some clarity here. Like I said, that code can definitely be very confusing when you first come across it. But that technique is (a) fairly common and (b) very useful. You will probably see or find other ways that you can use similar logic to iterate across a grid like that, so keep it in mind for the future.
Thank you so much for replying so quickly. It does make sense when reading carefully. Hard one to remember probably, but I guess practicing will do the trick.
Hello
when starting the project, I geta blue screen with a white square which is blinking.
inside the square, I can see (not well) all the sprites and not one at a time.
what's the problem ?
( thanks for that tutorial, very good)
thanks for your answer.
Post preview:
Close preview