|
|
View previous topic - View next topic |
Author |
Message |
Gardon Scholar
Joined: 05 Feb 2006 Posts: 157
|
Posted: 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
|
Posted: 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
|
Posted: 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
|
Posted: 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
|
Posted: 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
|
Posted: 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
|
Posted: 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
|
Posted: 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
|
Posted: 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 |
|
|
|
Page 1 of 1 |
All times are GMT
|
|
|
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
|
|