Subversion Repositories AndroidProjects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
244 chris 1
#ifndef __BOARD_H__
2
#define __BOARD_H__
3
 
4
//////////////////////////////////////////////////////////////////////////
5
//                                              Board.h
6
//
7
//      This is the third class to look at in this particular demo
8
//      (after main.cpp and GameApp.h/.cpp). The Board class is where most of
9
//      your actual game programming will go. It is here that we will do
10
//      all our game drawing, updating, and input processing. Of course, in
11
//      a larger application, you would probably do drawing and updating in
12
//      multiple files, but you would still most likely use something similar
13
//      to a Board class as the master game logic class. 
14
//
15
//      The reason that the Board class is a widget is because when a widget
16
//      is added to the GameApp's WidgetManager, it will automatically have its
17
//      Update and Draw methods called, and it will automatically receive input
18
//      at the appropriate times. Furthermore, by making it a widget and adding
19
//      it to the WidgetManager, the game logic loop, Update(), will be guaranteed
20
//      to run at a standard 100FPS on all machines. This is extremely important
21
//      as you always want your logic code to run at the same speed, but want
22
//      the drawing code to run as fast as possible. That way on faster machines
23
//      your program doesn't run its logic faster than on a slower machine.
24
//
25
//      You can think of the Board as a canvas upon which we do all our
26
//      drawing, and a central hub where if we need to, we instruct other
27
//      classes where and when to draw to.
28
//////////////////////////////////////////////////////////////////////////
29
 
30
#include "SexyAppFramework/Widget.h"
31
#include "SexyAppFramework/ButtonListener.h"
32
 
33
// Because we're going to be learning about some new widgets, we
34
// need to include some more listener classes so we can respond to each one.
35
#include "SexyAppFramework/EditListener.h"
36
#include "SexyAppFramework/CheckboxListener.h"
37
#include "SexyAppFramework/ListListener.h"
38
 
39
 
40
 
41
// We place all our classes inside the "Sexy" namespace to avoid name collisions
42
// with other libraries that might be added.
43
namespace Sexy
44
{
45
 
46
 
47
// Forward declare the graphics class. You will see the graphics class used
48
// and explained in Board.cpp: it is the main object used to draw all
49
// images, fonts, etc.
50
class Graphics;
51
 
52
// We maintain a pointer to the main game application in the Board class.
53
// The main game app contains functions that are often times needed
54
// by the Board class, such as registry reading/writing, file reading/writing,
55
// etc.
56
class GameApp;
57
 
58
// forward declare the widgets we're going to use in this demo:
59
class ButtonWidget;
60
class EditWidget;
61
class Checkbox;
62
class ListWidget;
63
class ScrollbarWidget;
64
 
65
// In this demo, we're going to do some more advanced things like 
66
// handle the two cases where Board is added and removed from the 
67
// WidgetManager.
68
class WidgetManager;
69
 
70
//////////////////////////////////////////////////////////////////////////
71
//////////////////////////////////////////////////////////////////////////
72
class Board :   public Widget, public ButtonListener,
73
                                public EditListener, public CheckboxListener,
74
                                public ListListener
75
{
76
 
77
        private:
78
 
79
                GameApp*                        mApp;
80
                ButtonWidget*           mButton1;               // We'll use these buttons for sound playing
81
                ButtonWidget*           mButton2;
82
 
83
                // These are explained in the C++ code, they are the new widgets we're learning about.
84
                EditWidget*                     mEditWidget;
85
                Checkbox*                       mCheckboxWidget;
86
                ListWidget*                     mListWidget;
87
                ScrollbarWidget*        mScrollbarWidget;
88
 
89
                SexyString                      mText;          // When we press enter on the edit box, we'll set this string and print it
90
 
91
                // Both are floats to ensure that the only difference in the movement demo
92
                // is the fact that one is updated in UpdateF and the other is in Update.
93
                float                   mMotionX;               // For our movement example, this is the X coordinate of the image as it moves rightward
94
                float                   mUpdateFMotionX;// Same as above, but only modified in UpdateF, to illustrate the difference in motion
95
 
96
        public:
97
 
98
                //////////////////////////////////////////////////////////////////////////
99
                //      Function: Board
100
                //      Parameters:
101
                //              theApp  - Pointer to the main application class
102
                //      
103
                //      Returns: none
104
                //////////////////////////////////////////////////////////////////////////
105
                Board(GameApp* theApp);
106
 
107
                virtual ~Board();
108
 
109
                //////////////////////////////////////////////////////////////////////////
110
                //      Function: EditWidgetText
111
                //      Parameters:
112
                //              theId           - Integer ID of the edit widget sending this message
113
                //              theString       - The contents of the edit widget
114
                //
115
                //      Returns: none
116
                //
117
                //      Purpose: Called whenever the return/enter key is pressed on
118
                //      an edit widget.
119
                //////////////////////////////////////////////////////////////////////////
120
                void EditWidgetText(int theId, const std::string& theString);
121
 
122
                //////////////////////////////////////////////////////////////////////////
123
                //      Function: AllowChar
124
                //      Parameters:
125
                //              theId   - Integer ID of the edit widget sending this message
126
                //              theChar - Character just typed in
127
                //
128
                //      Returns: 
129
                //              true    - Indicates that the character is acceptible
130
                //              false   - Indicates that the character is invalid
131
                //
132
                //      Purpose: Whenever an ASCII character is typed into the edit box,
133
                //      this method is called first. If the method returns true, then the
134
                //      character just typed is accepted and appended to the current edit widget
135
                //      string. If it returns false, the character is rejected and is not added.
136
                //////////////////////////////////////////////////////////////////////////
137
                bool AllowChar(int theId, char theChar);
138
 
139
                //////////////////////////////////////////////////////////////////////////
140
                //      Function: CheckboxChecked
141
                //      Parameters:
142
                //              theId   - Integer ID of the checkbox widget sending this message
143
                //              checked - Boolean indicating if the widget is checked or not
144
                //
145
                //      Returns: none
146
                //
147
                //      Purpose: Whenever a checkbox widget is checked or unchecked, this
148
                //      method is called. We're not actually going to do anything with this,
149
                //      we're just listing it here as an example of how you'd implement a
150
                //      function to respond to that event.
151
                //////////////////////////////////////////////////////////////////////////
152
                void CheckboxChecked(int theId, bool checked) {;}
153
 
154
                //////////////////////////////////////////////////////////////////////////
155
                //      Function: ListClicked
156
                //      Parameters:
157
                //              theId   - Integer ID of the listbox widget sending this message
158
                //              theIdx  - Integer indicating the index of the item selected in the list
159
                //              theClickCount   - An integer indicating which mouse button
160
                //                                              was pressed. One of the following:
161
                //                      1:  Left button
162
                //                      2:  Double-left-click
163
                //                      3:  Middle button
164
                //                      -1: Right button
165
                //                      -2: Double-right-click
166
                //
167
                //      Returns: none
168
                //
169
                //      Purpose: Called any time a list widget is clicked on. The list
170
                //      widget by default doesn't automatically select the item you clicked on,
171
                //      it instead calls this method and in here you manually select the item.
172
                //      This is to allow you to prevent the selection of certain items, such as
173
                //      disabled items, etc.
174
                //////////////////////////////////////////////////////////////////////////              
175
                void ListClicked(int theId, int theIdx, int theClickCount);
176
 
177
                //////////////////////////////////////////////////////////////////////////
178
                //      Function: Draw
179
                //      Parameters:
180
                //              g       - Graphics object used to draw all images and fonts to the screen.
181
                //      
182
                //      Returns: none
183
                //
184
                //      Purpose: Called automatically by GameApp's WidgetManager, this function
185
                //      is the main method that is responsible for all graphical and textual
186
                //      displaying.
187
                //////////////////////////////////////////////////////////////////////////
188
                virtual void Draw(Graphics* g);
189
 
190
                //////////////////////////////////////////////////////////////////////////
191
                //      Function: Update
192
                //      Parameters: none
193
                //      Returns: none
194
                //
195
                //      Purpose: Called automatically by GameApp's WidgetManager, this method
196
                //      is GUARANTEED to be called 100 times per second (100FPS) and is where
197
                //      all main game logic is performed. Of course, if you had a larger more
198
                //      complex game, you'd most likely divide your logic between several
199
                //      other files, but this is commonly the central place where all game
200
                //      logic begins and is executed.
201
                //////////////////////////////////////////////////////////////////////////
202
                virtual void Update();
203
 
204
                //////////////////////////////////////////////////////////////////////////
205
                //      Function: UpdateF
206
                //      Parameters: 
207
                //              theFrac - The number of updates this time slice represents.
208
                //
209
                //      Returns: none
210
                //
211
                //      Purpose:
212
                //      There has been a fundamental temporal aliasing issue in the previous
213
                //      demos because games run at a 100 Hz Update rate while the user's monitor 
214
                //      is refreshing at some other rate, generally between 60 and 85 Hz.  The fixed 
215
                //      100 Hz Update rate is convenient because it allows game logic to proceed 
216
                //      independantly from the refresh rate, but in some cases it's worth the extra 
217
                //      trouble of updating at a variable rate in order to provide smoother animation, 
218
                //      as in the case of a scrolling background, a shark with words written on it, 
219
                //      or an Arkanoid ball.
220
                //
221
                //      To illustrate the aliasing problem, imagine a ball that is supposed to move 
222
                //      200 pixels per second, running on a 75 Hz monitor.  The update rate of the 
223
                //      game is 100 Hz, so that means that we will add 2 pixels to the ball position 
224
                //      every update, and there will be 1.33 updates per monitor refresh (on average).  
225
                //      That means that that 2 out of every 3 monitor refreshes will show the ball 
226
                //      moving 2 pixels, and and the third will show it moving 4 pixels.  That isn't 
227
                //      smooth motion.  The correct solution would be for the ball to move 2.67 
228
                //      pixels every monitor refresh.  But how do we do that?
229
                //
230
                //      To support smooth motion, we use UpdateF.  Widget::UpdateF is similar to 
231
                //      Widget::Update, but Widget::UpdateF gets a float passed into it that 
232
                //      represents how many Update's this time slice represents.  In the 75 Hz 
233
                //      example, UpdateF would always be called with 1.33.  Update has certainly 
234
                //      not been made obsolete, however, and you can choose which 
235
                //      parts of your game logic should be in Update and which should be in 
236
                //      UpdateF.  To facilitate cooperation and good behavior between the two 
237
                //      update methods, there are some rules they follow:  Updating always occurs 
238
                //      in blocks, with one or two Update calls followed immediately with an 
239
                //      UpdateF call.  This means that the application will never get the chance 
240
                //      to draw or process input between an Update and a Draw without calling 
241
                //      UpdateF in the middle.  Therefore, you can assume that focus won't be 
242
                //      lost, nor will input change between an Update and an UpdateF, and you'll 
243
                //      know that you'll have a chance to finalize your state in UpdateF so things 
244
                //      can be left dangling (whatever that means for your app) after Update.  
245
                //      You are also guaranteed that the value passed in to UpdateF will be between 
246
                //      1.67 (for a 60 Hz monitor) and 1.0 (for a 100 Hz monitor).  Even if the 
247
                //      monitor is 60 Hz but the computer is only fast enough to draw at 30 FPS 
248
                //      you will get two Update blocks in a row before the draw, so it will still 
249
                //      appear to your app as if you are updating at 60 Hz.
250
                //
251
                //              IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT
252
                //
253
                //      In order to fully use this, you need to set up a few things.
254
                //      Set GameApp::mVSyncUpdates to true, override UpdateF(float theFrac),
255
                //      and move some code from Update that used to look like 
256
                //      this: "mPos += 1.5;", changing it to "mPos += 1.5 * theFrac;".
257
                //      Check out the C++ code for an example of motion using both Update and
258
                //      UpdateF.
259
                //
260
                //              IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT
261
                //
262
                //      Because UpdateF is called a variable number of times per second,
263
                //      you do NOT want to put game logic in it that needs to remain framerate
264
                //      independant. Use UpdateF ONLY for movement related operations, and not
265
                //      for your main game code.
266
                //
267
                //      If you really want to avoid shearing in windowed mode, you can
268
                //      set GameApp::mWaitForVSync to true and set GameApp::mSoftVSyncWait
269
                //      to false. NOTE: This winds up doing some busy waiting and consumes
270
                //      more processor time. 
271
                //      IMPORTANT: YOU MUST ALSO DELETE THE FOLLOWING REGISTRY KEY:
272
                //      Whereever your registry settings are stored 
273
                //      (HKEY_LOCAL_MACHINE\SOFTWARE\SexyAppFramework\Demo4 for this case),
274
                //      you must delete the key "WaitForVSync". This is VERY important, and it
275
                //      won't work otherwise.
276
                //////////////////////////////////////////////////////////////////////////
277
                virtual void UpdateF(float theFrac);
278
 
279
                //////////////////////////////////////////////////////////////////////////
280
                //      Function: ButtonDepress
281
                //      Parameters:
282
                //              theId   - Integer ID of the button that was clicked
283
                //
284
                //      Returns: none
285
                //
286
                //      Purpose: This method is called by the WidgetManager when a button widget
287
                //      is first pressed and THEN released. You can use ButtonPress if you want
288
                //      to know when the button is first pressed (before it is released).
289
                //      theId is the integer ID that was assigned to the button when it was
290
                //      first created. 
291
                //////////////////////////////////////////////////////////////////////////              
292
                virtual void    ButtonDepress(int theId);
293
 
294
                //////////////////////////////////////////////////////////////////////////
295
                //      Function: AddedToManager
296
                //      Parameters:
297
                //              theWidgetManager        - Pointer to the main widget manager from
298
                //                                                              GameApp.
299
                //
300
                //      Returns: none
301
                //
302
                //      Purpose: This function is automatically called by the widget manager
303
                //      which also passes a pointer to itself, when the Board class is
304
                //      added to its list of widgets. Every widget gets this function
305
                //      called when it is first added. It useful to use this function to
306
                //      set up any other widgets that the class might contain, such as buttons.
307
                //////////////////////////////////////////////////////////////////////////              
308
                virtual void    AddedToManager(WidgetManager* theWidgetManager);
309
 
310
                //////////////////////////////////////////////////////////////////////////
311
                //      Function: RemovedFromManager
312
                //      Parameters:
313
                //              theWidgetManager        - Pointer to the main widget manager from
314
                //                                                              GameApp.
315
                //
316
                //      Returns: none
317
                //
318
                //      Purpose: This function is automatically called by the widget manager
319
                //      which also passes a pointer to itself, when the Board class is
320
                //      removed from its list of widgets. Every widget gets this function
321
                //      called when it is finally removed. It useful to use this function to
322
                //      also remove any widgets that were added and created in AddedToManager.
323
                //////////////////////////////////////////////////////////////////////////
324
                virtual void    RemovedFromManager(WidgetManager* theWidgetManager);
325
 
326
};
327
 
328
 
329
}
330
 
331
#endif // __BOARD_H__