Reputation: 61
I am new to xna programming I need a little help here...
I build a 2D game, with static background In my current screen there are the background image, 4 large images on the left and i need to draw 16 small images (50x50 more or less) on the right
So this is my method to update the location of the 16 images on the left It is called only once by the Update
private void letterLblsLocation()
{
if (letterLbls.Count != 0)
{
letterlblposition = new Vector2(0f, 0f);
lblvector = new Vector2(0f, 0f);
int col = 1;
int lblsize = ScreenManager.GraphicsDevice.Viewport.Height / 15;
for (int lbl = 0; lbl < letterLbls.Count; lbl++)
{
letterlblposition.X = ScreenManager.GraphicsDevice.Viewport.Width - (col * lblsize);
letterlblposition.Y += 5 + lblsize;
if (letterlblposition.Y > ScreenManager.GraphicsDevice.Viewport.Height - lblsize)
{
col = col + 3;
letterlblposition.Y = 5 + lblsize;
}
recsOnRight.Add(new Rectangle((int)letterlblposition.X, (int)letterlblposition.Y, lblsize, lblsize));
lblvector.X = recsOnRight[lbl].X + 5;
lblvector.Y = recsOnRight[lbl].Y;
letterLbls[lbl].Position = lblvector;
}
}
}
This is my Update method
public override void Update(GameTime gameTime, bool otherScreenHasFocus,bool coveredByOtherScreen)
{
base.Update(gameTime, otherScreenHasFocus, false);
// Gradually fade in or out depending on whether we are covered by the pause screen.
if (coveredByOtherScreen)
pauseAlpha = Math.Min(pauseAlpha + 1f / 32, 1);
else
pauseAlpha = Math.Max(pauseAlpha - 1f / 32, 0);
if (IsActive)
{
if(questionNeeded)
{
ChooseWord();
ChooseLettersOnRight();
LabelsWithLetters();
letterLblsLocation();
}
}
}
And this is my Draw method
public override void Draw(GameTime gameTime)
{
spriteBatch.Begin();
spriteBatch.Draw(background, new Rectangle(0, 0, ScreenManager.GraphicsDevice.Viewport.Width, ScreenManager.GraphicsDevice.Viewport.Height), Color.White);
if (!questionNeeded)
{
for (int i = 0; i < 16; i++)
{
if (i < 4)
{
Texture2D helpTexture = questionToDisplay.pic[i];
Rectangle helpRect = questionToDisplay.picRecs[i];
spriteBatch.Draw(helpTexture, helpRect, Color.White);
}
spriteBatch.Draw(labelSquare, recsOnRight[i], Color.White);
}
}
spriteBatch.End();
Now my problem is that when I try to draw the 16 spritebatch on right the game becomes slow Is there a way to draw the 16 pics only once and redraw them only when the player clicks on one of them? Or a way to merge them in order to draw one large image and not 16 smaller? Or since I have a very little experience here, is there anything in this code that must change that makes the game runs slow when I draw this pics?
Thanks in advance
Upvotes: 2
Views: 1111
Reputation: 61
Well I just removed the for loop from draw method then call spriteBatch.Draw 16 times, one for each sprite. Yes obviously this is not the best solution, yet it worked and the speed is up to normal again. Also I moved all the initializations out of Draw or Update as Jon mentioned before they do make the code faster.
Upvotes: 1
Reputation:
There is no places in your code snippet that can slow down application a lot. Try test Draw and Update methods using stopwatch. With fps 60 (by default) it should be no more than 1/60s in total. Try localize what exactly part slow down your game.
What about drawing images only once it's not correct. XNA is not WinForms, and Draw() calls each frame and you should clear screen and redraw all you want show to player. Game loop is simple: once call Initialize() and LoadContent, then in 'endless' cicle calls Update and Draw with some frequency and once call of the UnloadContent in the end.
If you want change image after click by them that you need to have two images - clicked and unclicked, and some variable to keep state of each of them. You check mouse/keybord input in Update method, change variable state and in the Draw method decide what image pass to spritebatch.Draw() call. Also if you have some complex scene that consists of a lot sprites you can draw it to render target only once after each update and then draw it like one solid texture ('lot' mean 100s, like in Terraria, but not 16 blue rects).
Upvotes: 0
Reputation: 11273
You are initializing your Graphics Device, SpriteBatch, SpriteFont and Textures during your Draw call. This is really bad.
Move these initializations into a LoadContent() function outside of your Draw function, and only initialize this once.
Upvotes: 2