⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 btgame.cpp

📁 Games programming all in one code chapter 21(final chapter)
💻 CPP
📖 第 1 页 / 共 2 页
字号:
  {
    /* 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 + -