RPGDXThe center of Indie-RPG gaming
Not logged in. [log in] [register]
 
 
Post new topic Reply to topic  
View previous topic - View next topic  
Author Message
Gardon
Scholar


Joined: 05 Feb 2006
Posts: 157

PostPosted: Mon Feb 20, 2006 5:34 pm    Post subject: Tower [quote]

Is there a way i could make some sort of gigantic coding database tower that I could save all my info in between classes and use sparingly?

What I mean is, rather than have each class keep track of the other classes variables it needs to keep track of, is there a way to set up a big storage area that I can send and retrieve data from (database i guess) without having to deal with the disgustiness of handling other class variables?

Say the input class updates the players position every time a button is clicked. Rather than having to retrieve the data from the input class in my Engine class, I could just call "Whatever"->GetInput() and it would send me the data needed. I could call "Whatever"->GetInput() from any class, anywhere.

Is this what a singleton is? I've read some stuff on it, but I'm still not totally sure on how to use one or why you would use it.

thanks,

Jasno
Back to top  
zenogais
Slightly Deformed Faerie Princess


Joined: 10 Jan 2006
Posts: 34

PostPosted: Mon Feb 20, 2006 8:47 pm    Post subject: [quote]

This sounds like a case of bad design to me. I'd recommend the Observer pattern for this, because then you wouldn't even have to manually retrieve the data on input, you'd have something like this:

Code:

// Class player inherits from class keyboardListener
class player : public keyboardListener {
public:
  ... class stuff
  const void onKeyDown(const Uint8_t * const keys) {
      if ( keys[SDLK_RIGHT] ) {
          m_direction = DIRECTION_EAST;
      }
  }
};

player theDude;

input.attachKeyboardListener( (keyboardListener *)&theDude );

while ( engine.Running( ) ) {
   engine.Run( );
   // Dispatches keyboard events to all registered keyboard listeners
   input.Update( );
}


This is the easiest way to do stuff like this, and your player is automatically updated when there is relavent input (keyboard input) available. Inside the input class you'd probably using a vector for each kind of listener, and dispatch relevant events to those listeners that asked for them.
Back to top  
Gardon
Scholar


Joined: 05 Feb 2006
Posts: 157

PostPosted: Mon Feb 20, 2006 8:58 pm    Post subject: [quote]

I'm just trying to find the easiest way to do this. This is my first attempt at an RPG, and I'm trying to make it so it's readable, playable, and maintainable.

I'd prefer not to really get into tons of complex stuff this first time around, as it'll probably keep setting me back and make it so I never finish, but I do want a good design in my game that works.

Any suggestions on how to handle input and use it for the map, player, etc.?

Thanks,

Jason
Back to top  
zenogais
Slightly Deformed Faerie Princess


Joined: 10 Jan 2006
Posts: 34

PostPosted: Mon Feb 20, 2006 9:18 pm    Post subject: [quote]

I just gave you the easiest possible way to manage your input. It would probably take you all of 30 minutes to implement.

EDIT: If you want the absolute easiest system then you can do something like this:

Code:

class player : public updatable {
    ....
    const void update(mouse_data& data, keyboard_data& data) 
    {
        // react...
    }
};

player theDude;

engine.addObject( (updatable *)&theDude );


Then in engine.Run you iterate through all the updatable objects and call their update function with the current mouse and keyboard state.
Back to top  
Gardon
Scholar


Joined: 05 Feb 2006
Posts: 157

PostPosted: Mon Feb 20, 2006 11:57 pm    Post subject: [quote]

thank you
Back to top  
LeoDraco
Demon Hunter


Joined: 24 Jun 2003
Posts: 584
Location: Riverside, South Cali

PostPosted: Tue Feb 21, 2006 7:21 am    Post subject: [quote]

Hey zenogais: while my expertise in C++ could be said to be lacking in certain areas, why are you suggesting that cast operation? On the one hand, if the two methods you suggest --- Engine::addObject and Input::addKeyboardListener --- are written to accept the baseclasses you define, then the cast should not be needed. On the other hand, those are old, c-style casts, which are generally frowned upon by a lot of people in the community. (E.g., that's what the four cast operators are for.)
_________________
"...LeoDraco is a pompus git..." -- Mandrake
Back to top  
zenogais
Slightly Deformed Faerie Princess


Joined: 10 Jan 2006
Posts: 34

PostPosted: Tue Feb 21, 2006 1:54 pm    Post subject: [quote]

LeoDraco wrote:
Hey zenogais: while my expertise in C++ could be said to be lacking in certain areas, why are you suggesting that cast operation? On the one hand, if the two methods you suggest --- Engine::addObject and Input::addKeyboardListener --- are written to accept the baseclasses you define, then the cast should not be needed. On the other hand, those are old, c-style casts, which are generally frowned upon by a lot of people in the community. (E.g., that's what the four cast operators are for.)


The cast operation may not be "required", but part of being explicit in programming is showing what you mean to happen (even though the compiler would do it behind the scenes) - in this case a cast. Adding the cast has no performance hit, but instead moves into the foreground something that would have just happened in the background. If you wanted to, you could instead type all this:

Code:

reinterpret_cast< updatable * >( &object );


I sometimes get lazy and just do the C-style casts because I dislike all the extra typing. If you use them properly, however, they're just as safe as the C++-style casts (which only add type-checking at compile-time).
Back to top  
LeoDraco
Demon Hunter


Joined: 24 Jun 2003
Posts: 584
Location: Riverside, South Cali

PostPosted: Wed Feb 22, 2006 7:27 am    Post subject: [quote]

zenogais wrote:
The cast operation may not be "required", but part of being explicit in programming is showing what you mean to happen (even though the compiler would do it behind the scenes) - in this case a cast. Adding the cast has no performance hit, but instead moves into the foreground something that would have just happened in the background.


Sure, but there remains the fundamental question: that need for explicitness should not even exist; if you know enough about an object's interface to know that it accepts a certain type of parameter, than it is redundant to throw in the explicit cast. Granted, in a system of imperfect information, you do not necessarily know everything in a system; however, I find that a vacuous argument, especially for small projects: to use a system (in this case, one object's interface and another set of objects which may be used with it), you would need to know the system. Add in the fact that reinterpret casts allow for more shoot-yourself-in-the-foot programming than the three other casts, and the potential for headaches can become massive. (Not that arguing potentials is ever a valid basis for judgement.)

Quote:

If you wanted to, you could instead type all this:

Code:

reinterpret_cast< updatable * >( &object );


I sometimes get lazy and just do the C-style casts because I dislike all the extra typing.


First off, that is the worst C++-style cast operator to be used for object hierarchies: static_cast would be better (in this case) where there exist no ambiguities at compile time, and dynamic_cast should be used otherwise. You know, because they don't circumvent the type hierarchy the way reinterpret_cast does. As is the case in your examples, the type you are casting from (the derived class) and the type you are casting to (the base class) are related, so even if you wanted to make the information more explicit --- say, for that mythological beast, the self-documenting-code --- you should at the very least use the tightest possible coupling between the two, while still retaining some of the abstraction granted by the OO constructs involved.

Second, at least according to one person in the know, while not a hard and fast rule, casts should probably be avoided whenever possible; the reason for all that extra typing is probably due to the utter ugliness of the operation.

Quote:
If you use them properly, however, they're just as safe as the C++-style casts (which only add type-checking at compile-time).


As information can be found here, for the utterly curious, dynamic_cast allows for, and is mostly intended for, RTTI, and is generally used for run-time type-checking; as noted, it does perform as much static type-checking as it can, but allows for run-time checking when necessary.
_________________
"...LeoDraco is a pompus git..." -- Mandrake
Back to top  
zenogais
Slightly Deformed Faerie Princess


Joined: 10 Jan 2006
Posts: 34

PostPosted: Thu Feb 23, 2006 1:34 am    Post subject: [quote]

reinterpret_cast was certainly a poor choice in this circumstance. I appreciate your resources on the casting types and found them very helpful and insightful. I suppose doing low-level C programming for so long tends to make one wary of C++ operations as they're notorious for code bloat and other nasty side effects. This is, however, a non-issue on modern hardware, but old habits die hard I guess. I'll certainly be looking through all my code now and converting C-style casts to C++-style casts.
Back to top  
Post new topic Reply to topic Page 1 of 1 All times are GMT
 



Display posts from previous:   
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum