00001 #include "BreakoutGameScene.h"
00002
00003 #include "GameConfig.h"
00004
00005 #include "EventManager.h"
00006 #include "ApplicationEvents.h"
00007 #include "InputEvents.h"
00008 #include "BreakoutEvents.h"
00009
00010 #include "BreakoutLGLines.h"
00011 #include "BreakoutLGCircle.h"
00012 #include "BreakoutLGAlternate.h"
00013
00014 #include "DebugUtil.h"
00015
00016 BreakoutGameScene::BreakoutGameScene()
00017 : m_bIsActive(false), m_pBall(0), m_pPaddle(0), m_pWorldBoundaries(0), m_deathLineY(0),
00018 m_playerLives(0), m_playerScore(0), m_levelNumber(0), m_levelStatus(eLevelStarting),
00019 m_bgSprite(0), m_startLevelText(0), m_endLevelText(0), m_pScoreCounter(0), m_pLevelCounter(0),
00020 m_statusChangeTime(0), m_pLivesCounter(0), m_pCurrentLevel(0)
00021 {
00022
00023 }
00024
00025 BreakoutGameScene::~BreakoutGameScene()
00026 {
00027
00028 }
00029
00030 void BreakoutGameScene::Initialise()
00031 {
00032 DebugUtil::outputDebugText("Breakout Game Scene: Initialisation Start.\n");
00033 m_deathLineY = SCREEN_HEIGHT;
00034 m_playerLives = PLAYER_START_LIVES;
00035
00036 m_pBall = new BreakoutBall(7, ColourRGB(255,0,0), ColourRGB(0,0,255));
00037 m_pWorldBoundaries = new BreakoutWorldBoundaries(Vector2i(WALL_BORDER_SIZE, WALL_BORDER_SIZE), Vector2i(SCREEN_WIDTH - WALL_BORDER_SIZE, SCREEN_HEIGHT + 20));
00038 m_pPaddle = new BreakoutPaddle(Vector2i(160, SCREEN_HEIGHT - WALL_BORDER_SIZE - 15), Vector2i(60, 5), ColourRGB(15,255,15), ColourRGB(64,255,128));
00039 m_pScoreCounter = new BreakoutScoreCounter(Vector2i(2,2), ColourRGB(255,255,255), m_playerScore);
00040 m_pLevelCounter = new BreakoutScoreCounter(Vector2i(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2), ColourRGB(255,255,0), m_levelNumber);
00041 m_pLivesCounter = new BreakoutScoreCounter(Vector2i(SCREEN_WIDTH - (CHARACTER_WIDTH * 3), 2), ColourRGB(255,255,255), m_playerLives);
00042
00043 DebugUtil::outputDebugText("Breakout Game Scene: Objects created.\n");
00044
00045 AABBi locationArea(BOX_AREA_POS_X, BOX_AREA_POS_X + BOX_AREA_WIDTH, BOX_AREA_POS_Y + BOX_AREA_HEIGHT, BOX_AREA_POS_Y);
00046 Vector2i boxSize(MEDIUM_BOX_WIDTH, MEDIUM_BOX_HEIGHT);
00047 m_pBoxLocations = new BreakoutLocationArray(locationArea, boxSize, BOX_LOCATION_PADDING);
00048
00049 BreakoutLGLines* pLinesGen = new BreakoutLGLines();
00050 m_levelGenerators.push_back(pLinesGen);
00051
00052 BreakoutLGCircle* pCircleGen = new BreakoutLGCircle();
00053 m_levelGenerators.push_back(pCircleGen);
00054
00055 BreakoutLGAlternate* pAlternateGen = new BreakoutLGAlternate();
00056 m_levelGenerators.push_back(pAlternateGen);
00057
00058 DebugUtil::outputDebugText("Breakout Game Scene: Level generators created.\n");
00059
00060 StartNewLevel();
00061 DebugUtil::outputDebugText("Breakout Game Scene: Level generated.\n");
00062
00063 m_bgSprite = Visualisation::getSingleton()->CreateSpriteStarryBackground(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_WIDTH / 5);
00064 m_startLevelText = Visualisation::getSingleton()->CreateSpriteText("Level Start!", ColourRGB(255,255,0));
00065 m_endLevelText = Visualisation::getSingleton()->CreateSpriteText("Level Complete!", ColourRGB(255,255,0));
00066 m_livesLabel = Visualisation::getSingleton()->CreateSpriteText("Lives:", ColourRGB(255,255,255));
00067
00068 EventManager::getSingleton()->AddEventListener(ButtonInputEvent::cEventName, this);
00069
00070 DebugUtil::outputDebugText("Breakout Game Scene Initialisation End.\n");
00071 }
00072
00073 void BreakoutGameScene::Update()
00074 {
00075 if(!m_bIsActive)
00076 return;
00077
00078 if(m_levelStatus == eLevelPlaying)
00079 {
00080 m_pPaddle->Update();
00081 m_pBall->Update();
00082
00083
00084 m_pBall->HandleCollisionWithWorldBoundaries(m_pWorldBoundaries);
00085 m_pBall->HandleCollisionWithPaddle(m_pPaddle);
00086 m_pPaddle->HandleCollisionWithWorldBoundaries(m_pWorldBoundaries);
00087
00088 for(size_t i = 0; i < m_pCurrentLevel->size(); i++)
00089 {
00090 if(m_pCurrentLevel->at(i)->IsEnabled())
00091 {
00092 if(m_pBall->HandleCollisionWithBox(m_pCurrentLevel->at(i)))
00093 {
00094 m_pCurrentLevel->at(i)->TakeHit();
00095 m_playerScore += GAME_POINTS_PER_HIT;
00096 m_pScoreCounter->Update(m_playerScore);
00097 }
00098 }
00099 }
00100
00101
00102 BreakoutLevel::iterator levelIter = m_pCurrentLevel->begin();
00103 while(levelIter != m_pCurrentLevel->end())
00104 {
00105 if((*levelIter)->IsAlive() == false)
00106 {
00107 delete *levelIter;
00108 levelIter = m_pCurrentLevel->erase(levelIter);
00109 }
00110 else
00111 levelIter++;
00112 }
00113
00114 InputHandler* pInput = InputHandler::getSingleton();
00115 if(pInput->IsKeyDown(eKeyLeft) || pInput->IsKeyDown(eKeyUpLeft) || pInput->IsKeyDown(eKeyDownLeft))
00116 m_pPaddle->SetVelocity(Vector2i(-PADDLE_SPEED, m_pPaddle->GetVelocity().y));
00117 else if(pInput->IsKeyDown(eKeyRight) || pInput->IsKeyDown(eKeyUpRight) || pInput->IsKeyDown(eKeyDownRight))
00118 m_pPaddle->SetVelocity(Vector2i(PADDLE_SPEED, m_pPaddle->GetVelocity().y));
00119 else
00120 m_pPaddle->SetVelocity(Vector2i(0, m_pPaddle->GetVelocity().y));
00121
00122 CheckGameConditions();
00123 }
00124 else if(m_levelStatus == eLevelStarting)
00125 {
00126 if(m_statusChangeTime + LEVEL_LEAD_IN_TIME < SDL_GetTicks())
00127 m_levelStatus = eLevelPlaying;
00128 }
00129 else if(m_levelStatus == eLevelEnding)
00130 {
00131 if(m_statusChangeTime + LEVEL_LEAD_IN_TIME < SDL_GetTicks())
00132 StartNewLevel();
00133 }
00134 }
00135
00136 void BreakoutGameScene::CheckGameConditions()
00137 {
00138 if(m_pBall->GetPosition().y > m_deathLineY)
00139 {
00140 m_playerLives--;
00141 if(m_playerLives < 0)
00142 {
00143 BreakoutGameOverEvent* pEvent = new BreakoutGameOverEvent();
00144 EventManager::getSingleton()->QueueEvent(pEvent);
00145 return;
00146 }
00147
00148 m_pLivesCounter->Update(m_playerLives);
00149 m_pPaddle->AttachBallToPaddle(m_pBall);
00150 }
00151
00152
00153 if(m_pCurrentLevel->size() == 0)
00154 {
00155 m_levelStatus = eLevelEnding;
00156 m_playerLives++;
00157 m_statusChangeTime = SDL_GetTicks();
00158 }
00159 }
00160
00161 void BreakoutGameScene::StartNewLevel()
00162 {
00163 if(m_pCurrentLevel)
00164 delete m_pCurrentLevel;
00165
00166 m_levelNumber++;
00167 m_pLevelCounter->Update(m_levelNumber);
00168
00169 Vector2i boxSize(MEDIUM_BOX_WIDTH, MEDIUM_BOX_HEIGHT);
00170
00171 int levelGenIndex = rand() % m_levelGenerators.size();
00172 m_pCurrentLevel = m_levelGenerators[levelGenIndex]->GenerateLevel(m_pBoxLocations, boxSize, m_levelNumber);
00173 m_pPaddle->AttachBallToPaddle(m_pBall);
00174 m_levelStatus = eLevelStarting;
00175 m_statusChangeTime = SDL_GetTicks();
00176 }
00177
00178 void BreakoutGameScene::Reset()
00179 {
00180 m_levelNumber = 0;
00181 m_playerLives = PLAYER_START_LIVES;
00182 m_playerScore = 0;
00183
00184 StartNewLevel();
00185 }
00186
00187 void BreakoutGameScene::Draw()
00188 {
00189 if(!m_bIsActive)
00190 return;
00191
00192 Visualisation::getSingleton()->DrawSprite(m_bgSprite, 0, 0);
00193 m_pScoreCounter->Draw();
00194
00195 Vector2i livesPos = m_pLivesCounter->GetPosition();
00196 livesPos.x -= Visualisation::getSingleton()->GetSpriteWidth(m_livesLabel);
00197 Visualisation::getSingleton()->DrawSprite(m_livesLabel, livesPos.x, livesPos.y);
00198 m_pLivesCounter->Draw();
00199
00200 if(m_levelStatus == eLevelPlaying)
00201 {
00202 m_pBall->Draw();
00203 m_pPaddle->Draw();
00204
00205 if(m_pCurrentLevel)
00206 {
00207 for(size_t i = 0; i < m_pCurrentLevel->size(); i++)
00208 m_pCurrentLevel->at(i)->Draw();
00209 }
00210 }
00211 else if(m_levelStatus == eLevelStarting)
00212 {
00213 int width = Visualisation::getSingleton()->GetSpriteWidth(m_startLevelText);
00214 Visualisation::getSingleton()->DrawSprite(m_startLevelText, (SCREEN_WIDTH / 2) - (width / 2), SCREEN_HEIGHT / 4);
00215 m_pLevelCounter->Draw();
00216 }
00217 else if(m_levelStatus == eLevelEnding)
00218 {
00219 int width = Visualisation::getSingleton()->GetSpriteWidth(m_endLevelText);
00220 Visualisation::getSingleton()->DrawSprite(m_endLevelText, (SCREEN_WIDTH / 2) - (width / 2), SCREEN_HEIGHT / 4);
00221 }
00222 }
00223
00224 void BreakoutGameScene::Shutdown()
00225 {
00226 delete m_pBall;
00227 delete m_pPaddle;
00228 delete m_pWorldBoundaries;
00229 delete m_pCurrentLevel;
00230 delete m_pBoxLocations;
00231 for(size_t i = 0; i < m_levelGenerators.size(); i++)
00232 delete m_levelGenerators[i];
00233
00234 m_levelGenerators.clear();
00235
00236 Visualisation::getSingleton()->RemoveSprite(m_bgSprite);
00237 Visualisation::getSingleton()->RemoveSprite(m_startLevelText);
00238 Visualisation::getSingleton()->RemoveSprite(m_endLevelText);
00239 Visualisation::getSingleton()->RemoveSprite(m_livesLabel);
00240 }
00241
00242 void BreakoutGameScene::Activate()
00243 {
00244 m_bIsActive = true;
00245 m_statusChangeTime = SDL_GetTicks();
00246 }
00247
00248 void BreakoutGameScene::Deactivate()
00249 {
00250 m_bIsActive = false;
00251 }
00252
00253 bool BreakoutGameScene::HandleEvent(IEvent *pEvent)
00254 {
00255 if(!m_bIsActive)
00256 return false;
00257
00258 if(pEvent->GetEventType() == ButtonInputEvent::cEventName)
00259 {
00260 ButtonInputEvent* pButtonEvent = (ButtonInputEvent*)pEvent;
00261 int key = pButtonEvent->GetKey();
00262
00263 if(key == eKeyButtonStart && pButtonEvent->IsKeyDown())
00264 {
00265 BreakoutPauseGameEvent* pEvent = new BreakoutPauseGameEvent();
00266 EventManager::getSingleton()->QueueEvent(pEvent);
00267
00268 return true;
00269 }
00270
00271 if((key == eKeyButtonB || key == eKeyButtonX) && pButtonEvent->IsKeyDown())
00272 {
00273 if(m_pPaddle->IsBallAttached())
00274 {
00275 m_pPaddle->DetachBallFromPaddle();
00276 m_pBall->SetVelocity(Vector2i(BALL_START_SPEED_X, BALL_START_SPEED_Y));
00277 }
00278
00279 return true;
00280 }
00281
00282 return false;
00283 }
00284
00285 return false;
00286 }