Quote:Original post by programering
Quote:Original post by dmatter
If style is viciously impeding on getting things done then most programmers tend to opt for what works first and foremost; then they worry about how to make it better.
That's the kind of things which gets me stuck. I have difficulties to decide if should class or struct, pointer array or vector in the object definitions.
We'll there are no hard and fast rules, it's entirely up to you whether to use class or struct, in the end a struct
is a class.
Here's the rules of thumb I use:
If its going to have: methods (incl. constructor or destructor), private or protected data, or in someway require inheritance - then use a class.
If not, then it's only going to contain public data, if this is actually meant to represent only data (state) then I use a struct, otherwise I'm doing something more complicated and it depends on exactly what I'm doing.
Quote:And I thought my identifier prefixes was the standard, e.g. Hungary notation.
It's not the standard, it's just a convention. The actual standard C++ library doesn't use that convention, I don't use that convention and neither does jyk.
I use a convention known as CamelCase:
UpperCamelCaseForClassNames
lowerCamelCaseForMethods()
lowerComelCaseForVariables
BUT_ALL_CAPS_SEPARATED_BY_UNDERSCORES_FOR_CONSTANTS.
Quote:I don't mean class definitions, I mean object definitions you know in games; As monster definitions as an example, first you load the monster definitions which are the different types of monsters defined, then in your monster object(class or struct) decide which monster type definition you want that instance to be.
I mean object definitions as in game elements.
Ah, I understand now [smile]
What you may want to look into are some creational design patterns, like the abstract factory, factory method, builder and prototype patterns.
Found a good link.
Choosing the subjectively 'best' method does sort of depend on how you want to interface with this system and how many entites you might have, with what sort of control you want/need.
Based on the code you've presented so far, you seem to want to be able to create different types of entities from a single object description; so one way you might want to tackle this could be as so:
You have a structure that can fully describe how to initialise an entity instance:
struct EntityDescriptor{ std::string name; std::vector<Bitmap*> bitmaps; std::vector<Sequence*> sequences; EntityController* controller; /* Anything else here */};
N.B. You might want to consider using smart pointers or references instead of raw pointers, otherwise you need to decide who owns the actual instances.
Now you also have an entity class that can construct itself from a description by taking the attributes it's interested in:
class Entity{public: // Take whatever attributes we care about for construction. Entity(const EntityDescriptor& desc); void update(); void render();private: std::string name; Bitmap image; EntityController& controller; vector2D position; float angle; // etc};Entity::Entity(const EntityDescriptor& desc){ name = desc.name; // copy the name image = desc.bitmaps[ 0 ]; // take the 1st bitmap controller = *desc.controller; // take the controller position = controller.getStartPosition(); // take the start position angle = controller.getStartOrientation(); // take the start angle}
Then you have a factory that can create actual scene entities.
Here's a simple one (with no error checking), it stores prototypes of EntityDescriptors and when an entity needs to be created it finds the suitable description and passes that to the entity's constructor:
class EntityFactory{public: // Adds a description of an entity to the factory. void addEntityDescriptor(const EntityDescriptor& desc); // Creates and returns a new entity instance. Entity* create(const std::string name);private: std::map<std::string, EntityDescriptor> entityDescriptions;};void EntityFactory::addEntityDesctiptor(const EntityDescription& desc){ entityDescriptions[desc.name] = desc;}Entity* EntityFactory::create(const std::string name){ // Pass the description to the entity's constructor (should validate that 'name' actually exists in the map.) return new Entity( entityDescriptions[name] );}
So with all that in-place you can now add descriptors of entities to a factory at load-time and then whenver you want to spawn an entity you can ask the factory to find a suitable descriptor and construct an entity using it...
// Load the different entities that make up the game (probably from an external game file, but i've used hard-coded constants here)void Game::loadEntityDescriptors(){ this->entityFactory.addEntityDescriptor( Game::PLAYER_DESC ); this->entityFactory.addEntityDescriptor( Game::GHOST_DESC ); this->entityFactory.addEntityDescriptor( Game::TREE_DESC ); this->entityFactory.addEntityDescriptor( Game::WATER_DESC ); // // Create a forest description // // Take the generic tree descriptor as a starting point EntityDescriptor forestDesc = Game::TREE_DESC; // Replace the tree controller with a forest controller forestDesc.controller = &this->forestController; // Change the name forstDesc.name = "Forest"; // The density of trees in the forest this->forestController.setTreeDensity(10); // Add to the factory this->entityFactory.addEntityDescriptor( forestDesc );}// Create a forestvoid Game::spawnForest(){ this->forestController.randomiseSpawnPoint(); this->entityPool.add( this.entityFactory.create("Forest") );}
Well there you go. Hopefully that gives you some ideas.
One other thing worth mentioning - with the configuration of entities, their logic (the controllers) and their representation (bitmaps), you can look into the Model-View-Controller (MVC) idiom. The code I presented above is based on the snippets you provided, better use of the MVC pattern can lead to a cleaner and more flexible design overall [smile]
[Edited by - dmatter on January 1, 2008 6:27:05 PM]