Conan wrote:does anyone have a simple worked example? I have to admit to using 'method 1' and have not seen the virtual function approach in action so I'm not sure how it works.
Well, since starting this thread, I've made some good progress on my game using method 2, and, while I don't have a
simple example to post, I'll take a shot at coming up with something 'on-the-fly'. I can't guarantee that this will work as-is, but it should give you an idea of what we're talking about:
As a simple example, say we want to write a game that displays a blue screen or red screen, depending on the game 'mode' (Not a terribly
fun, game, I realize, but I'm not ambitious).
To use 'method 2', we must first create a base class for the modes we'll be using in the game.
- Code: Select all
1 2 3 4 5 6
| // CModeBase - Base class for all game modes class CModeBase { public: virtual void Update (Display* pDisplay) = 0; // (The '= 0' makes this class 'pure virtual' };
|
| 6 lines; 4 keywds; 1 nums; 9 ops; 0 strs; 2 coms Syntactic Coloring v0.4 - Dan East |
Of course, with a real game, we would likely also include virtual functions for ButtonDown, StylusDown, etc, and maybe some member variables shared among the modes.
Then we can create specific mode classes derived from the base class. For instance, a 'CModeBlue' class that colors the screen blue and a 'CModeRed' to color it red.
- Code: Select all
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| // CModeBlue - Colors the screen blue class CModeBlue : public CModeBase // derived from CModeBase { public: void Update (Display* pDisplay) { pDisplay->Clear (Color (0, 0, 255)); } };
// CModeRed - Colors the screen red class CModeRed : public CModeBase // Also derived from CModeBase { public: void Update (Display* pDisplay) { pDisplay->Clear (Color (255, 0, 0)); } };
|
| 19 lines; 8 keywds; 6 nums; 38 ops; 0 strs; 4 coms Syntactic Coloring v0.4 - Dan East |
Now let's assume that this game will be using PocketFrog's game framework. In our main game object, we need to include a CModeBase pointer as a member variable (or a global variable, I suppose...), like so:
- Code: Select all
1 2 3 4 5 6 7 8
| // Our game class 'CFunGame' (A bit of a misnomer) class CFunGame : public Game { . . // Misc. function and variable definitions... . CModeBase* m_pMode; }
|
| 8 lines; 2 keywds; 0 nums; 8 ops; 0 strs; 2 coms Syntactic Coloring v0.4 - Dan East |
Let's say we want to start out with a blue screen. In our GameInit function, we do the following:
- Code: Select all
1 2 3 4
| bool CFunGame::GameInit () { m_pMode = new CModeBlue; }
|
| 4 lines; 2 keywds; 0 nums; 8 ops; 0 strs; 0 coms Syntactic Coloring v0.4 - Dan East |
Now, believe it or not, most of the work's done. Thanks to C++'s
polymorphism (I think) capability, anytime we need to update the screen (i.e. in the GameLoop function), we just call m_pMode->Update (
pointer to the display); And a blue screen will be displayed. For instance:
- Code: Select all
1 2 3 4 5 6
| void CFunGame::GameLoop () { Display* pDisplay = GetDisplay (); m_pMode->Update (pDisplay); // Tells the current mode to update the screen pDisplay->Update (); // Updates the screen }
|
| 6 lines; 1 keywds; 0 nums; 21 ops; 0 strs; 2 coms Syntactic Coloring v0.4 - Dan East |
When you want the screen to change to red, do the following:
- Code: Select all
1 2
| delete m_pMode; // Get rid of the blue mode object m_pMode = new CModeRed;
|
| 2 lines; 2 keywds; 0 nums; 3 ops; 0 strs; 1 coms Syntactic Coloring v0.4 - Dan East |
Then, without changing our GameLoop function, the screen will be red! By changing the object pointed to by m_pMode, we can change back and forth between blue and red, blue and red, blue and red... makes one giddy just thinking about it!
Of course, this is just a simple example. This technique is, in fact, very powerful and quite versitile, as I'm learning. Why, with just a few changes, we could paint the screen green, yellow, purple or cyan, even!
Seriously, though, I'm glad the kind forum members here convinced me to go this route. There is quite a lot that you can do. For instance, in my game, I also pass button and stylus events to the current mode, so they're handled differently based on what the game is doing at the moment. Depending on the mode my game is currently in, pressing a hardware button may open a menu, advance to the next mode, or even quit the game abruptly (undocumented feature...).
Anyway, that's how I'm doing it. Hopefully, I haven't made
too many errors. I'll be happy to clarify any points I've muddled, just ask. Perhaps someone more experienced than I can clarify or correct this, as needed.