Arkcann

Well, earlier today I realized my mario-clone was taking a while to load mainly due to the audio files and partly due to the many sprites being loaded. It wasn't a real problem, but it seemed rather unproffesional to have the computer pause for a while without any feedback for the user to confirm that anything was happening. Initially I used System.Console.WriteLine("Loading Something...") for the various resources that I had. This works fine for debugging, but whenever I tried to organize a loading bar that the user could see on a devoted portion of my game I experienced some trouble. First off, I'm using game states to determine whether I'm loading, at the menu, or playing the game, these aren't a problem. Secondly I'm using a rather mediocre way of deciding how many resources have been loaded, I'm simply increasing an integer value below the code that loads my resource. It's simple but it works for my purposes. This integer value directly affects the width of my loading bar tick's (looks like a '|' ) destination rectangle, this stretches my image to achieve the desired look of the bar filling up.

All of this works except that the loading bar doesn't show the intermediate positions, rather it is either completely empty or completly full. This is due to all my loading code being in its own method, and whenever I do spriteBatch.Draw() the various textures that make up the bar aren't shown until the spriteBatch.End() at the end of my method, which is too late because by then all the resources have been loaded, so the bar is completely full. I think I remember reading (possibly in Shawn Hargreaves notes on SpriteBatches) about a setting which displays textures immediatly after each spriteBatch.Draw(), however if I'm just exhibiting some wishful thinking, then how might I show the textures individually in a fast way. Currently I've been experimenting with a spriteBatch.Begin - Draw - End for each time the bar has increased in size but this has proved to only yeild errors.

Much thanks to anyone who could help me solve this conundrum!

On a somewhat related note, does anyone know how to get the percentage of a number I know, this seems quite easy but for some reason everytime I try to assign an integer or double to a value that should return something other than zero, all I get IS zero. For example:

int inPercentage = (15 / 30) * 100;

From what I've learnt in math this should result in inPercentage having a value of 50, or 50% but from my experience it's always resulted in 0. When I do the same thing with a double I get the same result. I feel as though this is due to some extremely small thing that I'm completely overlooking, so hopefully someone on this forum will notice that small mistake and correct it . Thankyou for any help on the matter.



Re: XNA Game Studio Express Issues with a Loading Bar

dczraptor

You could try loading only, say, 25% of your assets. Then you increment the loading bar, and then stop loading assets to let the screen draw. Then the next time the method is called, load another 25% of your assets.

There is something called integer division, which basically truncates results if you specify that it must be an integer. In your code, (15/30), both the 15 and 30 are integers, which means that the result must also be an integer, either 0, 1, 2, etc. Since it will always round, you will always get 0. Then you take the 0 and multiply by 100, which is still zero. In your case, you could just do (15 * 100), which equals 1500, then divide by 30, and you'd get 50. so: int inPercentage = (15 * 100) / 30; If you wanted better precision (decimal places), then just convert your numbers to floats.






Re: XNA Game Studio Express Issues with a Loading Bar

Arkcann

That definitely answers my question about percentages (where's a half answer button when you need one) as I would not need decimals for what I'm doing. But the part of loading 25% of my resources, redrawing and repeating would be add quite a bit to my LoadResources() method which is already quite long at the moment, it would definitely solve the problem but I would like to first see if there is a better way to do it that doesn't involve alot of if statements or breaking up my LoadResources() method. Thankyou very much for the quick answer though!



Re: XNA Game Studio Express Issues with a Loading Bar

Hlubocky

Hmm... I'm not an expert on XNA but when I do this in WinForms apps I need to create another thread to do the loading and then have the UI thread retrieve some state from this thread describing how much of the load has finished. I assume this is also valid for XNA...




Re: XNA Game Studio Express Issues with a Loading Bar

djceejay

I'd split the loading into chunks and use a method to load each of the chunks.

[code]

unsigned int loadingprogress = 0;
unsigned int loadingtotal = 15;//total number of chunks

void LoadChunk( unsigned int chunk )
{
switch( chunk )
{
case 0:
{
//load
break;
}

case 1:
{
//load
break;
}

case 14:
{
//load
break;
}

//etc.

}

//then when you load:

if( loadingprogress < loadingtotal )
{
LoadChunk( loadingprogress++ );
float percentageDone = ( loadingprogress / (float)loadingtotal ) * 100.0f; //will be in the range 0.0 - 100.0
}
else
{
//finished loading
}


[/code]






Re: XNA Game Studio Express Issues with a Loading Bar

atlStylez

I'm not sure how ethical or how safe it is to do this, but you can call the device clear, present, and any draw methods anyway in your program. So when you're in your load module....let's say i have a list of texture filenames that I need to load.



Re: XNA Game Studio Express Issues with a Loading Bar

Leaf.

Generally you will be better off if you break your resource loading into smaller chunks or do your resource loading in another thread. But there is another option - you could render and present frames within your resource loading method. To do this you will need to handle Begin/EndDraw()yourself instead of using Game's render loop. As you will be completely in control of how often the screen is drawn you will need to find regular points in your resource loading where you can draw the screen.

Very roughly it would look like this, obviously you don't need to pass a reference to your game if the method is within your game class.

void DrawProgress(YourGame game, float progress)
{
game.BeginDraw();
game.graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

DrawLoadingScreen(game, progress);

game.EndDraw();
}

In your resource loading code call DrawProgress() as often as you can to update the screen.

There is one problem that might catch you out. The earliest chance you get to render anything is the first time Game.Draw() is called. Before that point there is no window to render too (at least on Windows using the standard GameWindow and GameHost) - the first call to Game.Update() also happens before the window is shown. This means you can't draw a progress bar the first time that Game.LoadGraphicsContent() is called, you would need to load your resources at a later point, after the first Game.Draw(). Dealing with this could be awkward, though your game state system might help.

Cheers,
Leaf.






Re: XNA Game Studio Express Issues with a Loading Bar

Arkcann

Leaf's method of doing this seems the easiest to implement in my situation, as I am already calling my LoadResources() method in the Draw() method because I noticed that the Update() method was being executed before the screen was showing, so theoretically all I really need to put in is the Begin/EndDraw methods and rearrange some other code and it should work. Thankyou to all those who helped!