Loader class dependencies.

Started by
6 comments, last by FReY 18 years, 10 months ago
I've been thinking recently about the dependence of smaller objects on their loaders. For example my sprite animation class right now is self-dependant, it loads the animation file and is able to play it. The next evolution of this class will extend to animation instances, where I have an animation loader which stores an animation sequence and frames. The instance handles a specific sequence of frames all at different times relative to other instances. This is quickly how it works now.

cSprAniLoader loader;
loader.create(&graphics, "myspr.spr");
loader.action("idle");

DWORD timedif = 0;
timer.start();
while(1){
timedif = timer.timedifference();
loader.update(timediff);
loader.draw();
timer.present();
};

This is kind of how I want it to work.

cSprAniLoader loader;
cSprAni	sprani1;
cSprAni	sprani2;
loader.create(&graphics, "myspr.spr");

sprani1.create(&loader);
sprani2.create(&loader);

sprani1.action("idle");
sprani2.action("walk");

DWORD timedif = 0;
timer.start();
while(1){
timedif = timer.timedifference();
sprani1.update(timediff);
sprani2.update(timediff);
sprani1.draw();
sprani2.draw();
timer.present();
};


My question is, in cases where there are loaders how 'attached' should the object instances be to them? Should the instances be updating themselves, or should they be passed to the loader to get updated? If neither, is there a better or more efficient way of doing something like this? Thanks. :)
Advertisement
Why do you need a separate class for the loaders? I just have a Load() member function and that works ok. Sometimes it's cleaner to implement it as a static factory method but I've never felt a need to use a separate class.
Well, I'm not an expert, but the way I've been doing it is I have a seperate interface for loading read-only resources like images, sounds, and config files. Basically, when a Sprite object is created, it asks my Resource system for the appropriate images, which are specified in my config file. My Resource system takes care of all the loading and cacheing of data, and nothing else. My Sprite object does all the updating; if it needs a new image, it asks the Resource system for it.
-----http://alopex.liLet's Program: http://youtube.com/user/icefox192
Let me make sure I understand you correctly. You are trying to separate the properties and graphics of sprites that are used across all sprite instances from the actual sprite instances themselves, so you can individually control the sprite instances without having multiple copies of the never-changing properties and graphics.

I use the term sprite base as the class that holds the never-changing properties and graphics that are used across multiple sprite instances. A sprite instance I call the unique unit in the game. So if you have 50 soldiers, all using the same graphics, you have 50 sprite instances but only one sprite base. The sprite base would contain the graphics, animation sequences, etc that all of the instances reference. The sprite instances would contain the position and current animation state of the unit soldier.

You are definitely on the right track by recognizing the difference. I see you have a loader which the sprites use to get their graphics from. Realize, however, that the loader does more than just load. It STORES the graphics and frees them when you are done. Loader sounds temporary, when, in fact, your Loader should be stored for the same duration of time as the sprite instances, if not longer.

Now when you go to program this all, one of your questions involved who should update what. If you think of a sprite base as an omnipresent access point for the sprite instances, and nothing else, it doesn't make much sense for the sprite base to do the updating. After all, the sprite base really should have no knowledge of the sprite instances. The instances are like little creatures that leech off of the base. All of the updating code, therefore, should be done in the instances.

Now, it's possible to take this concept even further. The original idea was to have a Loader which only loads the graphics once. However, it's possible that another part of the code will load the same graphics for another purpose, say the GUI. So you may also want to have a surface manager that keeps track of all the surfaces themselves and checks if multiple copies of the same surface are being loaded. The sprite bases would have ways to reference their graphics in the surface manager. Therefore, the sprite bases would be leeches to another set of resources.

Once you start coding it, it will all fall together nicely. Just don't stop thinking about ways to better your code.
....[size="1"]Brent Gunning
Alright, that's exactly what I was thinking. I just wasn't sure if the method I was using was an effective choice.

I have a resource class right now that has an inhertiable base class and is inhertied by the texture, sound and other resource classes. The SpriteAnimation class already utilizes this code to make sure that there is no duplicate textures when loading.

I have another class for static sprites, which I'm thinking of converting in to a multipurpose class for static and animated sprites.

class cSprite{protected:	cGraphics*	graphics;	cTexture*	texture;	RECT		pSrcRect;	D3DXVECTOR2 m_view;	D3DXVECTOR2 m_scale;	D3DXVECTOR2 m_position;	D3DXVECTOR2 m_center;	float		m_rotation;	D3DCOLOR	m_colour;public:	cSprite();	~cSprite();	bool Create(cGraphics* pGraphics, D3DXVECTOR2* pViewWindow );	void Free();	void Mask(long left, long top, long right, long bottom);	void Scale(float ScaleX, float ScaleY);	void Move(float PosX, float PosY);	void Center(float CenterX, float CenterY);	void CenterMask();	void Rotate(float radians);	void Colour(uint8 Red, uint8 Green, uint8 Blue, uint8 Alpha);	bool Texture(cTexture* pTexture);	bool Draw(float value = 0.0f);	float GetXScale();	float GetYScale();	float GetXPos();	float GetYPos();	float GetXCenter();	float GetYCenter();	float GetRotation();	DWORD GetColour();};


I'll try it and see what I get.

Quote:Original post by Kylotan
Why do you need a separate class for the loaders? I just have a Load() member function and that works ok. Sometimes it's cleaner to implement it as a static factory method but I've never felt a need to use a separate class.

The loader has all of the animation sequences and animation frames, the sprites will just have a pointer to the animation seqence so this way I can use the same sprite at different time intervals.
I guess I just don't understand your terminology - the word 'Loader' to me implies a class that reads data from disk, creates a data structure from it, and then disappears.

If your loader class is just a sort of central store for all the frames for a given character, I'd probably structure the code very differently to make it look more like typical C++ paradigms:

cSprAniLoader loader(&graphics, "myspr.spr");cSprAni	sprani1 = loader.create("idle");cSprAni	sprani2 = loader.create("walk");
One of the things that I don't want is having to update each of the sprite objects by their loaders, what if I had 300 loaders? I'd be better off having a pointer in the sprite object that points to the loader, that would eliminate a lot of problems.
Quote:
One of the things that I don't want is having to update each of the sprite objects by their loaders, what if I had 300 loaders? I'd be better off having a pointer in the sprite object that points to the loader, that would eliminate a lot of problems.


Have a sprite 'manager'. When you load a sprite, you add it to the sprite manager and then you update the manager. The manager will then update each of the sprites it is managing. eg:

cSprAniLoader loader;cSprManager   manager;cSprAni	sprani1;cSprAni	sprani2;loader.create(&graphics, "myspr.spr");sprani1.create(&loader);sprani2.create(&loader);sprani1.action("idle");sprani2.action("walk");manager.addSprite(&sprani1);manager.addSprite(&sprani2);DWORD timedif = 0;timer.start();while(1){  timedif = timer.timedifference();  manager.update(timedif);  manager.draw();  timer.present();};

do unto others... and then run like hell.

This topic is closed to new replies.

Advertisement