File: Board.h

package info (click to toggle)
libtuxcap 1.4.0.dfsg2-2.1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 4,176 kB
  • sloc: cpp: 43,203; ansic: 3,095; python: 774; objc: 242; makefile: 100; xml: 87
file content (332 lines) | stat: -rw-r--r-- 14,840 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
#ifndef __BOARD_H__
#define __BOARD_H__

//////////////////////////////////////////////////////////////////////////
//						Board.h
//
//	This is the third class to look at in this particular demo
//	(after main.cpp and GameApp.h/.cpp). The Board class is where most of
//	your actual game programming will go. It is here that we will do
//	all our game drawing, updating, and input processing. Of course, in
//	a larger application, you would probably do drawing and updating in
//	multiple files, but you would still most likely use something similar
//	to a Board class as the master game logic class. 
//
//	The reason that the Board class is a widget is because when a widget
//	is added to the GameApp's WidgetManager, it will automatically have its
//	Update and Draw methods called, and it will automatically receive input
//	at the appropriate times. Furthermore, by making it a widget and adding
//	it to the WidgetManager, the game logic loop, Update(), will be guaranteed
//	to run at a standard 100FPS on all machines. This is extremely important
//	as you always want your logic code to run at the same speed, but want
//	the drawing code to run as fast as possible. That way on faster machines
//	your program doesn't run its logic faster than on a slower machine.
//
//	You can think of the Board as a canvas upon which we do all our
//	drawing, and a central hub where if we need to, we instruct other
//	classes where and when to draw to.
//////////////////////////////////////////////////////////////////////////

#include "Widget.h"
#include "ButtonListener.h"

// Because we're going to be learning about some new widgets, we
// need to include some more listener classes so we can respond to each one.
#include "EditListener.h"
#include "CheckboxListener.h"
#include "ListListener.h"



// We place all our classes inside the "Sexy" namespace to avoid name collisions
// with other libraries that might be added.
namespace Sexy
{


// Forward declare the graphics class. You will see the graphics class used
// and explained in Board.cpp: it is the main object used to draw all
// images, fonts, etc.
class Graphics;

// We maintain a pointer to the main game application in the Board class.
// The main game app contains functions that are often times needed
// by the Board class, such as registry reading/writing, file reading/writing,
// etc.
class GameApp;

// forward declare the widgets we're going to use in this demo:
class ButtonWidget;
class EditWidget;
class Checkbox;
class ListWidget;
class ScrollbarWidget;

// In this demo, we're going to do some more advanced things like 
// handle the two cases where Board is added and removed from the 
// WidgetManager.
class WidgetManager;

//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
class Board :	public Widget, public ButtonListener, 
				public EditListener, public CheckboxListener, 
				public ListListener
{

	private:

		GameApp*			mApp;
		ButtonWidget*		mButton1;		// We'll use these buttons for sound playing
		ButtonWidget*		mButton2;

		// These are explained in the C++ code, they are the new widgets we're learning about.
		EditWidget*			mEditWidget;
		Checkbox*			mCheckboxWidget;
		ListWidget*			mListWidget;
		ScrollbarWidget*	mScrollbarWidget;

		SexyString			mText;		// When we press enter on the edit box, we'll set this string and print it

		// Both are floats to ensure that the only difference in the movement demo
		// is the fact that one is updated in UpdateF and the other is in Update.
		float			mMotionX;		// For our movement example, this is the X coordinate of the image as it moves rightward
		float			mUpdateFMotionX;// Same as above, but only modified in UpdateF, to illustrate the difference in motion

	public:

		//////////////////////////////////////////////////////////////////////////
		//	Function: Board
		//	Parameters:
		//		theApp	- Pointer to the main application class
		//	
		//	Returns: none
		//////////////////////////////////////////////////////////////////////////
		Board(GameApp* theApp);

		virtual ~Board();

		//////////////////////////////////////////////////////////////////////////
		//	Function: EditWidgetText
		//	Parameters:
		//		theId		- Integer ID of the edit widget sending this message
		//		theString	- The contents of the edit widget
		//
		//	Returns: none
		//
		//	Purpose: Called whenever the return/enter key is pressed on
		//	an edit widget.
		//////////////////////////////////////////////////////////////////////////
		void EditWidgetText(int theId, const std::string& theString);

		//////////////////////////////////////////////////////////////////////////
		//	Function: AllowChar
		//	Parameters:
		//		theId	- Integer ID of the edit widget sending this message
		//		theChar	- Character just typed in
		//
		//	Returns: 
		//		true	- Indicates that the character is acceptible
		//		false	- Indicates that the character is invalid
		//
		//	Purpose: Whenever an ASCII character is typed into the edit box,
		//	this method is called first. If the method returns true, then the
		//	character just typed is accepted and appended to the current edit widget
		//	string. If it returns false, the character is rejected and is not added.
		//////////////////////////////////////////////////////////////////////////
		bool AllowChar(int theId, char theChar);

		//////////////////////////////////////////////////////////////////////////
		//	Function: CheckboxChecked
		//	Parameters:
		//		theId	- Integer ID of the checkbox widget sending this message
		//		checked	- Boolean indicating if the widget is checked or not
		//
		//	Returns: none
		//
		//	Purpose: Whenever a checkbox widget is checked or unchecked, this
		//	method is called. We're not actually going to do anything with this,
		//	we're just listing it here as an example of how you'd implement a
		//	function to respond to that event.
		//////////////////////////////////////////////////////////////////////////
		void CheckboxChecked(int theId, bool checked) {;}

		//////////////////////////////////////////////////////////////////////////
		//	Function: ListClicked
		//	Parameters:
		//		theId	- Integer ID of the listbox widget sending this message
		//		theIdx	- Integer indicating the index of the item selected in the list
		//		theClickCount	- An integer indicating which mouse button
		//						was pressed. One of the following:
		//			1:  Left button
		//			2:  Double-left-click
		//			3:  Middle button
		//			-1: Right button
		//			-2: Double-right-click
		//
		//	Returns: none
		//
		//	Purpose: Called any time a list widget is clicked on. The list
		//	widget by default doesn't automatically select the item you clicked on,
		//	it instead calls this method and in here you manually select the item.
		//	This is to allow you to prevent the selection of certain items, such as
		//	disabled items, etc.
		//////////////////////////////////////////////////////////////////////////		
		void ListClicked(int theId, int theIdx, int theClickCount);

		//////////////////////////////////////////////////////////////////////////
		//	Function: Draw
		//	Parameters:
		//		g	- Graphics object used to draw all images and fonts to the screen.
		//	
		//	Returns: none
		//
		//	Purpose: Called automatically by GameApp's WidgetManager, this function
		//	is the main method that is responsible for all graphical and textual
		//	displaying.
		//////////////////////////////////////////////////////////////////////////
		virtual void Draw(Graphics* g);

		//////////////////////////////////////////////////////////////////////////
		//	Function: Update
		//	Parameters: none
		//	Returns: none
		//
		//	Purpose: Called automatically by GameApp's WidgetManager, this method
		//	is GUARANTEED to be called 100 times per second (100FPS) and is where
		//	all main game logic is performed. Of course, if you had a larger more
		//	complex game, you'd most likely divide your logic between several
		//	other files, but this is commonly the central place where all game
		//	logic begins and is executed.
		//////////////////////////////////////////////////////////////////////////
		virtual void Update();

		//////////////////////////////////////////////////////////////////////////
		//	Function: UpdateF
		//	Parameters: 
		//		theFrac	- The number of updates this time slice represents.
		//
		//	Returns: none
		//
		//	Purpose:
		//	There has been a fundamental temporal aliasing issue in the previous
		//	demos because games run at a 100 Hz Update rate while the user's monitor 
		//	is refreshing at some other rate, generally between 60 and 85 Hz.  The fixed 
		//	100 Hz Update rate is convenient because it allows game logic to proceed 
		//	independantly from the refresh rate, but in some cases it's worth the extra 
		//	trouble of updating at a variable rate in order to provide smoother animation, 
		//	as in the case of a scrolling background, a shark with words written on it, 
		//	or an Arkanoid ball.
		//
		//	To illustrate the aliasing problem, imagine a ball that is supposed to move 
		//	200 pixels per second, running on a 75 Hz monitor.  The update rate of the 
		//	game is 100 Hz, so that means that we will add 2 pixels to the ball position 
		//	every update, and there will be 1.33 updates per monitor refresh (on average).  
		//	That means that that 2 out of every 3 monitor refreshes will show the ball 
		//	moving 2 pixels, and and the third will show it moving 4 pixels.  That isn't 
		//	smooth motion.  The correct solution would be for the ball to move 2.67 
		//	pixels every monitor refresh.  But how do we do that?
		//
		//	To support smooth motion, we use UpdateF.  Widget::UpdateF is similar to 
		//	Widget::Update, but Widget::UpdateF gets a float passed into it that 
		//	represents how many Update's this time slice represents.  In the 75 Hz 
		//	example, UpdateF would always be called with 1.33.  Update has certainly 
		//	not been made obsolete, however, and you can choose which 
		//	parts of your game logic should be in Update and which should be in 
		//	UpdateF.  To facilitate cooperation and good behavior between the two 
		//	update methods, there are some rules they follow:  Updating always occurs 
		//	in blocks, with one or two Update calls followed immediately with an 
		//	UpdateF call.  This means that the application will never get the chance 
		//	to draw or process input between an Update and a Draw without calling 
		//	UpdateF in the middle.  Therefore, you can assume that focus won't be 
		//	lost, nor will input change between an Update and an UpdateF, and you'll 
		//	know that you'll have a chance to finalize your state in UpdateF so things 
		//	can be left dangling (whatever that means for your app) after Update.  
		//	You are also guaranteed that the value passed in to UpdateF will be between 
		//	1.67 (for a 60 Hz monitor) and 1.0 (for a 100 Hz monitor).  Even if the 
		//	monitor is 60 Hz but the computer is only fast enough to draw at 30 FPS 
		//	you will get two Update blocks in a row before the draw, so it will still 
		//	appear to your app as if you are updating at 60 Hz.
		//
		//		IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT
		//
		//	In order to fully use this, you need to set up a few things.
		//	Set GameApp::mVSyncUpdates to true, override UpdateF(float theFrac),
		//	and move some code from Update that used to look like 
		//	this: "mPos += 1.5;", changing it to "mPos += 1.5 * theFrac;".
		//	Check out the C++ code for an example of motion using both Update and
		//	UpdateF.
		//
		//		IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT
		//
		//	Because UpdateF is called a variable number of times per second,
		//	you do NOT want to put game logic in it that needs to remain framerate
		//	independant. Use UpdateF ONLY for movement related operations, and not
		//	for your main game code.
		//
		//	If you really want to avoid shearing in windowed mode, you can
		//	set GameApp::mWaitForVSync to true and set GameApp::mSoftVSyncWait
		//	to false. NOTE: This winds up doing some busy waiting and consumes
		//	more processor time. 
		//	IMPORTANT: YOU MUST ALSO DELETE THE FOLLOWING REGISTRY KEY:
		//	Whereever your registry settings are stored 
		//	(HKEY_LOCAL_MACHINE\SOFTWARE\SexyAppFramework\Demo4 for this case),
		//	you must delete the key "WaitForVSync". This is VERY important, and it
		//	won't work otherwise.
		//////////////////////////////////////////////////////////////////////////
		virtual void UpdateF(float theFrac);

		//////////////////////////////////////////////////////////////////////////
		//	Function: ButtonDepress
		//	Parameters:
		//		theId	- Integer ID of the button that was clicked
		//
		//	Returns: none
		//
		//	Purpose: This method is called by the WidgetManager when a button widget
		//	is first pressed and THEN released. You can use ButtonPress if you want
		//	to know when the button is first pressed (before it is released).
		//	theId is the integer ID that was assigned to the button when it was
		//	first created. 
		//////////////////////////////////////////////////////////////////////////		
		virtual void	ButtonDepress(int theId);

		//////////////////////////////////////////////////////////////////////////
		//	Function: AddedToManager
		//	Parameters:
		//		theWidgetManager	- Pointer to the main widget manager from
		//								GameApp.
		//
		//	Returns: none
		//
		//	Purpose: This function is automatically called by the widget manager
		//	which also passes a pointer to itself, when the Board class is
		//	added to its list of widgets. Every widget gets this function
		//	called when it is first added. It useful to use this function to
		//	set up any other widgets that the class might contain, such as buttons.
		//////////////////////////////////////////////////////////////////////////		
		virtual void	AddedToManager(WidgetManager* theWidgetManager);

		//////////////////////////////////////////////////////////////////////////
		//	Function: RemovedFromManager
		//	Parameters:
		//		theWidgetManager	- Pointer to the main widget manager from
		//								GameApp.
		//
		//	Returns: none
		//
		//	Purpose: This function is automatically called by the widget manager
		//	which also passes a pointer to itself, when the Board class is
		//	removed from its list of widgets. Every widget gets this function
		//	called when it is finally removed. It useful to use this function to
		//	also remove any widgets that were added and created in AddedToManager.
		//////////////////////////////////////////////////////////////////////////
		virtual void	RemovedFromManager(WidgetManager* theWidgetManager);
			
};


}

#endif // __BOARD_H__