I'm not sure if this exact question has been asked before, but all I could find were questions about how to work with GameComponent, or why something wasn't working.
I understand that you overload the Initialize, Draw, and Update methods with your own code, and XNA will then invoke them when the time is right. But what exactly is the purpose of Initialize? If you're writing something that extends from GameComponent, why wouldn't you just put all your initialize logic in the constructor?
For example, if my classes have a reference type that needs to be initialized, such as a collection or dictionary, I make of point of doing so in the constructor, and this pattern follows me into my GameComponent class design.
EDIT: Having worked with it a bit more, it looks like the primary purpose is to allow for more flexibility.
For example, IGameComponent
merely exposes one method -- Initialize()
-- and by implementing this, you are allowed to plug it into the Game.Components
collection. This means that GameComponent
, with all of its various properties, even the reference to Game
, is just an implementation detail.
Another use I've found is when one component contains a collection of other components. In this case, the constructor for the container is called, and you now have empty collections. This pattern allows you to populate the collections, then call the initialize on both the parent and children objects.
I'm still stumped as to what I would specifically put into Initialize, but I understand the reasoning behind it.
Answer
The reason you wouldn't put the initialize logic in the constructor is because Initialize
is the first point where you can be sure that GraphicsDevice
is set up.
Recall that, while your constructor for your Game
-derived class may create GraphicsDeviceManager
, the graphics device itself is only created when Game.Run()
is called (an instance method, so it requires an instance, which requires calling the constructor).
A more interesting question would be: Why is there Initialize
and LoadContent
? Why not just LoadContent
?
Partly this goes back to XNA 1.0 (there's a certain degree of backwards-compatibility in the API). Back then, there was no LoadContent
method, but instead there was a LoadGraphicsContent
method. That method would get called whenever the graphics device was reset, in order to reload all of your GPU resources - such as textures (you were expected to handle this correctly).
(Aside: A device reset can happen if the user minimises the window, locks their workstation, etc.)
From XNA 2.0 onwards, XNA will automatically reload textures (and other GPU resources) for you - and the method was renamed LoadContent
. Although, in the very rare case where the automatic-reload fails, XNA will still call LoadContent
to attempt to recreate the resources from scratch.
(Most people don't bother writing LoadContent
carefully enough to handle this situation correctly.)
In either case, having an Initialize
method gives you a separate code-path that is only called once at startup, when the graphics device is available, but is not part of the reset-handling.
The methods in (Drawable
)GameComponent
are the way they are largely to mirror what is in Game
, but the same reasoning as above applies.
You might also find this answer interesting.
No comments:
Post a Comment