📄 btgame.cpp
字号:
{
/* Get block proprieties */
iBlockWidth = m_pkBlocks [iBlock].GetWidth ();
iBlockHeight = m_pkBlocks [iBlock].GetHeight ();
pkBlockEntity = m_pkBlocks [iBlock].GetObject ();
kBlockPosition = pkBlockEntity->GetPosition ();
/* Test to see if the ball touched the block and if so,
destroy the block, add points and play sound */
if ((kBallPosition [0] >= kBlockPosition [0] - iBlockWidth/2) &&
(kBallPosition [0] <= kBlockPosition [0] + iBlockWidth/2) &&
(kBallPosition [1] >= kBlockPosition [1] - iBlockHeight/2) &&
(kBallPosition [1] <= kBlockPosition [1] + iBlockHeight/2) )
{
m_pkBlocks [iBlock].Destroy ();
m_iScore += 10;
m_kSoundBlink.Play (mrFalse);
/* Get distance from ball to the all the block sides */
mrReal32 iX1;
mrReal32 iY1;
mrReal32 iX2;
mrReal32 iY2;
iX1 = kBlockPosition [0] + iBlockWidth/2 - (kBallPosition [0]-iBallRadius);
iX2 = kBlockPosition [0] - iBlockWidth/2 - (kBallPosition [0]+iBallRadius);
iY1 = kBlockPosition [1] + iBlockHeight/2 - (kBallPosition [1]-iBallRadius);
iY2 = kBlockPosition [1] - iBlockHeight/2 - (kBallPosition [1]+iBallRadius);
/* Depending on which side of the block the ball hit, handle the collision
with the appropriate collision plane normal */
if ( (fabs(iX1) < fabs(iX2)) &&
(fabs(iX1) < fabs(iY1)) &&
(fabs(iX1) < fabs(iY2)) )
{
pkBallEntity->HandleCollision (*pkBlockEntity, mrVector2D (-1,0));
}
if ( (fabs(iX2) < fabs(iY1)) &&
(fabs(iX2) < fabs(iY2)) )
{
pkBallEntity->HandleCollision (*pkBlockEntity, mrVector2D (1,0));
}
else if ( fabs(iY1) < fabs(iY2) )
{
pkBallEntity->HandleCollision (*pkBlockEntity, mrVector2D (0,-1));
}
else
{
pkBallEntity->HandleCollision (*pkBlockEntity, mrVector2D (0,1));
}
}
}
}
}
/* Handle collisions of paddle with border and paddle with ball */
void btGame::HandleCollisionsPaddle (void)
{
mrVector2D kPaddlePosition;
mrEntity * kPaddleEntity;
mrUInt32 iPaddleWidth;
mrUInt32 iPaddleHeight;
mrEntity * pkBallEntity;
mrVector2D kBallPosition ;
mrUInt32 iBallRadius;
/* Get paddle and ball information */
iBallRadius = m_kBall.GetSize ();
pkBallEntity = m_kBall.GetObject ();
kBallPosition = pkBallEntity->GetPosition ();
kPaddleEntity = m_kPaddle.GetObject ();
kPaddlePosition = kPaddleEntity->GetPosition ();
iPaddleHeight = m_kPaddle.GetHeight ();
iPaddleWidth = m_kPaddle.GetWidth ()-iPaddleHeight;
/* Handle collision of ball with paddle */
if ((kBallPosition [0] + iBallRadius >
kPaddlePosition [0] - iPaddleWidth / 2) &&
(kBallPosition [0] - iBallRadius <
kPaddlePosition [0] + iPaddleWidth / 2) &&
(kBallPosition [1] + iBallRadius >
kPaddlePosition [1] - iPaddleHeight / 2) &&
(kBallPosition [1] + iBallRadius <
kPaddlePosition [1] + iPaddleHeight / 2) )
{
pkBallEntity->SetPosition (mrVector2D(kBallPosition [0],
(kPaddlePosition [1] - iPaddleHeight / 2) - iBallRadius));
pkBallEntity->HandleCollision (*kPaddleEntity, mrVector2D (0, -1));
m_kSoundBlink.Play (mrFalse);
}
/* Handle collisions of paddle and borders */
if (kPaddlePosition [0] - m_kPaddle.GetWidth() / 2 < 8)
{
kPaddleEntity->SetPosition (mrVector2D (
(mrReal32)(8 + m_kPaddle.GetWidth()/2),kPaddlePosition [1]));
kPaddleEntity->HandleCollision (m_kBorder, mrVector2D (1, 0));
}
if (kPaddlePosition [0] + m_kPaddle.GetWidth()/2 > 624)
{
kPaddleEntity->SetPosition (mrVector2D (
(mrReal32)(624 - m_kPaddle.GetWidth()/2),kPaddlePosition [1]));
kPaddleEntity->HandleCollision (m_kBorder, mrVector2D (-1, 0));
}
}
/* Handle collisions of ball and border */
void btGame::HandleCollisionsBorder (void)
{
mrEntity * pkBallEntity;
mrVector2D kBallPosition;
mrUInt32 iBallRadius;
/* Get ball information */
iBallRadius = m_kBall.GetSize ();
pkBallEntity = m_kBall.GetObject ();
kBallPosition = pkBallEntity->GetPosition ();
/* Check if ball hit any of the borders */
if (kBallPosition [0] + iBallRadius > 624)
{
pkBallEntity->SetPosition (mrVector2D ((mrReal32)(624 - iBallRadius),
kBallPosition [1]));
pkBallEntity->HandleCollision (m_kBorder, mrVector2D (1, 0));
m_kSoundBlink.Play (mrFalse);
}
if (kBallPosition [0] - iBallRadius < 8)
{
pkBallEntity->SetPosition (mrVector2D ((mrReal32)(8 + iBallRadius),
kBallPosition [1]));
pkBallEntity->HandleCollision (m_kBorder, mrVector2D (1, 0));
m_kSoundBlink.Play (mrFalse);
}
if (kBallPosition [1] - iBallRadius < 16)
{
pkBallEntity->SetPosition (mrVector2D (kBallPosition [0],
(mrReal32)(16 + iBallRadius)));
pkBallEntity->HandleCollision (m_kBorder, mrVector2D (0, 1));
m_kSoundBlink.Play (mrFalse);
}
}
/* Process the game */
mrBool32 btGame::Process (mrReal32 fStep)
{
/* Process appropriate state */
switch (m_eGameState)
{
case btGameRunning:
ProcessFrame (fStep);
break;
case btGameLostBall:
ProcessLostBall (fStep);
break;
case btGameLost:
ProcessLostGame (fStep);
break;
case btGameSplash:
ProcessSplash (fStep);
break;
case btGameMenu:
ProcessMenu (fStep);
break;
case btGameLevelStarting:
ProcessLevelStarting (fStep);
break;
case btGameLevelComplete:
ProcessLevelComplete (fStep);
break;
case btGameComplete:
ProcessComplete (fStep);
break;
case btGameQuit:
return mrFalse;
break;
}
return mrTrue;
}
/* Process the current frame */
void btGame::ProcessFrame (mrReal32 fStep)
{
/* Check if the ball hit the bottom of the screen */
if ((m_kBall.GetObject ()->GetPosition () [1] >= 443) &&
(m_kBall.GetIsAlive ()))
{
m_kBall.Destroy ();
m_eGameState = btGameLostBall;
m_fTimer = 0;
m_kSoundDie.Play (mrFalse);
}
/* Check the number of blocks that are alive */
mrUInt32 iBlock;
mrUInt32 iBlocksAlive;
iBlocksAlive = 0;
for (iBlock=0; iBlock < m_iBlocks; iBlock++)
{
if (m_pkBlocks [iBlock].GetIsAlive () == mrTrue)
{
iBlocksAlive ++;
}
}
/* If no blocks are alive, level is complete */
if (iBlocksAlive == 0)
{
m_eGameState = btGameLevelComplete;
}
mrEntity * pkPaddleEntity;
pkPaddleEntity = m_kPaddle.GetObject ();
/* Update the keyboard and see if there are any keys pressed,
if so, apply the corresponding force to the paddle */
m_kKeyboard.Update ();
if (m_kKeyboard.IsButtonDown (DIK_RIGHT))
{
pkPaddleEntity->ApplyLinearForce (mrVector2D (4500000, 0));
}
if (m_kKeyboard.IsButtonDown (DIK_LEFT))
{
pkPaddleEntity->ApplyLinearForce (mrVector2D (-4500000, 0));
}
/* Save game */
if (m_kKeyboard.IsButtonDown (DIK_S))
{
SaveGame ();
}
/* Update all the game members */
HandleCollisions ();
m_kPaddle.Update (fStep);
m_kBall.Update (fStep);
}
/* Process lost ball */
void btGame::ProcessLostBall (mrReal32 fStep)
{
m_fTimer += fStep;
m_kBall.Update (fStep);
/* If no more balls, game over */
if (m_iBalls == 0)
{
/* Wait a little for ball explosion */
if (m_fTimer > 1)
{
m_eGameState = btGameLost;
}
}
/* Restart playing */
else
{
/* If only one second has passed, show ready */
if ( (m_fTimer > 1) && (m_fTimer <= 2) )
{
m_kReadyGo.SetSize (254, 126);
m_kReadyGo.SetCurrentAnimation (0);
}
/* If only two seconds has passed, show go */
if ( (m_fTimer > 2) && (m_fTimer <= 3) )
{
m_kReadyGo.SetSize (254, 126);
m_kReadyGo.SetCurrentAnimation (1);
}
/* If three seconds has passed, restart game */
if (m_fTimer > 3)
{
m_kReadyGo.SetSize (0, 0);
m_kBall.Create ();
m_kPaddle.Create ();
m_eGameState = btGameRunning;
m_fTimer = 0;
m_iBalls--;
}
}
}
/* Process lost game */
void btGame::ProcessLostGame (mrReal32 fStep)
{
m_eGameState = btGameMenu;
m_fTimer = 0;
}
/* Process splash screen */
void btGame::ProcessSplash (mrReal32 fStep)
{
/* Wait three seconds then switch to the main menu */
m_fTimer += fStep;
if (m_fTimer <= 3)
{
}
else
{
m_eGameState = btGameMenu;
m_fTimer = 0;
}
}
/* Process menu */
void btGame::ProcessMenu (mrReal32 fStep)
{
m_kKeyboard.Update ();
/* If 'N' key was pressed, start a new game */
if (m_kKeyboard.IsButtonDown (DIK_N))
{
m_iCurrentLevel=0;
LoadLevel (m_aszLevels[m_iCurrentLevel]);
m_eGameState = btGameLevelStarting;
m_fTimer = 0;
m_iBalls = 2;
m_iScore = 0;
m_kBall.Create ();
m_kPaddle.Create ();
}
/* If 'N' key was pressed, load a game */
if (m_kKeyboard.IsButtonDown (DIK_L))
{
LoadGame ();
LoadLevel (m_aszLevels[m_iCurrentLevel]);
m_eGameState = btGameLevelStarting;
m_fTimer = 0;
m_kBall.Create ();
m_kPaddle.Create ();
}
/* If 'Q' key was pressed, quit the game */
if (m_kKeyboard.IsButtonDown (DIK_Q))
{
m_eGameState = btGameQuit;
}
}
/* Process level starting */
void btGame::ProcessLevelStarting (mrReal32 fStep)
{
m_fTimer += fStep;
/* If only one second has passed, show ready */
if ( (m_fTimer > 1) && (m_fTimer <= 2) )
{
m_kReadyGo.SetSize (254, 126);
m_kReadyGo.SetCurrentAnimation (0);
}
/* If only two seconds has passed, show go */
if ( (m_fTimer > 2) && (m_fTimer <= 3) )
{
m_kReadyGo.SetSize (254, 126);
m_kReadyGo.SetCurrentAnimation (1);
}
/* If three seconds has passed, restart game */
if (m_fTimer > 3)
{
m_kReadyGo.SetSize (0, 0);
m_eGameState = btGameRunning;
m_fTimer = 0;
}
}
/* Process level complete */
void btGame::ProcessLevelComplete (mrReal32 fStep)
{
m_iCurrentLevel ++;
/* Level complete */
if (m_iCurrentLevel >= m_iLevels)
{
m_eGameState = btGameComplete;
}
/* Load new level */
else
{
LoadLevel (m_aszLevels [m_iCurrentLevel]);
m_kBall.Create ();
m_kPaddle.Create ();
m_eGameState = btGameLevelStarting;
m_fTimer = 0;
}
}
/* Process game complete */
void btGame::ProcessComplete (mrReal32 fStep)
{
/* Wait five seconds then switch to the main menu */
m_fTimer += fStep;
if (m_fTimer <= 5)
{
}
else
{
m_eGameState = btGameMenu;
m_fTimer = 0;
}
}
/* Load a game from file */
void btGame::LoadGame (void)
{
fstream kGame;
kGame.open ("game.sav", ios::in);
if (kGame.is_open ())
{
/* Read game data */
kGame >> m_iBalls;
kGame >> m_iScore;
kGame >> m_iCurrentLevel;
}
kGame.close ();
}
/* Save a game to a file */
void btGame::SaveGame (void)
{
fstream kGame;
kGame.open ("game.sav", ios::out);
if (kGame.is_open ())
{
/* Save game data */
kGame << m_iBalls << " ";
kGame << m_iScore << " ";
kGame << m_iCurrentLevel << " ";
}
kGame.close ();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -