Jump to content
  • Advertisement
Sign in to follow this  
39ster

OOP design

This topic is 3611 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm struggling with code design in OO programming. What is the "correct" way to do this: I have a class called "Map" and this class needs to Update objects called "Characters" Do i do it like this:
void Map::Update(float deltaTime)
{
  for(std::list<Character*>::iterator it = characterList.begin(); it != characterList.end(); ++it)
  {
    Character* character = *it;
    
    //Simulate the character (Character::Update does the simulation)
    character->Update(this, deltaTime);
  }
}
or
void Map::Update(float deltaTime)
{
  for(std::list<Character*>::iterator it = characterList.begin(); it != characterList.end(); ++it)
  {
    Character* character = *it;
    
    //Simulate the character
    character->IncreaseVelocity(deltaTime);
    
    if(PlaceFree(character->GetX(), character->GetY() + 1))
    {
      character->MoveDown();
    }
    ...
    ...
  }
}

Share this post


Link to post
Share on other sites
Advertisement
To me it's a bit questionable whether a map should be explicitly coupled to the characters at all. The map doesn't 'own' the characters - it can exist independent of the characters. The characters presumably need to make decisions about their whereabouts, so they will need some way to percieve the map. I get the feeling you're using the map in two ways: first, to maintain state about the 'world' (which a map does, in the traditional sense) but also as a container for the things in the map. In real life you can't change the world by manipulating a map, so unless there's a good overriding reason to do so in code it's probably a good idea to separate these different functionalities.

For instance, having a map require the elapsed time in order to perform it's function seems immediately unusual compared to my understanding of what a 'map' does. As long as the map reflects what's in the world, does it matter how long it is since I last looked at it? If your characters are managed separately (by a process that does require timing) the map's time-dependence wouldn't exist.

Share this post


Link to post
Share on other sites
Quote:
Original post by PKLoki
To me it's a bit questionable whether a map should be explicitly coupled to the characters at all. The map doesn't 'own' the characters - it can exist independent of the characters. The characters presumably need to make decisions about their whereabouts, so they will need some way to percieve the map. I get the feeling you're using the map in two ways: first, to maintain state about the 'world' (which a map does, in the traditional sense) but also as a container for the things in the map. In real life you can't change the world by manipulating a map, so unless there's a good overriding reason to do so in code it's probably a good idea to separate these different functionalities.

For instance, having a map require the elapsed time in order to perform it's function seems immediately unusual compared to my understanding of what a 'map' does. As long as the map reflects what's in the world, does it matter how long it is since I last looked at it? If your characters are managed separately (by a process that does require timing) the map's time-dependence wouldn't exist.

I'm confused. Not exactly sure what you mean but i pass the deltaTime to Map::Update() so Map::Update() can pass it to the characters for movement (like x += 2 * deltaTime)


EDIT: Are you saying to do have "Map* map" a member of "Character" like:

Character::Map* map ?


And then update the characters?

Share this post


Link to post
Share on other sites
From the limited information you have given, I can deduct that only the "character" needs to know about the "map", because it needs to extract collision information from it during updates. The "map" does not need to know about the "character", because there is no information in the "character" that the map needs to perform its duties. In fact, in your case the map doesn't even need to update since its main purpose is just to store collision information. While the "character's" purpose is to update its movement while avoiding collisions. If "characters" need to collide with other "characters", then add a method called markPlace(int x, int y), to the "map" class, that will allow characters take over a cell and other characters who check for that cell, will know its taken.

So that means you should just store the list of "players" and the "map" in a separate "game" class. And then in your the update() ( or run() ) method of your "game" class you: loop through your "characters", call their update() method, and pass a reference to the "map" class.


void Game::Run()
{
while(!gameOver)
{
for each character
{
character.update(map, deltaTime);
}
}
}



Share this post


Link to post
Share on other sites
Thanks Snisarenko, precisely what I meant - the map isn't the logical place to update your characters. The characters use the map to make decisions about where to go, then tell the map that they have moved in order for it to update it's representation of the world. The map can maintain an abstraction of where the characters are without maintaining reference to the actual characters, and certainly not 'owning' those references. The abstraction is then queried by the characters as part of their decision making process when something else (their own dedicated collection class, for instance) tells them to update.

Basically, characters' response to the map is up to the characters based on their knowledge of the map. The characters' decisions are not up to the map based on it's knowledge of the characters.

Share this post


Link to post
Share on other sites
I think the disagreements here are more because of name choosing than anything else; the OP names 'map' what we more traditionally will call 'World' or sometimes 'Game', while the other posters think 'map' as 'static geometry' or 'terrain'. It certainly makes sense for the World to keep lists of its entities, such as characters,maps/terrains,lights,etc...

Now, I'm not sure though that passing the map as a parameter to character is a good idea, as it makes a low-level module(the character) depend on a higher-level one(the map), and it increases coupling. It's a better idea to pass only the relevant bits of information that are needed. Also, I don't think the Character::Update() should handle the collision detection, this seems more of a job for a Physics module that have knowledge of character and map geometry and can update their velocities/positions accordingly.

Share this post


Link to post
Share on other sites
Hmm, guess i'll be a bit more clear of what "class Map" is and what it can do.

First off, the game is a 2D Platform game.
Map pretty much contains all the level information such as Tiles, Walls, Backgrounds, Enemies (Character), Players (Character), Items (Character, until touched, then it passes on it's item class to the player), Warp fields, etc.

The game needs to be able to "Simulate" multiple Maps at the same time because the same source code will be used to program the Server (different build target, but alot of the source code will be the same) and one server will be able to host multiple maps.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!