Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411809 Posts in 69416 Topics- by 58462 Members - Latest Member: Moko1910

May 29, 2024, 02:46:34 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)Resource Management in C++
Pages: [1]
Print
Author Topic: Resource Management in C++  (Read 2946 times)
TheLastBanana
Level 9
****



View Profile WWW
« on: September 20, 2010, 07:51:36 PM »

I've been working on two different games in C++, and they're my first. I've learned plenty along the way, but there's one thing that's still bugging me: one game loads resources externally, simply because I wanted to make it easy to mod. However, for the other project, it seems really unnecessary to include all the extra work to load data externally when it's a fairly small game. However, being somewhat new to C++, I'm trying to wrap my head around how one would deal with resources like that.
To be a bit more specific, I've got my sprites all loaded externally. That much I'm fine with. However, I'm trying to determine how to manage all the sprites in the game's engine. For instance, when an enemy is spawned, how will I define what sprites it should use? Is it a good idea to have a manager of some kind that stores all the sprites by name, so I can call on it from there?
As well, on a different topic, should enemies with different behaviours have different classes, or is there a neater technique for dealing with all of that?
Just curious how other developers deal with things like this. I'm finding it's the one thing holding me back from just sitting down and making a game - I always end up getting caught trying to choose how to handle silly things like this.
Logged
Aquin
Level 10
*****


Aquin is over here.


View Profile WWW
« Reply #1 on: September 20, 2010, 09:02:48 PM »

Man, I don't have much of an answer.  My code tends to get a bit messy.

Still, I like to use the same superclass for all of my enemies and maybe another superclass for all of their missiles (or whatever.) 

Also, as for how the sprite animations are handled, I suppose there isn't anything stopping you from doing it externally.

You know what?  Some guy is gonna come in here and go on about Lua.  I suggest listening to that guy.
Logged

I'd write a devlog about my current game, but I'm too busy making it.
TheLastBanana
Level 9
****



View Profile WWW
« Reply #2 on: September 20, 2010, 09:04:41 PM »

I'm all for Lua. I use it all the time. I just don't feel like this is a big enough project to go ahead and implement that extra layer of functionality. Then again, if it's actually easier to do that, maybe it's not a bad idea.
Logged
flavio
Level 4
****



View Profile WWW
« Reply #3 on: September 20, 2010, 09:26:45 PM »

For instance, when an enemy is spawned, how will I define what sprites it should use?
You should create a new instance of your enemy class. That instance should know what sprites it should use. And this must be programmed by you.

Another solution could be to define a file (for example an XML one) that contains the sprite information (sprites, ...) and, when you create a new enemy, you use these information.

Is it a good idea to have a manager of some kind that stores all the sprites by name, so I can call on it from there?
Yes, this is a valid solution, but I think that if you separate code and assets (so, you allow to define a sprite via an XML file), this will lead you to a cleaner code and a simpler management of assets.

should enemies with different behaviours have different classes, or is there a neater technique for dealing with all of that?
If you haven't a solid AI engine (that allows you to define these things), yes, the best solution when you're dealing with behavioural differences is to provide different classes.

Just curious how other developers deal with things like this.
As I said, I separate "code" and "design" (so, sprite management from specific sprite definitions), and, if possible, I use AI techniques, otherwise (if the logic of behaviours is simple enough) I code it.
Logged

Skofo
Level 10
*****



View Profile
« Reply #4 on: September 20, 2010, 09:28:18 PM »

This seems like a general programming question, not a C++ question... what did you use before C++?
Logged

If you wish to make a video game from scratch, you must first invent the universe.
TheLastBanana
Level 9
****



View Profile WWW
« Reply #5 on: September 20, 2010, 09:33:24 PM »

I've used Game Maker pretty extensively and done a lot of modding of games with Lua, so I'm used to having this particular side of things dealt with.
From what I'm hearing, my original approach of getting this kind of data from an outside file seems to be the best way to go. I guess I'll take a look at implementing Lua. On second thought, I guess this question was really more of a standards kind of thing - is it okay to have something as specific as a definition of sprites in a C++ class, or is that considered bad form? I get the concepts, and I could certainly go ahead and do it, but I'd like to try and do it the right way. Then again, maybe there isn't a right way per se and I'm just overanaylzing this.
Logged
flavio
Level 4
****



View Profile WWW
« Reply #6 on: September 20, 2010, 09:40:27 PM »

is it okay to have something as specific as a definition of sprites in a C++ class, or is that considered bad form?
I can't see a better solution. Smiley
Logged

benbradley
Guest
« Reply #7 on: September 21, 2010, 02:18:57 AM »

I wouldn't worry too much about what's bad form or not when making your first couple of C++ games. You'll figure out what's good form for yourself, and if you have previous programming experience of Lua or anything else you'll figure it out much quicker. A lot of resources for teaching C++ try to teach you good practise at the same time as the language, a bit of that is good but I think sometimes it can be taken too far.

A class is basically some variables, and some functions which operate primarily on those variables. It's a wrapper to join related things together. Use that however you see fit! You'll start to see patterns of what works ok and what works really nicely.

And yeah, I would definitely hard-code your sprite definitions somewhere, either in a class or even one big function if there aren't too many types.
Logged
drChengele
Level 2
**


if (status = UNDER_ATTACK) launch_nukes();


View Profile
« Reply #8 on: September 21, 2010, 12:34:02 PM »

Quote
However, I'm trying to determine how to manage all the sprites in the game's engine. For instance, when an enemy is spawned, how will I define what sprites it should use? Is it a good idea to have a manager of some kind that stores all the sprites by name, so I can call on it from there?
I can't tell what would suit you the most, but, it would probably make your life a lot easier if you had some kind of "manager" if that's what you want to call it, which would handle textures, texture loading, unloading, and access for you. I personally do it by having a "graphics manager" class which loads and stores all textures internally. This manager is part of a framework I use in all my games.

In game code proper I usually define "entity blueprints" which among other things define stuff like, for example, maximum hit points, max movement speed, and which textures are used for sprites. A single blueprint can have multiple sprite layers, and for each layer I define every tidbit I need, such as texture ID, blit regions (if multiple sprites are tiled on the texture), alpha, colors, blend modes, animations, etc.

When rendering an entity it looks up its parent blueprint and gets all the info about sprites it needs to render and how. All the entity itself provides is where to draw it, rotation offset, opacity override, and animation sequence (if any).

Quote
As well, on a different topic, should enemies with different behaviours have different classes, or is there a neater technique for dealing with all of that?
What ever floats your boat. If "different behavior" means slightly different pathfinding or something like that, then most likely the answer is no. If it makes you feel any better, I have looked through the code of Source Engine games such as Half-Life 2 and Alien Swarm, and in them, every single enemy type or weapon is a separate class.

The most reasonable solution, one I implement, is to have separate classes if you really need them, but all of them derived from a single "entity" base class. That way you get the best of both worlds - you can make each class do its own stuff internally, but you can store, reference, and pass the objects around like they are all of a single "entity" type.

I mean, if you're going to use c++, it makes sense to make use of its more powerful concepts such as inheritance.
Logged

Praetor
Currently working on : tactical battles.
superflat
Level 10
*****



View Profile WWW
« Reply #9 on: September 21, 2010, 01:24:15 PM »

I prefer to use a factory class, which sound similar to what drChengele describes.

You tell it to create a sprite class by type-name, and it adds it to its internal sprite list (they all derive from the same Sprite superclass).  It may call an init() type function on each object it spits out, but I also use it to do some general stuff such as load the image... I like to have all image loads in one central resource, when hard-coding this sort of thing, but recently I've started doing a separate resource manager as drChengele also mentions, so that sprites can easily flick between resources without reload.

So to create a sprite, call something like:

SpriteManager->createSprite( "type" , X, Y ) [PSEUDOCODE]

In the SpriteManager.createSprite() method, or perhaps the Sprite.init() method, there would be a call to BitmapResources.getByName("this class' image name") which will dig out the one it needs.

Depends on the game I suppose...  And this may not be good practice - it's just how I've approached it in the past. Would love to know if this is a bad method also...  I'm assuming the question applies to all OO languages?
Logged

drChengele
Level 2
**


if (status = UNDER_ATTACK) launch_nukes();


View Profile
« Reply #10 on: September 21, 2010, 05:14:34 PM »

There really is no "right" and "wrong" way to do this. Just make it so it's clean, easy to use code and do what ever works for you.

I found it is good practice to always preload all your assets (except music, which is probably better off being streamed real-time) on game init or level load. There is really no reason not to do it, if you're not making an AAA title texture memory space is virtually a non-issue.
Logged

