3
\$\begingroup\$

I'm working on a SpaceWar-esque project to get comfortable with XNA. I have a Ship DrawableGameComponent and a Bullet DrawableGameComponent. The player's Ship is created at the start of the game, and the Bullets are created for each Ship as part of its constructor.

In my Ship constructor, I have the following code:

for (int i = 0; i < 5; i++)
{
    activeBullets[i] = new Bullet(game);
}

The relevant part of my Ship's shoot() function is as follows:

activeBullets[bullet].Visible = true;
activeBullets[bullet].Enabled = true;
activeBullets[bullet].position = this.position;

The first five times I shoot() (that is, once for each bullet object that the ship is allotted), there is lag that I think is due to the bullet sprite being loaded. I've tried setting Visible and Enabled to true in the ship constructor loop where the Bullets are instantiated, but the first-five-shots lag persists. Any shots beyond the first five are completely lag-free.

How do I load the Bullets properly ahead of time so that there is no lag on the first shots?

\$\endgroup\$
3
  • \$\begingroup\$ Load the bullet texture in LoadContent()? \$\endgroup\$ Jul 26, 2011 at 4:16
  • \$\begingroup\$ Bullet's texture is loaded in bullet's LoadContent(). Shouldn't this happen when the Bullet() is instantiated, or barring that, Enable'd in the Ship constructor? \$\endgroup\$
    – Bill
    Jul 26, 2011 at 4:34
  • \$\begingroup\$ Sorry, should have read your post a bit closer. I'll post a real answer. \$\endgroup\$ Jul 26, 2011 at 5:02

2 Answers 2

9
\$\begingroup\$

DrawableGameComponent's come with a certain amount of overhead - aside from the memory, every time you add a component to the collection it must be resorted (because components have a DrawOrder). You don't want to be constantly adding and removing components.

For this reason, you don't want Bullet to be a DrawableGameComponent. Instead, you should make something like a ProjectileManager, which loads all the projectiles (including their textures), and manages creating/destroying/updating/drawing them. This simultaneously solves your texture-loading problem, as the textures can (and should) be loaded only once, in LoadContent().

If this does not work, then the textures are not your problem, and we'll need more information to help you further.

\$\endgroup\$
7
  • 6
    \$\begingroup\$ +1; DrawableGameComponent is not intended to be used for things like bullets. \$\endgroup\$
    – Riki
    Jul 26, 2011 at 5:30
  • \$\begingroup\$ Maybe I'm understanding them incorrectly. I'm not creating and destroying bullets, just enabling/disabling an array of 5 of them. I don't need hundreds on screen at once, and I want to limit the amount of shots my player can fire at a time anyways. Besides, it only happens the first time each bullet is fired. Can I force the add/load to happen at the beginning of the game even though it's a DrawableGameComponent? I thought I was accomplishing this by instantiating/enabling them when the Ship is instantiated. \$\endgroup\$
    – Bill
    Jul 26, 2011 at 5:51
  • \$\begingroup\$ @Bill: You could do that, but it comes with the obvious limitation of only allowing five bullets on the screen at once; a much better solution would be to create a ProjectileManager class. In either case, LoadContent() is called after all components have been added to the collection (in Initialize()), before the game starts. Override it and load your content there. Store the texture in a private field. \$\endgroup\$ Jul 26, 2011 at 5:56
  • \$\begingroup\$ This is just for a simple demo and I don't see the need to build an underlying framework that could support boatloads of entities at once. I doubt I'll ever have more than a dozen total entities (2 ships, 5 bullets each). I don't want more than 5 bullets per ship available, ever. In my main Game.cs Initialize(), there is the following code: myShip = new Ship(this);. Doesn't this call the Ship constructor, which in turn would call the Bullet constructor 5 times, and load all their textures in turn? \$\endgroup\$
    – Bill
    Jul 26, 2011 at 16:14
  • \$\begingroup\$ @Bill: Without the code, I have no idea. Try stepping through the code in a debugger. \$\endgroup\$ Jul 26, 2011 at 16:24
0
\$\begingroup\$

It appears that my Update function was being called at least twice before anything was being displayed, and that even though the bullets were part of the collection they were becoming disabled before being drawn and thus textures not loaded (?!?).

By setting the lifetime (which is decremented once per Update, and when lifetime = 0 the bullets are no longer Visible/Enabled) of each Bullet to 3 or greater (this may vary depending on CPU speed?) when I instantiate the Bullets as part of the ship class, the textures are properly loaded at the beginning of the game.

I'm still not sure why manually setting them to Enabled/Visible at creation doesn't force the texture to be loaded.

\$\endgroup\$
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .