home | |||
links |
|
||
developer's mag main page article part 1 part 2 part 3 part 4 part 5 part 6 part 7 |
6 - Pen Detection and HandlingThe HandlePen() function takes the WM_PEN_DOWN message and determines if it is a valid press - if so, mark it X or O, and check if the game is over. Testing is via the m_owner array and the m_state variable. The only part not yet discussed is how to figure out which cell the pen is in.The Initialize() function sets the entries in the m_rect structure to indicate the 'hot spot' for each pen press. It does it by looking at the two vertical and two horizontal bars in the game, and using GetX(), GetY(), GetWidth(), and GetHeight() to calculate the rectangular areas defined by them, storing the values for future use. Although this can waste memory (the width and height of each cell are identical), I recommend this approach in ebm programs for a couple of reasons. Generating the rectangle once means the whole code can access it; here, DrawItem() uses it in centering the X or O in each cell. Another reason is that the RECT structure is ideally suited for pen detection, as shown in the HandlePen() function: void paTicTacToe::HandlePen(CViewable *from, S32 data) { // check if we've pressed on an empty square, and handle move if (m_state==STATE_GAME_OVER) return; // ignore unless game on int x=data>>16, y=data&0x0000FFFFL; // get coordinates of pen press // go through m_rect list to see if we have a hit for (int i=0;i<9;i++) { if (GUI_PointInRect(&m_rect[i],x,y)) // on one of our spots? { if (m_owner[i]) // already owned? return; // ignore // new entry selected - mark it appropriately m_owner[i]=(m_move&1)+1; // 1 or 2 depending on player 1/2 ++m_move; // record another move DrawItem(i); // display it // after move, we now check if game over, or exit and wait for next message int result=CheckGame(); // -1 if draw, 1/2 if winner switch (result) // if done, alert player { case 1: GUI_Alert(ALERT_WARNING,"Congratulations, Player 1 Won!"); break; case 2: GUI_Alert(ALERT_WARNING,"Congratulations, Player 2 Won!"); break; case -1: GUI_Alert(ALERT_WARNING,"It's a Draw!"); break; } if (result) // over? m_state=STATE_GAME_OVER; // note game done return; } } }Using GUI_PointInRect(), we quickly determine if we are pressing on a game cell. Looking over the rest of the function, we see the complete game logic. We filter out invalid pen presses by the rectangle test and checking that the game is not over. We additionally use m_owner to make sure we aren't selecting an occupied cell. Finally, we turn on the appropriate cell and check for end of game. Although we've coded a Draw() function that displays the whole screen (the GUI_NeedUpdate() call in NewGame invokes it), calling Draw() for every move is a cycle-stealer, and makes the game sluggish. Instead, we code two routines - DrawItem() for an individual entry, and Draw() to do it all (and which in turn calls DrawItem() once for each cell). This way, we get both speed and flexibility in item drawing. Previous Section Next Section |
||
Copyright © 2001-2006 ebmDevMag.com - Legal Notice |