Praetor
Currently working on : tactical battles.
Glaiel-Gamer
Guest
« Reply #11 on: September 21, 2010, 08:28:59 PM »

The way mine works is:

Every file that needs to be shared in the game is defined externally in a custom binary format [text based would have been nicer for a few things but meh I didn't think ahead so I was forced to write editors for stuff]

[resources like shaders are handled differently since I never usually have more than 1 instance of a shader in my game anyway, and my sound engine needs to be revamped into a normal resource anyway so i'll ignore talking about those]

The core classes that get shared are:
Texture
Animation
Sprite

A texture is pretty much what it sounds like, just a PNG with a few extra data (a rectangle defining the area of the png that actually counts, usually is just the entire png, some functions for interfacing with the gpu with and junk).

An animation contains a texture and information on how many frames the animation contains and the size of the sprite sheet.

A sprite contains a list of animations and collision data for them. [bad decision on my part, most collision data should actually be in the individual animations.... but i overlooked that]


All 3 of those are defined in files, and shared. If I ask my resource manager for one of these, it returns a pointer to it and increases its use count. When I release one of these, its use count is decreased by one. Note I don't actually delete them manually, I call release on them. Between levels the manager will cull all resources that aren't in use.


When I construct an Object, I do so like this:
character = new Object(IO.Manager.getSprite("character.spr"));

when i delete the character it releases the sprite for me.
an Object contains physical information related to that sprite, while the sprite contains raw data used for rendering. An object will store state, so I can make a bunch of objects that all use the same sprite be in different states. These are defined in my code rather than in a file.

I usually derive Object and initialize the sprite in its constructor. Object defines an update function which I can override to provide different behavior to different objects. By default it just updates the animation state.
Logged
TheLastBanana
Level 9
****



View Profile WWW
« Reply #12 on: September 21, 2010, 09:33:28 PM »

Thanks for all the replies guys, that's really informative. I actually ended up with a really similar setup to what you guys described, but I just kind of assumed there must be a better way to do it, since there often is. It's a bit reassuring to hear that I've more or less hit the nail on the head with this one. Maybe now I can actually get around to making the game part of the game and not focusing so much on the engine Giggle
Logged
Hima
Level 4
****


OM NOM NOM


View Profile WWW
« Reply #13 on: September 25, 2010, 07:30:54 AM »

I've been wondering about this too so might as well share what I've done to my C++ game

Mine is pretty much like Glaiel-Gamer. I separate the resources information from the actual data. The resource information is defined in an xml file. For example, a sprite data might be something like

<sprite>
     <id>player</id>
     <texture>player.png</texture>
     <collision type="circle">
            <radius>10</radius>
     <collision/>
     <center x="0" y ="10" />
</sprite>

Then, I have a singleton class called ResourceManager that taking care of loading/unloading the resources. Though I don't have reference counting like Glaiel-Gamer has, which is a very good idea by the way :D.

I also separate the processes into two parts, registration and loading. Registration will take an xml file, and store all the information according to the xml file, without loading the raw data yet. For example, registering the xml above will not load the file "player.png".

The file will be loaded only when I call something like

GameEntity* entity = new GameEntity();
entity.setSprite("player"); // Passing a sprite ID here.

Then, the setSprite method will use all the information registered and assign it to the entity.

At first I was gonna use lua too, but I think these are data and lua should be use for something more programming-related and not data-definition like this. So I went with XML instead.


For the enemy behavior, maybe using a component-based design for your enemies might be better? Like, having a Behaviour class and then you can have same type of enemy with different behaviour instances so they act differently.

EDIT : Removed the quotes from texture.
« Last Edit: September 26, 2010, 03:30:48 AM by Hima » Logged

BorisTheBrave
Level 10
*****


View Profile WWW
« Reply #14 on: September 26, 2010, 02:11:31 AM »

Why does the texture element have quotes in it?
Logged
Hima
Level 4
****


OM NOM NOM


View Profile WWW
« Reply #15 on: September 26, 2010, 03:29:18 AM »

Sorry about that! No, it shouldn't have. I wrote it based on my memory so I made silly mistake like that X(
Logged

Floor is lava
Level 0
**


BEARS DON'T CARE


View Profile
« Reply #16 on: October 01, 2010, 04:32:22 AM »

The way I've always managed images in SDL was to keep them stored in a STL Map using the file name as the key. When loading an image the image manager will check the map to see if it is already loaded if it is it will return a pointer to the image.
Logged
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic