CSuperBrickBreaker.cpp
上传用户:sycq158
上传日期:2008-10-22
资源大小:15361k
文件大小:70k
- //////////////////////////////////////////////////////////////////////////////
- /// File: CSuperBrickBreaker.cpp
- /// Purpose: Implementation of CSuperBrickBreaker Class
- ///////////////////////////////////////////////////////////////////////////////
- /// Configuation Management
- ///
- /// Who When Description
- /// ===========================================================================
- /// R. Walter 28-Dec-2003 Initial Version/Release
- ///
- ///////////////////////////////////////////////////////////////////////////////
- /// Copyright 2003: Robert Walter All rights reserved
- ///////////////////////////////////////////////////////////////////////////////
- /// HEADER FILE INCLUDES //////////////////////////////////////////////////////
- #include <stdio.h>
- #include "CSuperBrickBreaker.h"
- /// CLASS CONSTRUCTORS / DESTRUCTORS //////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: CSuperBrickBreaker --> default constructor
- /// Purpose: Initialize member variables
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: nothing
- /// Returns: nothing
- ///////////////////////////////////////////////////////////////////////////////
- CSuperBrickBreaker::CSuperBrickBreaker()
- {
- m_game_state = GS_INITIALIZE;
- m_game_type = SBB_STANDARD;
- m_paused_state = PS_RESUME;
- m_gameover_state = GO_PLAYAGAIN;
- m_hit_top_boun_fg = false;
- m_new_level_fg = false;
- m_score = 0;
- m_file_stream.open("sbb_log.txt");
- return;
- }
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: ~CSuperBrickBreaker --> class destructor
- /// Purpose: Uninitialize member variables
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: nothing
- /// Returns: nothing
- ///////////////////////////////////////////////////////////////////////////////
- CSuperBrickBreaker::~CSuperBrickBreaker()
- {
- m_file_stream.close();
- return;
- }
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: BallRectIntersect
- /// Purpose: Determine the passed ball rect intersects the passed rectangle
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: RECT describing current position of ball
- /// RECT describing brick or paddle being tested for interesection
- /// Returns: EIntersect describing how ball rect intersected rectangle
- ///////////////////////////////////////////////////////////////////////////////
- EIntersect CSuperBrickBreaker::BallRectIntersect(RECT p_ball_rect, RECT p_rect)
- {
- bool l_contains_top_left = false;
- bool l_contains_top_right = false;
- bool l_contains_bot_left = false;
- bool l_contains_bot_right = false;
- // check if top-left corner of the ball is in the rectangle
- l_contains_top_left = ( (p_ball_rect.top >= p_rect.top) && (p_ball_rect.top <= p_rect.bottom) &&
- (p_ball_rect.left >= p_rect.left) && (p_ball_rect.left <= p_rect.right) ) ;
- // check if top-right corner of the ball is in the rectangle
- l_contains_top_right = ( (p_ball_rect.top >= p_rect.top) && (p_ball_rect.top <= p_rect.bottom) &&
- (p_ball_rect.right >= p_rect.left) && (p_ball_rect.right <= p_rect.right) ) ;
- // check if bottom-left corner of the ball is in the rectangle
- l_contains_bot_left = ( (p_ball_rect.bottom >= p_rect.top) && (p_ball_rect.bottom <= p_rect.bottom) &&
- (p_ball_rect.left >= p_rect.left) && (p_ball_rect.left <= p_rect.right) ) ;
- // check if bottom-right corner of the ball is in the rectangle
- l_contains_bot_right = ( (p_ball_rect.bottom >= p_rect.top) && (p_ball_rect.bottom <= p_rect.bottom) &&
- (p_ball_rect.right >= p_rect.left) && (p_ball_rect.right <= p_rect.right) ) ;
- if ( (l_contains_top_left) && (l_contains_top_right) )
- {
- return(IS_BOTTOM);
- }
- else if ( (l_contains_top_right) && (l_contains_bot_right) )
- {
- return(IS_LEFT);
- }
- else if ( (l_contains_bot_right) && (l_contains_bot_left) )
- {
- return(IS_TOP);
- }
- else if ( (l_contains_bot_left) && (l_contains_top_left) )
- {
- return(IS_RIGHT);
- }
- else if (l_contains_top_left)
- {
- // only the top left corner 'penetrated' the rectangle
- // if the top-left corner is farther from the bottom of the
- // rectangle than the right side, assume the ball interected
- // the right
- if ( (p_rect.bottom - p_ball_rect.top) >= (p_rect.right - p_ball_rect.left) )
- {
- return(IS_RIGHT);
- }
- else
- {
- return(IS_BOTTOM);
- }
- }
- else if (l_contains_top_right)
- {
- // only the top right corner 'penetrated' the rectangle
- // if the top-right corner is farther from the bottom of the
- // rectangle than the left side, assume the ball interected
- // the left
- if ( (p_rect.bottom - p_ball_rect.top) >= (p_ball_rect.right - p_rect.left) )
- {
- return(IS_LEFT);
- }
- else
- {
- return(IS_BOTTOM);
- }
- }
- else if (l_contains_bot_right)
- {
- // only the bottom right corner 'penetrated' the rectangle
- // if the bottom-right corner is farther from the top of the
- // rectangle than the left side, assume the ball interected
- // the left
- if ( (p_ball_rect.bottom - p_rect.top) >= (p_ball_rect.right - p_rect.left) )
- {
- return(IS_LEFT);
- }
- else
- {
- return(IS_BOTTOM);
- }
- }
- else if (l_contains_bot_left)
- {
- // only the bottom left corner 'penetrated' the rectangle
- // if the bottom-left corner is farther from the top of the
- // rectangle than the right side, assume the ball interected
- // the right
- if ( (p_ball_rect.bottom - p_rect.top) >= (p_rect.right - p_ball_rect.left) )
- {
- return(IS_RIGHT);
- }
- else
- {
- return(IS_BOTTOM);
- }
- }
- return(IS_NONE);
- }
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: CheckHitBrick
- /// Purpose: Determines if the ball (based on passed rectangle) hit a brick
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: RECT structure of current positon of a ball
- /// Returns: EIntersect value describing how ball hit a brick
- ///////////////////////////////////////////////////////////////////////////////
- EIntersect CSuperBrickBreaker::CheckHitBrick(const RECT p_ball_rect, TBrick* p_hit_brick)
- {
- bool l_is_brick = IsBrickAtBallLocation(p_ball_rect, p_hit_brick);
- if (l_is_brick)
- {
- EIntersect l_intersect = IS_NONE;
- if (p_hit_brick->state == BS_NORMAL)
- {
- // determine which side of the brick the ball intersected.
- l_intersect = BallRectIntersect(p_ball_rect, p_hit_brick->rect);
- return(l_intersect);
- }
- }
- return(IS_NONE);
- }
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: CheckHitPaddle
- /// Purpose: Determines if the ball (based on passed rectangle) hit the paddle
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: RECT structure of current positon of a ball
- /// Returns: EIntersect value describing how ball hit the paddle
- ///////////////////////////////////////////////////////////////////////////////
- EIntersect CSuperBrickBreaker::CheckHitPaddle(const RECT p_ball_rect)
- {
- TBallCorner m_ball_corner[4];
- EIntersect l_result = IS_NONE;
- /*************************
- ** top left corner
- *************************/
- m_ball_corner[0].x = p_ball_rect.left;
- m_ball_corner[0].y = p_ball_rect.top;
- /*************************
- ** top right corner
- *************************/
- m_ball_corner[1].x = p_ball_rect.right;
- m_ball_corner[1].y = p_ball_rect.top;
- /*************************
- ** bottom right corner
- *************************/
- m_ball_corner[2].x = p_ball_rect.right;
- m_ball_corner[2].y = p_ball_rect.bottom;
- /*************************
- ** bottom left corner
- *************************/
- m_ball_corner[3].x = p_ball_rect.left;
- m_ball_corner[3].y = p_ball_rect.bottom;
- int j = 0;
- bool l_hit_paddle = false;
- RECT l_paddle_rect;
- ///////////////////////////////////////////////////////////////////////////
- /// loop through each of the ball corners to determine if the ball
- /// struck the paddle
- ///////////////////////////////////////////////////////////////////////////
- while (j < 4)
- {
- l_hit_paddle = m_paddle.IsPaddleAtPosition
- (
- /* x */ m_ball_corner[j].x,
- /* y */ m_ball_corner[j].y,
- /* paddle rect */ &l_paddle_rect
- );
- ///////////////////////////////////////////////////////////////////////
- /// if the ball hit the paddle, determine how (ie. which side) the
- /// ball intersected
- ///////////////////////////////////////////////////////////////////////
- if (l_hit_paddle)
- {
- l_result = BallRectIntersect(p_ball_rect, l_paddle_rect);
- if (l_result != IS_NONE)
- {
- return(l_result);
- }
- }
- j++;
- }
- return(l_result);
- }
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: DrawBalls
- /// Purpose: Draw the Super Brick Breaker game balls
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: nothing
- /// Returns: true if balls successfully drawn, otherwise false
- ///////////////////////////////////////////////////////////////////////////////
- bool CSuperBrickBreaker::DrawBalls()
- {
- // draw all FREE and CAPTIVE balls
- for (int i = 0; i < m_num_balls; i++)
- {
- if ( (m_ball[i].GetState() == FREE) || (m_ball[i].GetState() == CAPTIVE) )
- {
-
- m_ball_rect = m_ball[i].GetBallRect();
- bool br = false;
- br = DrawRectangle(&m_ball_rect, m_white_clr);
- if (!br)
- {
- return(false);
- }
- }
- }
- return true;
- }
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: DrawBoundary
- /// Purpose: Draw the Super Brick Breaker boundary
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: nothing
- /// Returns: true if bounday successfully drawn, otherwise false
- ///////////////////////////////////////////////////////////////////////////////
- bool CSuperBrickBreaker::DrawBoundary()
- {
- // draw left boundary
- bool br = false;
- // draw main boundary rectangles
- br = DrawRectangle(&m_left_boun_rect, m_boundary_clr);
- if (!br)
- {
- return(false);
- }
- br = DrawRectangle(&m_top_boun_rect, m_boundary_clr);
- if (!br)
- {
- return(false);
- }
- br = DrawRectangle(&m_right_boun_rect, m_boundary_clr);
- if (!br)
- {
- return(false);
- }
- // draw 'light' 3d rectangles on boundary
- br = DrawRectangle(&m_left_3d_light_rect, m_3d_light_clr);
- if (!br)
- {
- return(false);
- }
- br = DrawRectangle(&m_top_3d_light_rect, m_3d_light_clr);
- if (!br)
- {
- return(false);
- }
- br = DrawRectangle(&m_right_3d_light_rect, m_3d_light_clr);
- if (!br)
- {
- return(false);
- }
- // draw 'shadow' 3d rectangles on boundary
- br = DrawRectangle(&m_left_3d_shadow_rect, m_3d_shadow_clr);
- if (!br)
- {
- return(false);
- }
- br = DrawRectangle(&m_top_3d_shadow_rect, m_3d_shadow_clr);
- if (!br)
- {
- return(false);
- }
- br = DrawRectangle(&m_right_3d_shadow_rect, m_3d_shadow_clr);
- if (!br)
- {
- return(false);
- }
-
- return(true);
- };
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: DrawBricks
- /// Purpose: Draw the Super Brick Breaker game bricks
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: nothing
- /// Returns: true if bricks successfully drawn, otherwise false
- ///////////////////////////////////////////////////////////////////////////////
- bool CSuperBrickBreaker::DrawBricks()
- {
- int l_brick_cnt = m_bricks.GetBrickCount();
- for (int i = 0; i < l_brick_cnt; i++)
- {
- TBrick l_brick = m_bricks.GetBrick(i);
- bool br = false;
- if (l_brick.state == BS_NORMAL)
- {
- br = DrawRectangle(&l_brick.rect, l_brick.color);
- if (!br)
- {
- return(false);
- }
- br = Draw3DFrame(l_brick.rect);
- if (!br)
- {
- return(false);
- }
- }
- }
- return(true);
- }
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: DrawGameOverMenu
- /// Purpose: Draw the 'game over' menu in the playing area on top of
- /// bricks
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: nothing
- /// Returns: true if the menu is successfully drawn, otherwise false
- ///////////////////////////////////////////////////////////////////////////////
- bool CSuperBrickBreaker::DrawGameOverMenu()
- {
- bool br = false;
- ///////////////////////////////////////////////////////////////////////////
- /// draw the game over shadow text
- ///////////////////////////////////////////////////////////////////////////
- br = DrawGDIText
- (
- /* text */ "Game Over",
- /* red */ 212,
- /* green */ 208,
- /* blue */ 200,
- /* font */ m_menu_font,
- /* x */ 172,
- /* y */ 77
- );
- if (!br)
- {
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- /// draw the game over text
- ///////////////////////////////////////////////////////////////////////////
- br = DrawGDIText
- (
- /* text */ "Game Over",
- /* red */ 255,
- /* green */ 255,
- /* blue */ 255,
- /* font */ m_menu_font,
- /* x */ 170,
- /* y */ 75
- );
- if (!br)
- {
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- /// draw the play again shadow text
- ///////////////////////////////////////////////////////////////////////////
- br = DrawGDIText
- (
- /* text */ "Play Again",
- /* red */ 212,
- /* green */ 208,
- /* blue */ 200,
- /* font */ m_menu_font,
- /* x */ 289,
- /* y */ 152
- );
- if (!br)
- {
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- /// draw the play again text
- ///////////////////////////////////////////////////////////////////////////
- br = DrawGDIText
- (
- /* text */ "Play Again",
- /* red */ 255,
- /* green */ 255,
- /* blue */ 255,
- /* font */ m_menu_font,
- /* x */ 287,
- /* y */ 150
- );
- if (!br)
- {
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- /// draw the main menu shadow text
- ///////////////////////////////////////////////////////////////////////////
- br = DrawGDIText
- (
- /* text */ "Main Menu",
- /* red */ 212,
- /* green */ 208,
- /* blue */ 200,
- /* font */ m_menu_font,
- /* x */ 289,
- /* y */ 207
- );
- if (!br)
- {
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- /// draw the main menu text
- ///////////////////////////////////////////////////////////////////////////
- br = DrawGDIText
- (
- /* text */ "Main Menu",
- /* red */ 255,
- /* green */ 255,
- /* blue */ 255,
- /* font */ m_menu_font,
- /* x */ 287,
- /* y */ 205
- );
- if (!br)
- {
- return(false);
- }
- int l_menu_x = 0;
- int l_menu_y = 0;
- if (m_gameover_state == GO_PLAYAGAIN)
- {
- l_menu_x = 230;
- l_menu_y = 150;
- }
- else if (m_gameover_state == GO_MAINMENU)
- {
- l_menu_x = 230;
- l_menu_y = 205;
- }
- else
- {
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- /// draw the 'chosen (->)' game shadow
- ///////////////////////////////////////////////////////////////////////////
- br = DrawGDIText
- (
- /* text */ "->",
- /* red */ 212,
- /* green */ 208,
- /* blue */ 200,
- /* font */ m_menu_font,
- /* x */ l_menu_x + 2,
- /* y */ l_menu_y + 2
- );
- if (!br)
- {
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- /// draw the 'chosen (->)' game
- ///////////////////////////////////////////////////////////////////////////
- br = DrawGDIText
- (
- /* text */ "->",
- /* red */ 255,
- /* green */ 255,
- /* blue */ 255,
- /* font */ m_menu_font,
- /* x */ l_menu_x,
- /* y */ l_menu_y
- );
- if (!br)
- {
- return(false);
- }
- return(true);
- }
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: DrawHeadingLine
- /// Purpose: Draw the Super Brick Breaker heading line
- /// - game title
- /// - turns remaining
- /// - current level
- /// - current score
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: nothing
- /// Returns: true if heading line successfully drawn, otherwise false
- ///////////////////////////////////////////////////////////////////////////////
- bool CSuperBrickBreaker::DrawHeadingLine()
- {
- char l_text[200];
- ostrstream l_stream(l_text, sizeof(l_text));
- l_stream << "SUPER BRICK BREAKER TURNS " << m_game_turns_remaining
- << " LEVEL " << m_level << " SCORE "
- << m_score << ends;
- StartGDIDrawing();
- bool br = false;
- br = DrawGDIText
- (
- /* text */ l_text,
- /* red */ 255,
- /* green */ 255,
- /* blue */ 255,
- /* font */ m_plain_font,
- /* x */ 2,
- /* y */ 2
- );
- if (!br)
- {
- return(false);
- }
- EndGDIDrawing();
- return(true);
- }
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: DrawMainMenu
- /// Purpose: Draw the main menu in the playing area on top of
- /// bricks
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: nothing
- /// Returns: true if the main menu is successfully drawn, otherwise false
- ///////////////////////////////////////////////////////////////////////////////
- bool CSuperBrickBreaker::DrawMainMenu()
- {
- bool br = false;
- ///////////////////////////////////////////////////////////////////////////
- /// draw the 'Standard' game shadow text
- ///////////////////////////////////////////////////////////////////////////
- br = DrawGDIText
- (
- /* text */ "Standard",
- /* red */ 212,
- /* green */ 208,
- /* blue */ 200,
- /* font */ m_menu_font,
- /* x */ 315,
- /* y */ 152
- );
- if (!br)
- {
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- /// draw the 'Standard' game text
- ///////////////////////////////////////////////////////////////////////////
- br = DrawGDIText
- (
- /* text */ "Standard",
- /* red */ 255,
- /* green */ 255,
- /* blue */ 255,
- /* font */ m_menu_font,
- /* x */ 312,
- /* y */ 150
- );
- if (!br)
- {
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- /// draw the 'Double' game shadow text
- ///////////////////////////////////////////////////////////////////////////
- br = DrawGDIText
- (
- /* text */ "Double",
- /* red */ 212,
- /* green */ 208,
- /* blue */ 200,
- /* font */ m_menu_font,
- /* x */ 314,
- /* y */ 207
- );
- if (!br)
- {
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- /// draw the 'Double' game text
- ///////////////////////////////////////////////////////////////////////////
- br = DrawGDIText
- (
- /* text */ "Double",
- /* red */ 255,
- /* green */ 255,
- /* blue */ 255,
- /* font */ m_menu_font,
- /* x */ 312,
- /* y */ 205
- );
- if (!br)
- {
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- /// draw the 'Escape' game shadow text
- ///////////////////////////////////////////////////////////////////////////
- br = DrawGDIText
- (
- /* text */ "Escape",
- /* red */ 212,
- /* green */ 208,
- /* blue */ 200,
- /* font */ m_menu_font,
- /* x */ 314,
- /* y */ 262
- );
- if (!br)
- {
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- /// draw the 'Escape' game text
- ///////////////////////////////////////////////////////////////////////////
- br = DrawGDIText
- (
- /* text */ "Escape",
- /* red */ 255,
- /* green */ 255,
- /* blue */ 255,
- /* font */ m_menu_font,
- /* x */ 312,
- /* y */ 260
- );
- if (!br)
- {
- return(false);
- }
- int l_game_menu_x = 0;
- int l_game_menu_y = 0;
- if (m_game_type == SBB_STANDARD)
- {
- l_game_menu_x = 255;
- l_game_menu_y = 150;
- }
- else if (m_game_type == SBB_DOUBLE)
- {
- l_game_menu_x = 255;
- l_game_menu_y = 205;
- }
- else if (m_game_type == SBB_ESCAPE)
- {
- l_game_menu_x = 255;
- l_game_menu_y = 260;
- }
- else
- {
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- /// draw the 'chosen (->)' game shadow
- ///////////////////////////////////////////////////////////////////////////
- br = DrawGDIText
- (
- /* text */ "->",
- /* red */ 212,
- /* green */ 208,
- /* blue */ 200,
- /* font */ m_menu_font,
- /* x */ l_game_menu_x + 2,
- /* y */ l_game_menu_y + 2
- );
- if (!br)
- {
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- /// draw the 'chosen (->)' game
- ///////////////////////////////////////////////////////////////////////////
- br = DrawGDIText
- (
- /* text */ "->",
- /* red */ 255,
- /* green */ 255,
- /* blue */ 255,
- /* font */ m_menu_font,
- /* x */ l_game_menu_x,
- /* y */ l_game_menu_y
- );
- if (!br)
- {
- return(false);
- }
- return(true);
- };
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: DrawPaddle
- /// Purpose: Draw the paddle in the playing area
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: nothing
- /// Returns: true if paddle successfully drawn, otherwise false
- ///////////////////////////////////////////////////////////////////////////////
- bool CSuperBrickBreaker::DrawPaddle()
- {
- bool br = false;
- m_paddle.GetPaddleRects(&m_paddle_cnt, m_paddle_rects);
- for (int i = 0; i < m_paddle_cnt; i++)
- {
- br = DrawRectangle(&m_paddle_rects[i], m_boundary_clr);
- if (!br)
- {
- return(false);
- }
- br = Draw3DFrame(m_paddle_rects[i]);
- if (!br)
- {
- return(false);
- }
- }
- return(true);
- }
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: DrawPausedMenu
- /// Purpose: Draw the 'game paused' menu in the playing area on top of
- /// bricks
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: nothing
- /// Returns: true if the menu is successfully drawn, otherwise false
- ///////////////////////////////////////////////////////////////////////////////
- bool CSuperBrickBreaker::DrawPausedMenu()
- {
- bool br = false;
- ///////////////////////////////////////////////////////////////////////////
- /// draw the game paused shadow text
- ///////////////////////////////////////////////////////////////////////////
- br = DrawGDIText
- (
- /* text */ "Game Paused",
- /* red */ 212,
- /* green */ 208,
- /* blue */ 200,
- /* font */ m_menu_font,
- /* x */ 242,
- /* y */ 77
- );
- if (!br)
- {
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- /// draw the game paused text
- ///////////////////////////////////////////////////////////////////////////
- br = DrawGDIText
- (
- /* text */ "Game Paused",
- /* red */ 255,
- /* green */ 255,
- /* blue */ 255,
- /* font */ m_menu_font,
- /* x */ 240,
- /* y */ 75
- );
- if (!br)
- {
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- /// draw the resume game shadow text
- ///////////////////////////////////////////////////////////////////////////
- br = DrawGDIText
- (
- /* text */ "Resume Game",
- /* red */ 212,
- /* green */ 208,
- /* blue */ 200,
- /* font */ m_menu_font,
- /* x */ 314,
- /* y */ 152
- );
- if (!br)
- {
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- /// draw the resume game text
- ///////////////////////////////////////////////////////////////////////////
- br = DrawGDIText
- (
- /* text */ "Resume Game",
- /* red */ 255,
- /* green */ 255,
- /* blue */ 255,
- /* font */ m_menu_font,
- /* x */ 312,
- /* y */ 150
- );
- if (!br)
- {
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- /// draw the main menu shadow text
- ///////////////////////////////////////////////////////////////////////////
- br = DrawGDIText
- (
- /* text */ "Main Menu",
- /* red */ 212,
- /* green */ 208,
- /* blue */ 200,
- /* font */ m_menu_font,
- /* x */ 314,
- /* y */ 207
- );
- if (!br)
- {
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- /// draw the main menu text
- ///////////////////////////////////////////////////////////////////////////
- br = DrawGDIText
- (
- /* text */ "Main Menu",
- /* red */ 255,
- /* green */ 255,
- /* blue */ 255,
- /* font */ m_menu_font,
- /* x */ 312,
- /* y */ 205
- );
- if (!br)
- {
- return(false);
- }
- int l_menu_x = 0;
- int l_menu_y = 0;
- if (m_paused_state == PS_RESUME)
- {
- l_menu_x = 255;
- l_menu_y = 150;
- }
- else if (m_paused_state == PS_MAINMENU)
- {
- l_menu_x = 255;
- l_menu_y = 205;
- }
- else
- {
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- /// draw the 'chosen (->)' game shadow
- ///////////////////////////////////////////////////////////////////////////
- br = DrawGDIText
- (
- /* text */ "->",
- /* red */ 212,
- /* green */ 208,
- /* blue */ 200,
- /* font */ m_menu_font,
- /* x */ l_menu_x + 2,
- /* y */ l_menu_y + 2
- );
- if (!br)
- {
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- /// draw the 'chosen (->)' game
- ///////////////////////////////////////////////////////////////////////////
- br = DrawGDIText
- (
- /* text */ "->",
- /* red */ 255,
- /* green */ 255,
- /* blue */ 255,
- /* font */ m_menu_font,
- /* x */ l_menu_x,
- /* y */ l_menu_y
- );
- if (!br)
- {
- return(false);
- }
- return(true);
- }
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: DrawStartNextTurn
- /// Purpose: Draw the 'READY' text before actually beginning the next turn
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: nothing
- /// Returns: true if the text is successfully drawn, otherwise false
- ///////////////////////////////////////////////////////////////////////////////
- bool CSuperBrickBreaker::DrawStartNextTurn()
- {
- bool br = false;
- ///////////////////////////////////////////////////////////////////////////
- /// draw the 'READY!' shadow text
- ///////////////////////////////////////////////////////////////////////////
- br = DrawGDIText
- (
- /* text */ "READY!",
- /* red */ 212,
- /* green */ 208,
- /* blue */ 200,
- /* font */ m_menu_font,
- /* x */ 302,
- /* y */ 282
- );
- if (!br)
- {
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- /// draw the 'READY!' text
- ///////////////////////////////////////////////////////////////////////////
- br = DrawGDIText
- (
- /* text */ "READY!",
- /* red */ 255,
- /* green */ 255,
- /* blue */ 255,
- /* font */ m_menu_font,
- /* x */ 300,
- /* y */ 280
- );
- if (!br)
- {
- return(false);
- }
- return(true);
- }
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: Draw3DFrame
- /// Purpose: Draw a 3D frame around the passed rectangle
- /// NOTE: the frame is drawn around the INSIDE of the rectangle
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: rectangle around frame will be drawn
- /// Returns: true if frame successfully drawn, otherwise false
- ///////////////////////////////////////////////////////////////////////////////
- bool CSuperBrickBreaker::Draw3DFrame(const RECT p_rect)
- {
- RECT l_frame_rect;
- bool br = false;
- // first - draw left light frame
- l_frame_rect.left = p_rect.left;
- l_frame_rect.top = p_rect.top;
- l_frame_rect.right = p_rect.left + 1;
- l_frame_rect.bottom = p_rect.bottom;
- br = DrawRectangle(&l_frame_rect, m_3d_light_clr);
- if (!br)
- {
- return(false);
- }
- // second - draw top light frame
- l_frame_rect.left = p_rect.left;
- l_frame_rect.top = p_rect.top;
- l_frame_rect.right = p_rect.right;
- l_frame_rect.bottom = p_rect.top + 1;
- br = DrawRectangle(&l_frame_rect, m_3d_light_clr);
- if (!br)
- {
- return(false);
- }
- // third - draw right shadow frame
- l_frame_rect.left = p_rect.right - 1;
- l_frame_rect.top = p_rect.top;
- l_frame_rect.right = p_rect.right;
- l_frame_rect.bottom = p_rect.bottom;
- br = DrawRectangle(&l_frame_rect, m_3d_shadow_clr);
- if (!br)
- {
- return(false);
- }
- // last - draw bottom shadow frame
- l_frame_rect.left = p_rect.left + 1;
- l_frame_rect.top = p_rect.bottom - 1;
- l_frame_rect.right = p_rect.right;
- l_frame_rect.bottom = p_rect.bottom;
- br = DrawRectangle(&l_frame_rect, m_3d_shadow_clr);
- if (!br)
- {
- return(false);
- }
- return true;
- }
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: GameInitialize
- /// Purpose: Initialize any variable required by this game object
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: nothing
- /// Returns: true if game objects successfully initialized, otherwise false
- ///////////////////////////////////////////////////////////////////////////////
- bool CSuperBrickBreaker::GameInitialize()
- {
- // initialize color variables
- InitializeColors();
- m_menu_font = CreateFont
- (
- /* height */ 60,
- /* width */ 0,
- /* escapement */ 0,
- /* orientation */ 0,
- /* weight */ FW_HEAVY,
- /* italic */ FALSE,
- /* underline */ FALSE,
- /* strikeout */ FALSE,
- /* char set */ DEFAULT_CHARSET,
- /* output precision */ OUT_CHARACTER_PRECIS,
- /* clip precision */ CLIP_DEFAULT_PRECIS,
- /* font quality */ DEFAULT_QUALITY,
- /* pitch and family */ DEFAULT_PITCH | FF_DONTCARE,
- /* typeface name */ "MS Sans Serif"
- );
- m_plain_font = CreateFont
- (
- /* height */ 24,
- /* width */ 0,
- /* escapement */ 0,
- /* orientation */ 0,
- /* weight */ FW_HEAVY,
- /* italic */ FALSE,
- /* underline */ FALSE,
- /* strikeout */ FALSE,
- /* char set */ DEFAULT_CHARSET,
- /* output precision */ OUT_CHARACTER_PRECIS,
- /* clip precision */ CLIP_DEFAULT_PRECIS,
- /* font quality */ DEFAULT_QUALITY,
- /* pitch and family */ DEFAULT_PITCH | FF_DONTCARE,
- /* typeface name */ "MS Sans Serif"
- );
- // initialize boundary rectangles
- InitializePlayingArea();
- // set the base properties for the bricks
- // they are the same for all games
- m_bricks.SetTopLeftPosition(/* x */ DEFAULT_BRICK_START_X, /* y */ DEFAULT_BRICK_START_Y);
- m_bricks.SetBrickProperties
- (
- /* width */ DEFAULT_BRICK_WIDTH,
- /* height */ DEFAULT_BRICK_HEIGHT,
- /* h space */ DEFAULT_BRICK_HOR_SPACE,
- /* v_space */ DEFAULT_BRICK_VER_SPACE
- );
- bool br = false;
- br = ProcessStateChange(/* new state */ GS_MAINMENU);
- if (!br)
- {
- return(false);
- }
- return(true);
- }
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: GameMain
- /// Purpose: Perform the next game logic loop
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: nothing
- /// Returns: true if game loop successfully processed, otherwise false
- ///////////////////////////////////////////////////////////////////////////////
- bool CSuperBrickBreaker::GameMain()
- {
- bool br = false;
- ///////////////////////////////////////////////////////////////////////////
- /// ensure we are in a 'Game Main' acceptable state:
- /// - we cannot be in GS_INITIALIZE
- ///////////////////////////////////////////////////////////////////////////
- if (m_game_state == GS_INITIALIZE)
- {
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- /// process the keyboard data (ie. move paddle, pause game, etc)
- ///////////////////////////////////////////////////////////////////////////
- br = ProcessKeyboard();
- if (!br)
- {
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- /// process the game objects -> if the game is not paused or awaiting the
- /// start of the next turn
- /// - move the paddle
- /// - move the ball(s)
- ///////////////////////////////////////////////////////////////////////////
- if ( (m_game_state != GS_STARTTURN) && (m_game_state != GS_GAMEPAUSED) && (m_game_state != GS_GAMEOVER) )
- {
- br = ProcessPaddle();
- if (!br)
- {
- return(false);
- }
- br = ProcessBalls();
- if (!br)
- {
- return(false);
- }
- }
- ///////////////////////////////////////////////////////////////////////////
- /// start the next frame (scene)
- ///////////////////////////////////////////////////////////////////////////
- br = StartScene(m_black_clr);
- if (!br)
- {
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- /// draw the parts of the playing area not based on the
- /// current state of the game
- /// - Boundary
- /// - Bricks
- /// - Paddle
- /// - Score
- /// - Turns Remaining
- ///////////////////////////////////////////////////////////////////////////
- br = DrawBoundary();
- if (!br)
- {
- return(false);
- }
- br = DrawBricks();
- if (!br)
- {
- return(false);
- }
- br = DrawPaddle();
- if (!br)
- {
- return(false);
- }
- br = DrawBalls();
- if (!br)
- {
- return(false);
- }
- br = DrawHeadingLine();
- if (!br)
- {
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- /// draw the playing area based on the current state
- /// of the game
- ///////////////////////////////////////////////////////////////////////////
- switch(m_game_state)
- {
- case GS_MAINMENU:
- {
- ///////////////////////////////////////////////////////////////////////////
- /// draw the main menu text with the current item highlighted
- ///////////////////////////////////////////////////////////////////////////
- StartGDIDrawing();
- br = DrawMainMenu();
- if (!br)
- {
- return(false);
- }
- EndGDIDrawing();
- } break;
- case GS_STARTTURN:
- {
- ///////////////////////////////////////////////////////////////////////////
- /// draw the main menu text with the current item highlighted
- ///////////////////////////////////////////////////////////////////////////
- StartGDIDrawing();
- br = DrawStartNextTurn();
- if (!br)
- {
- return(false);
- }
- EndGDIDrawing();
- } break;
- case GS_GAMEPLAY:
- {
- ///////////////////////////////////////////////////////////////////////////
- /// no extra things to do
- ///////////////////////////////////////////////////////////////////////////
- } break;
- case GS_GAMEPAUSED:
- {
- ///////////////////////////////////////////////////////////////////////////
- /// draw the paused menu
- ///////////////////////////////////////////////////////////////////////////
- StartGDIDrawing();
- br = DrawPausedMenu();
- if (!br)
- {
- return(false);
- }
- EndGDIDrawing();
- } break;
- case GS_GAMEOVER:
- {
- ///////////////////////////////////////////////////////////////////////////
- /// draw the game over menu
- ///////////////////////////////////////////////////////////////////////////
- StartGDIDrawing();
- br = DrawGameOverMenu();
- if (!br)
- {
- return(false);
- }
- EndGDIDrawing();
- } break;
- }
-
- ///////////////////////////////////////////////////////////////////////////
- /// 'mark' the end of this frame and flip the back buffer
- ///////////////////////////////////////////////////////////////////////////
- br = EndScene();
- if (!br)
- {
- return(false);
- }
- return(true);
- }
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: GameShutdown
- /// Purpose: Uninitialize any variable required by this game object
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: nothing
- /// Returns: true if game objects successfully uninitialized, otherwise false
- ///////////////////////////////////////////////////////////////////////////////
- bool CSuperBrickBreaker::GameShutdown()
- {
- return true;
- };
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: InitializeBalls
- /// Purpose: Set the 'ball' variables for the game
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: nothing
- /// Returns: nothing
- ///////////////////////////////////////////////////////////////////////////////
- void CSuperBrickBreaker::InitializeBalls()
- {
- m_balls_in_play = 0;
- m_hit_top_boun_fg = false;
- int m_temp_x = 23;
- int m_temp_y = 295;
- srand(GetTickCount());
- m_temp_x += (rand()%120);
- m_temp_y += (rand()%50);
- m_ball[0].SetXPos(m_temp_x);
- m_ball[0].SetYPos(m_temp_y);
- m_ball[0].SetXVel(2);
- m_ball[0].SetYVel(2);
- m_ball[0].SetVelMultiplier(1);
- m_ball[0].SetState(IDLE);
- switch(m_game_type)
- {
- case SBB_STANDARD:
- {
- // no extra initialization required
- } break;
- case SBB_DOUBLE:
- {
- m_first_paddle_hit = false;
- m_ball[1].SetXPos(23);
- m_ball[1].SetYPos(295);
- m_ball[1].SetXVel(2);
- m_ball[1].SetYVel(2);
- m_ball[1].SetVelMultiplier(1);
- m_ball[1].SetState(IDLE);
- } break;
- case SBB_ESCAPE:
- {
- RECT m_ball_rect;
- m_ball_rect.top = DEFAULT_BRICK_START_Y + (2 * (DEFAULT_BRICK_HEIGHT + DEFAULT_BRICK_VER_SPACE) ) - DEFAULT_BRICK_VER_SPACE;
- m_ball_rect.left = DEFAULT_BRICK_START_X + (2 * (DEFAULT_BRICK_WIDTH + DEFAULT_BRICK_HOR_SPACE) ) - DEFAULT_BRICK_HOR_SPACE;
- m_ball_rect.right = m_ball_rect.left + (2 * (DEFAULT_BRICK_WIDTH + DEFAULT_BRICK_HOR_SPACE) ) + DEFAULT_BRICK_HOR_SPACE;
- m_ball_rect.bottom = m_ball_rect.top + (2 * (DEFAULT_BRICK_HEIGHT + DEFAULT_BRICK_VER_SPACE) ) + DEFAULT_BRICK_VER_SPACE;
- if (m_game_turns_remaining < 5)
- {
- if ((m_ball[1].GetState() != CAPTIVE) && (!m_new_level_fg))
- {
- // the ball has been freed and has been lost, do nothing
- }
- else
- {
- m_ball[1].SetXPos(151);
- m_ball[1].SetYPos(133);
- m_ball[1].SetXVel(2);
- m_ball[1].SetYVel(2);
- m_ball[1].SetVelMultiplier(2);
- m_ball[1].SetCaptiveRect(m_ball_rect);
- }
- }
- else
- {
- m_ball[1].SetXPos(151);
- m_ball[1].SetYPos(133);
- m_ball[1].SetXVel(2);
- m_ball[1].SetYVel(2);
- m_ball[1].SetVelMultiplier(2);
- m_ball[1].SetState(CAPTIVE);
- m_ball[1].SetCaptiveRect(m_ball_rect);
- }
- m_ball_rect.top = DEFAULT_BRICK_START_Y + (2 * (DEFAULT_BRICK_HEIGHT + DEFAULT_BRICK_VER_SPACE) ) - DEFAULT_BRICK_VER_SPACE;
- m_ball_rect.left = DEFAULT_BRICK_START_X + (8 * (DEFAULT_BRICK_WIDTH + DEFAULT_BRICK_HOR_SPACE) ) - DEFAULT_BRICK_HOR_SPACE;
- m_ball_rect.right = m_ball_rect.left + (2 * (DEFAULT_BRICK_WIDTH + DEFAULT_BRICK_HOR_SPACE) ) + DEFAULT_BRICK_HOR_SPACE;
- m_ball_rect.bottom = m_ball_rect.top + (2 * (DEFAULT_BRICK_HEIGHT + DEFAULT_BRICK_VER_SPACE) ) + DEFAULT_BRICK_VER_SPACE;
- if (m_game_turns_remaining < 5)
- {
- if ((m_ball[2].GetState() != CAPTIVE) && (!m_new_level_fg))
- {
- // do nothing
- }
- else
- {
- m_ball[2].SetXPos(634);
- m_ball[2].SetYPos(133);
- m_ball[2].SetXVel(-2);
- m_ball[2].SetYVel(2);
- m_ball[2].SetVelMultiplier(2);
- m_ball[2].SetCaptiveRect(m_ball_rect);
- }
- }
- else
- {
- m_ball[2].SetXPos(634);
- m_ball[2].SetYPos(133);
- m_ball[2].SetXVel(-2);
- m_ball[2].SetYVel(2);
- m_ball[2].SetVelMultiplier(2);
- //m_ball[2].SetState(CAPTIVE);
- m_ball[2].SetCaptiveRect(m_ball_rect);
- }
- } break;
- }
- return;
- };
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: InitializeBricks
- /// Purpose: Set the 'bricks' variables for the game
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: nothing
- /// Returns: nothing
- ///////////////////////////////////////////////////////////////////////////////
- void CSuperBrickBreaker::InitializeBricks()
- {
- ///////////////////////////////////////////////////////////////////////////
- /// reset the bricks based on the current game settings
- ///////////////////////////////////////////////////////////////////////////
- m_bricks.SetRowColProperties
- (
- /* num rows */ DEFAULT_BRICK_ROWS,
- /* num cols */ DEFAULT_BRICK_COLS,
- /* row colors */ m_brick_colors,
- /* row points */ m_brick_points,
- /* row vel */ m_brick_reflect_vel
- );
- m_bricks.InitializeBricks();
- ///////////////////////////////////////////////////////////////////////////
- /// if we are playing ESCAPE, remove the bricks that 'hold' the
- /// two captive balls
- ///////////////////////////////////////////////////////////////////////////
- if (m_game_type == SBB_ESCAPE)
- {
- m_bricks.SetBrickState(/* row */ 3, /* col */ 3, /* state */ BS_SKIP);
- m_bricks.SetBrickState(/* row */ 3, /* col */ 4, /* state */ BS_SKIP);
- m_bricks.SetBrickState(/* row */ 4, /* col */ 3, /* state */ BS_SKIP);
- m_bricks.SetBrickState(/* row */ 4, /* col */ 4, /* state */ BS_SKIP);
- m_bricks.SetBrickState(/* row */ 3, /* col */ 9, /* state */ BS_SKIP);
- m_bricks.SetBrickState(/* row */ 3, /* col */ 10, /* state */ BS_SKIP);
- m_bricks.SetBrickState(/* row */ 4, /* col */ 9, /* state */ BS_SKIP);
- m_bricks.SetBrickState(/* row */ 4, /* col */ 10, /* state */ BS_SKIP);
- }
- return;
- }
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: InitializeColors
- /// Purpose: Set the color variables from the DirectDraw color masks
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: nothing
- /// Returns: nothing
- ///////////////////////////////////////////////////////////////////////////////
- void CSuperBrickBreaker::InitializeColors()
- {
- m_3d_light_clr = RGBto16BitColor(/* red */ 255, /* green */ 255, /* blue */ 255);
- m_3d_shadow_clr = RGBto16BitColor(/* red */ 132, /* green */ 130, /* blue */ 132);
- m_black_clr = RGBto16BitColor(/* red */ 0, /* green */ 0, /* blue */ 0);
- m_blue_clr = RGBto16BitColor(/* red */ 0, /* green */ 0, /* blue */ 255);
- m_boundary_clr = RGBto16BitColor(/* red */ 214, /* green */ 211, /* blue */ 206);
- m_green_clr = RGBto16BitColor(/* red */ 0, /* green */ 130, /* blue */ 0);
- m_red_clr = RGBto16BitColor(/* red */ 255, /* green */ 0, /* blue */ 0);
- m_yellow_clr = RGBto16BitColor(/* red */ 255, /* green */ 255, /* blue */ 0);
- m_white_clr = RGBto16BitColor(/* red */ 255, /* green */ 255, /* blue */ 255);
- return;
- };
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: InitializeNewGame
- /// Purpose: Reset all the game variables based on the current game type
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: nothing
- /// Returns: nothing
- ///////////////////////////////////////////////////////////////////////////////
- void CSuperBrickBreaker::InitializeNewGame()
- {
- m_score = 0;
- m_level = 1;
- switch(m_game_type)
- {
- case SBB_STANDARD:
- {
- m_num_balls = 1;
- m_game_turns_remaining = 5;
- } break;
- case SBB_DOUBLE:
- {
- m_num_balls = 2;
- m_game_turns_remaining = 3;
- } break;
- case SBB_ESCAPE:
- {
- m_num_balls = 3;
- m_game_turns_remaining = 5;
- } break;
- }
- InitializeBalls();
- InitializeNewLevel();
- InitializeBricks();
- InitializePaddle();
- };
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: InitializeNewLevel
- /// Purpose: Intialize the bricks and balls for the start of a new level
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: nothing
- /// Returns: nothing
- ///////////////////////////////////////////////////////////////////////////////
- void CSuperBrickBreaker::InitializeNewLevel()
- {
- m_brick_colors[0] = m_red_clr;
- m_brick_colors[1] = m_red_clr;
- m_brick_colors[2] = m_yellow_clr;
- m_brick_colors[3] = m_yellow_clr;
- m_brick_colors[4] = m_green_clr;
- m_brick_colors[5] = m_green_clr;
- m_brick_colors[6] = m_blue_clr;
- m_brick_colors[7] = m_blue_clr;
- if (m_level >= 3)
- {
- int m_stop = m_level;
-
- if (m_level > 7)
- {
- m_stop = 7;
- }
- for (int i = 0; i < m_stop; i++)
- {
- m_brick_colors[i] = m_red_clr;
- }
- }
-
- for (int i = 0; i <= 7; i++)
- {
- if (m_brick_colors[i] == m_red_clr)
- {
- m_brick_points[i] = 16;
- m_brick_reflect_vel[i] = 4;
- }
- else if (m_brick_colors[i] == m_yellow_clr)
- {
- m_brick_points[i] = 8;
- m_brick_reflect_vel[i] = 3;
- }
- else if (m_brick_colors[i] == m_green_clr)
- {
- m_brick_points[i] = 4;
- m_brick_reflect_vel[i] = 2;
- }
- else if (m_brick_colors[i] == m_blue_clr)
- {
- m_brick_points[i] = 2;
- m_brick_reflect_vel[i] = 1;
- }
- }
- switch(m_game_type)
- {
- case SBB_STANDARD:
- {
- // no extra initialization required
- } break;
- case SBB_DOUBLE:
- {
- // no extra initialization required
- } break;
- case SBB_ESCAPE:
- {
- m_ball[1].SetState(CAPTIVE);
- m_ball[2].SetState(CAPTIVE);
- } break;
- }
- }
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: InitializePaddle
- /// Purpose: Set the required default paddle properties and limits
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: nothing
- /// Returns: nothing
- ///////////////////////////////////////////////////////////////////////////////
- void CSuperBrickBreaker::InitializePaddle()
- {
- int l_cnt = 1;
- switch(m_game_type)
- {
- case SBB_STANDARD:
- {
- l_cnt = PADDLE_COUNT_STANDARD;
- }
- break;
- case SBB_DOUBLE:
- {
- l_cnt = PADDLE_COUNT_DOUBLE;
- }
- break;
- case SBB_ESCAPE:
- {
- l_cnt = PADDLE_COUNT_ESCAPE;
- }
- break;
- }
- m_paddle.SetBaseProperties
- (
- /* p_cnt*/ l_cnt,
- /* p_hor_space */ DEFAULT_PADDLE_HOR_SPACE,
- /* p_length */ DEFAULT_PADDLE_STANDARD_LENGTH,
- /* p_height */ DEFAULT_PADDLE_HEIGHT
- );
- m_paddle.SetPaddleLimits
- (
- /* p_min_limit */ 23,
- /* p_max_limit */ 776,
- /* p_bottom_limit */ 597
- );
- };
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: InitializePlayingArea
- /// Purpose: Set the boundary (playing area) rect variables
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: nothing
- /// Returns: nothing
- ///////////////////////////////////////////////////////////////////////////////
- void CSuperBrickBreaker::InitializePlayingArea()
- {
- m_left_boun_rect.left = 0;
- m_left_boun_rect.top = 30;
- m_left_boun_rect.right = 23;
- m_left_boun_rect.bottom = 599;
-
- m_top_boun_rect.left = 0;
- m_top_boun_rect.top = 30;
- m_top_boun_rect.right = 799;
- m_top_boun_rect.bottom = 53;
-
- m_right_boun_rect.left = 776;
- m_right_boun_rect.top = 30;
- m_right_boun_rect.right = 799;
- m_right_boun_rect.bottom = 599;
- m_left_3d_light_rect.left = 0;
- m_left_3d_light_rect.top = 30;
- m_left_3d_light_rect.right = 1;
- m_left_3d_light_rect.bottom = 599;
- m_left_3d_shadow_rect.left = 22;
- m_left_3d_shadow_rect.top = 53;
- m_left_3d_shadow_rect.right = 23;
- m_left_3d_shadow_rect.bottom = 599;
- m_top_3d_light_rect.left = 0;
- m_top_3d_light_rect.top = 30;
- m_top_3d_light_rect.right = 799;
- m_top_3d_light_rect.bottom = 31;
- m_top_3d_shadow_rect.left = 22;
- m_top_3d_shadow_rect.top = 52;
- m_top_3d_shadow_rect.right = 776;
- m_top_3d_shadow_rect.bottom = 53;
- m_right_3d_light_rect.left = 776;
- m_right_3d_light_rect.top = 53;
- m_right_3d_light_rect.right = 777;
- m_right_3d_light_rect.bottom = 599;
- m_right_3d_shadow_rect.left = 798;
- m_right_3d_shadow_rect.top = 30;
- m_right_3d_shadow_rect.right = 799;
- m_right_3d_shadow_rect.bottom = 599;
- m_playing_area_rect.left = 23;
- m_playing_area_rect.top = 53;
- m_playing_area_rect.right = 776;
- m_playing_area_rect.bottom = 598;
- return;
- };
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: IsBrickAtBallLocation
- /// Purpose: Determine if a brick is currently at the location of the ball
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: RECT describing current position of a ball
- /// Returns: true if a brick (with a NORMAL state) exists at the ball location
- /// pointer to TBrick structure of the brick that exists at the location
- ///////////////////////////////////////////////////////////////////////////////
- bool CSuperBrickBreaker::IsBrickAtBallLocation(const RECT p_ball_rect, TBrick* l_hit_brick)
- {
- TBallCorner l_ball_corner[4];
- EIntersect l_result = IS_NONE;
- /*************************
- ** top left corner
- *************************/
- l_ball_corner[0].x = p_ball_rect.left;
- l_ball_corner[0].y = p_ball_rect.top;
- /*************************
- ** top right corner
- *************************/
- l_ball_corner[1].x = p_ball_rect.right;
- l_ball_corner[1].y = p_ball_rect.top;
- /*************************
- ** bottom right corner
- *************************/
- l_ball_corner[2].x = p_ball_rect.right;
- l_ball_corner[2].y = p_ball_rect.bottom;
- /*************************
- ** bottom left corner
- *************************/
- l_ball_corner[3].x = p_ball_rect.left;
- l_ball_corner[3].y = p_ball_rect.bottom;
- int j = 0;
- ///////////////////////////////////////////////////////////////////////////
- /// loop through each of the ball corners to determine if the ball
- /// struck the paddle
- ///////////////////////////////////////////////////////////////////////////
- while (j < 4)
- {
- bool l_is_brick = m_bricks.IsBrickAtPosition
- (
- /* x */ l_ball_corner[j].x,
- /* y */ l_ball_corner[j].y,
- /* brick */ l_hit_brick
- );
- if (l_is_brick)
- {
- if (( (l_ball_corner[j].x >= l_hit_brick->rect.left) && (l_ball_corner[j].x <= l_hit_brick->rect.right) )
- && ( (l_ball_corner[j].y >= l_hit_brick->rect.top) && (l_ball_corner[j].y <= l_hit_brick->rect.bottom) )
- && (l_hit_brick->state == BS_NORMAL) )
- {
- return(true);
- }
- }
- j++;
- }
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: ProcessBalls
- /// Purpose: Set the 'ball' variables for the next frame
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: nothing
- /// Returns: true if the balls were handled (moved) successfully
- ///////////////////////////////////////////////////////////////////////////////
- bool CSuperBrickBreaker::ProcessBalls()
- {
- bool br = false;
- if (m_game_state == GS_GAMEPAUSED)
- {
- return(true);
- }
- ///////////////////////////////////////////////////////////////////////////
- /// loop through each ball
- ///////////////////////////////////////////////////////////////////////////
- for (int i = 0; i < m_num_balls; i++)
- {
- int l_x_pos = m_ball[i].GetXPos();
- int l_y_pos = m_ball[i].GetYPos();
- int l_x_vel = m_ball[i].GetVelMultiplier() * m_ball[i].GetXVel();
- int l_y_vel = m_ball[i].GetVelMultiplier() * m_ball[i].GetYVel();
- RECT l_ball_rect;
-
-
- EBallState l_ball_state = m_ball[i].GetState();
- EIntersect l_intersect = IS_NONE;
- if ( (l_ball_state == FREE) || (l_ball_state == CAPTIVE) )
- {
- ///////////////////////////////////////////////////////////////////////
- /// set new ball position based on current velocity
- ///////////////////////////////////////////////////////////////////////
- l_x_pos += l_x_vel;
- l_y_pos += l_y_vel;
- m_ball[i].SetXYPos(l_x_pos, l_y_pos);
- l_ball_rect.top = l_y_pos;
- l_ball_rect.left = l_x_pos;
- l_ball_rect.right = l_x_pos + BALL_WIDTH;
- l_ball_rect.bottom = l_y_pos + BALL_HEIGHT;
- ///////////////////////////////////////////////////////////////////////
- /// process the ball as a free ball
- ///////////////////////////////////////////////////////////////////////
- if (l_ball_state == FREE)
- {
- ///////////////////////////////////////////////////////////////////
- /// determine if the ball hit one of the playing area boundaries
- ///////////////////////////////////////////////////////////////////
- if (l_ball_rect.left <= m_playing_area_rect.left)
- {
- l_x_pos = m_playing_area_rect.left;
- l_intersect = IS_RIGHT; // ie. intersect right side of left boundary
- }
- if (l_ball_rect.right >= m_playing_area_rect.right)
- {
- l_x_pos = m_playing_area_rect.right - BALL_WIDTH;
- l_intersect = IS_LEFT;
- }
- if (l_ball_rect.top <= m_playing_area_rect.top)
- {
- l_y_pos = m_playing_area_rect.top;
- l_intersect = IS_BOTTOM;
- if (!m_hit_top_boun_fg)
- {
- m_hit_top_boun_fg = true;
- m_paddle.SetLength(DEFAULT_PADDLE_SHORT_LENGTH);
- }
- }
- if (l_ball_rect.bottom >= m_playing_area_rect.bottom)
- {
- --m_balls_in_play;
- m_ball[i].SetState(LOST);
- if (m_balls_in_play == 0)
- {
- if (m_game_turns_remaining == 0)
- {
- ProcessStateChange(/* new state */ GS_GAMEOVER);
- return(true);
- }
- else
- {
- --m_game_turns_remaining;
- ProcessStateChange(/* new state */ GS_STARTTURN);
- return(true);
- }
- }
- }
- ///////////////////////////////////////////////////////////////////
- /// determine if the ball hit the paddle
- ///////////////////////////////////////////////////////////////////
- if (l_intersect == IS_NONE) // didn't hit the boundary
- {
- l_intersect = CheckHitPaddle(l_ball_rect);
- if (l_intersect != IS_NONE)
- {
- // if we are playing 'Double' release the second ball on
- // first hit of the paddle
- if ( (!m_first_paddle_hit) && (m_game_type == SBB_DOUBLE) )
- {
- m_first_paddle_hit = true;
- if (m_game_type == SBB_DOUBLE)
- {
- m_ball[1].SetState(FREE);
- m_balls_in_play++;
- }
- }
- }
- }
- ///////////////////////////////////////////////////////////////////
- /// determine if the ball hit a brick
- ///////////////////////////////////////////////////////////////////
- if (l_intersect == IS_NONE) // didn't hit boundary or paddle
- {
- TBrick l_hit_brick;
- l_intersect = CheckHitBrick(l_ball_rect, &l_hit_brick);
- if (l_intersect != IS_NONE)
- {
- m_bricks.SetBrickState(l_hit_brick.row, l_hit_brick.col, BS_HIT);
- m_score += l_hit_brick.point_value;
- if (m_ball[i].GetVelMultiplier() > l_hit_brick.reflect_vel)
- {
- m_ball[i].SetVelMultiplier(m_ball[i].GetVelMultiplier() - 1);
- }
- else
- {
- m_ball[i].SetVelMultiplier(l_hit_brick.reflect_vel);
- }
-
- if (m_bricks.GetBricksRemaining() == 0)
- {
- m_new_level_fg = true;
- m_level++;
- InitializeNewLevel();
- InitializeBalls();
- InitializeBricks();
- ProcessStateChange(/* new state */ GS_STARTTURN);
- return(true);
- }
- }
- }
- if (l_intersect != IS_NONE)
- {
- m_ball[i].SetXYPos(l_x_pos, l_y_pos);
- }
- }
- ///////////////////////////////////////////////////////////////////////
- /// process the ball as a captive ball
- ///////////////////////////////////////////////////////////////////////
- else if (l_ball_state == CAPTIVE)
- {
- RECT l_captive_rect = m_ball[i].GetCaptiveRect();
- TBrick l_hit_brick;
- int l_temp_x = 0;
- int l_temp_y = 0;
- if (l_ball_rect.left <= l_captive_rect.left)
- {
- l_intersect = IS_RIGHT;
- l_temp_x = l_captive_rect.left;
- l_temp_y = l_y_pos;
- }
- else if (l_ball_rect.top <= l_captive_rect.top)
- {
- l_intersect = IS_BOTTOM;
- l_temp_x = l_x_pos;
- l_temp_y = l_captive_rect.top;
- }
- else if (l_ball_rect.right >= l_captive_rect.right)
- {
- l_intersect = IS_LEFT;
- l_temp_x = (l_captive_rect.right - BALL_WIDTH);
- l_temp_y = l_y_pos;
- }
- else if (l_ball_rect.bottom >= l_captive_rect.bottom)
- {
- l_intersect = IS_TOP;
- l_temp_x = l_x_pos;
- l_temp_y = (l_captive_rect.bottom - BALL_HEIGHT);
- }
-
- if (l_intersect != IS_NONE)
- {
- bool l_is_brick = IsBrickAtBallLocation(l_ball_rect, &l_hit_brick);
- if (l_is_brick)
- {
- if (l_hit_brick.state == BS_NORMAL)
- {
- // ball is still captive, set position to hit boundary
- m_ball[i].SetXYPos(l_temp_x, l_temp_y);
- }
- else if (l_hit_brick.state == BS_NORMAL)
- {
- m_ball[i].SetState(FREE);
- m_balls_in_play++;
- }
- }
- else
- {
- l_intersect = IS_NONE;
- m_ball[i].SetState(FREE);
- m_balls_in_play++;
- }
- }
- }
- if ( (l_intersect == IS_TOP) || (l_intersect == IS_BOTTOM) )
- {
- m_ball[i].ReflectY();
- }
- else if ( (l_intersect == IS_LEFT) || (l_intersect == IS_RIGHT) )
- {
- m_ball[i].ReflectX();
- }
-
- }
- }
- return(true);
- };
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: ProcessKeyboard
- /// Purpose: Process the DirectInput keyboard state information based
- /// the current state of the game
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: nothing
- /// Returns: nothing
- ///////////////////////////////////////////////////////////////////////////////
- bool CSuperBrickBreaker::ProcessKeyboard()
- {
- bool br = false;
- ///////////////////////////////////////////////////////////////////////////
- /// retrieve the keyboard data from DirectInput
- ///////////////////////////////////////////////////////////////////////////
- br = GetKeyboardState(m_key_state);
- if (!br)
- {
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- /// interpret the keyboard data based on the current state
- /// of the game
- ///////////////////////////////////////////////////////////////////////////
- switch(m_game_state)
- {
- case GS_MAINMENU: /// the main menu is currently displayed to the player
- {
- ///////////////////////////////////////////////////////////////////////////
- /// user pressed escape --> end the game
- ///////////////////////////////////////////////////////////////////////////
- if (m_key_state[DIK_ESCAPE] & 0x80)
- {
- PostQuitMessage(0);
- }
- ///////////////////////////////////////////////////////////////////////////
- /// user pressed up arrow --> set next game type
- ///////////////////////////////////////////////////////////////////////////
- else if (m_key_state[DIK_UP] & 0x80)
- {
- switch(m_game_type)
- {
- case SBB_STANDARD:
- {
- m_game_type = SBB_ESCAPE;
- } break;
- case SBB_DOUBLE:
- {
- m_game_type = SBB_STANDARD;
- } break;
- case SBB_ESCAPE:
- {
- m_game_type = SBB_DOUBLE;
- } break;
- }
- InitializeNewGame();
- }
- ///////////////////////////////////////////////////////////////////////////
- /// user pressed down arrow --> set next game type
- ///////////////////////////////////////////////////////////////////////////
- else if (m_key_state[DIK_DOWN] & 0x80)
- {
- switch(m_game_type)
- {
- case SBB_STANDARD:
- {
- m_game_type = SBB_DOUBLE;
- } break;
- case SBB_DOUBLE:
- {
- m_game_type = SBB_ESCAPE;
- } break;
- case SBB_ESCAPE:
- {
- m_game_type = SBB_STANDARD;
- } break;
- }
- InitializeNewGame();
- }
- ///////////////////////////////////////////////////////////////////////////
- /// user pressed return or space bar --> start game based
- /// on currently selected game
- ///////////////////////////////////////////////////////////////////////////
- else if ( (m_key_state[DIK_RETURN] & 0x80) || (m_key_state[DIK_SPACE] & 0x80) )
- {
- --m_game_turns_remaining;
- br = ProcessStateChange(/* new state */ GS_STARTTURN);
- if (!br)
- {
- return(false);
- }
- }
- } break;
- case GS_STARTTURN: /// the READY message is displayed to warn player of start
- /// of the next turn (or start of the game)
- {
- ///////////////////////////////////////////////////////////////////////////
- /// user pressed return or space bar --> move into game play state
- ///////////////////////////////////////////////////////////////////////////
- if ( (m_key_state[DIK_RETURN] & 0x80) || (m_key_state[DIK_SPACE] & 0x80) )
- {
- br = ProcessStateChange(/* new state */ GS_GAMEPLAY);
- if (!br)
- {
- return(false);
- }
- }
- } break;
- case GS_GAMEPLAY: /// we are in a 'general' state of play (ie. the balls are
- /// still in play and there are bricks remaining
- {
- ///////////////////////////////////////////////////////////////////////////
- /// user pressed escape --> go to 'game paused' state
- ///////////////////////////////////////////////////////////////////////////
- if (m_key_state[DIK_ESCAPE] & 0x80)
- {
- br = ProcessStateChange(/* new state */ GS_GAMEPAUSED);
- if (!br)
- {
- return(false);
- }
- //PostQuitMessage(0);
- }
- ///////////////////////////////////////////////////////////////////////////
- /// user pressed left arrow --> set negative paddle velocity
- ///////////////////////////////////////////////////////////////////////////
- if (m_key_state[DIK_LEFT] & 0x80)
- {
- m_paddle.SetXVel(-PADDLE_VELOCITY);
- }
- ///////////////////////////////////////////////////////////////////////////
- /// user pressed right arrow --> set positive paddle velocity
- ///////////////////////////////////////////////////////////////////////////
- else if (m_key_state[DIK_RIGHT] & 0x80)
- {
- m_paddle.SetXVel(PADDLE_VELOCITY);
- }
- } break;
- case GS_GAMEPAUSED:
- {
- ///////////////////////////////////////////////////////////////////////////
- /// user pressed up arrow --> set next paused menu selection
- ///////////////////////////////////////////////////////////////////////////
- if (m_key_state[DIK_UP] & 0x80)
- {
- switch(m_paused_state)
- {
- case PS_RESUME:
- {
- m_paused_state = PS_MAINMENU;
- } break;
- case PS_MAINMENU:
- {
- m_paused_state = PS_RESUME;
- } break;
- }
- }
- ///////////////////////////////////////////////////////////////////////////
- /// user pressed down arrow --> set next game type
- ///////////////////////////////////////////////////////////////////////////
- else if (m_key_state[DIK_DOWN] & 0x80)
- {
- switch(m_paused_state)
- {
- case PS_RESUME:
- {
- m_paused_state = PS_MAINMENU;
- } break;
- case PS_MAINMENU:
- {
- m_paused_state = PS_RESUME;
- } break;
- }
- }
- ///////////////////////////////////////////////////////////////////////////
- /// user pressed return or space bar --> take next action based
- /// on selected option
- ///////////////////////////////////////////////////////////////////////////
- else if ( (m_key_state[DIK_RETURN] & 0x80) || (m_key_state[DIK_SPACE] & 0x80) )
- {
- switch(m_paused_state)
- {
- case PS_RESUME:
- {
- br = ProcessStateChange(/* new state */ GS_GAMEPLAY);
- if (!br)
- {
- return(false);
- }
- } break;
- case PS_MAINMENU:
- {
- br = ProcessStateChange(/* new state */ GS_MAINMENU);
- if (!br)
- {
- return(false);
- }
- } break;
- }
-
- }
- } break;
- case GS_GAMEOVER:
- {
- ///////////////////////////////////////////////////////////////////////////
- /// user pressed up arrow --> set next game over menu selection
- ///////////////////////////////////////////////////////////////////////////
- if (m_key_state[DIK_UP] & 0x80)
- {
- switch(m_gameover_state)
- {
- case GO_PLAYAGAIN:
- {
- m_gameover_state = GO_MAINMENU;
- } break;
- case GO_MAINMENU:
- {
- m_gameover_state = GO_PLAYAGAIN;
- } break;
- }
- }
- ///////////////////////////////////////////////////////////////////////////
- /// user pressed down arrow --> set next game type
- ///////////////////////////////////////////////////////////////////////////
- else if (m_key_state[DIK_DOWN] & 0x80)
- {
- switch(m_gameover_state)
- {
- case GO_PLAYAGAIN:
- {
- m_gameover_state = GO_MAINMENU;
- } break;
- case GO_MAINMENU:
- {
- m_gameover_state = GO_PLAYAGAIN;
- } break;
- }
- }
- ///////////////////////////////////////////////////////////////////////////
- /// user pressed return or space bar --> take next action based
- /// on selected option
- ///////////////////////////////////////////////////////////////////////////
- else if ( (m_key_state[DIK_RETURN] & 0x80) || (m_key_state[DIK_SPACE] & 0x80) )
- {
- switch(m_gameover_state)
- {
- case GO_PLAYAGAIN:
- {
- InitializeNewGame();
- br = ProcessStateChange(/* new state */ GS_STARTTURN);
- if (!br)
- {
- return(false);
- }
- } break;
- case GO_MAINMENU:
- {
- InitializeNewGame();
- br = ProcessStateChange(/* new state */ GS_MAINMENU);
- if (!br)
- {
- return(false);
- }
- } break;
- }
-
- }
- } break;
- default:
- {
- }
- };
- return(true);
- }
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: ProcessPaddle
- /// Purpose: Set the 'paddle' variables for the next frame
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: nothing
- /// Returns: true if the paddle was handled (moved) successfully
- ///////////////////////////////////////////////////////////////////////////////
- bool CSuperBrickBreaker::ProcessPaddle()
- {
- ///////////////////////////////////////////////////////////////////////////
- /// retrieve the current paddle position and velocity values
- ///////////////////////////////////////////////////////////////////////////
- int l_x_pos = m_paddle.GetXPos();
- int l_x_vel = m_paddle.GetXVel();
- int l_length = m_paddle.GetLength();
- int l_paddle_right = (l_x_pos + l_length);
- ///////////////////////////////////////////////////////////////////////////
- /// set new paddle position based on current velocity
- ///////////////////////////////////////////////////////////////////////////
- l_x_pos += l_x_vel;
- ///////////////////////////////////////////////////////////////////////////
- /// ensure new paddle position is within game playing area
- ///////////////////////////////////////////////////////////////////////////
- if (l_x_vel < 0) // we are moving to the left
- {
- if (l_x_pos < m_playing_area_rect.left)
- {
- l_x_pos = m_playing_area_rect.left;
- }
- }
- else if (l_x_vel > 0) // we are moving to the right
- {
- if (l_paddle_right >= m_playing_area_rect.right)
- {
- l_x_pos = (m_playing_area_rect.right - l_length);
- }
- }
- ///////////////////////////////////////////////////////////////////////////
- /// move paddle to new location and reset velocity to zero
- ///////////////////////////////////////////////////////////////////////////
- if (l_x_vel != 0)
- {
- m_paddle.SetXPos(l_x_pos);
- m_paddle.SetXVel(0);
- }
- return(true);
- };
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: ProcessStateChange
- /// Purpose: Check the state change is valid and set the variables for the
- /// state change
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: nothing
- /// Returns: true if the state change was processed (moved) successfully
- ///////////////////////////////////////////////////////////////////////////////
- bool CSuperBrickBreaker::ProcessStateChange(EGameState m_new_game_state)
- {
- EGameState l_old_state = m_game_state;
- m_game_state = m_new_game_state;
- switch(m_new_game_state)
- {
- case GS_MAINMENU:
- {
- SetFrameRate(10);
- InitializeNewGame();
- } break;
- case GS_STARTTURN:
- {
- if (m_game_state == GS_GAMEPAUSED)
- {
- InitializeNewGame();
- }
- SetFrameRate(10);
- InitializeBalls();
- InitializePaddle();
- } break;
- case GS_GAMEPLAY:
- {
- m_ball[0].SetState(FREE);
- SetFrameRate(20);
- m_balls_in_play = 1;
- } break;
- case GS_GAMEPAUSED:
- {
- SetFrameRate(10);
- m_paused_state = PS_RESUME;
- } break;
- case GS_GAMEOVER:
- {
- m_gameover_state = GO_PLAYAGAIN;
- for (int i = 0; i < m_num_balls; i++)
- {
- if (m_ball[i].GetState() == FREE)
- {
- m_ball[i].SetState(IDLE);
- }
- }
- SetFrameRate(10);
- }
- }
- return(true);
- }
- /// END OF FILE ///////////////////////////////////////////////////////////////