/* ================================================================================ Game::Update Gets called once per frame to perform game logic. The parameter dt is the time elapsed since last frame (in seconds). ================================================================================ */ void Game::Update(float dt) { // Update the robot if (mRobot) { // If the robot has reached the last scene // disable its controls and play game over animation if (mScene == 6 && !mRobot->GetJumping() && !mRobot->GetFalling()) { mRobot->SetAutoPilot(true); } mRobot->Update(dt); } // Update the coins std::list<Coin*>::iterator coinIt = mCoins.begin(); while (coinIt != mCoins.end()) { Coin *coin = *coinIt; // Check if the robot collides with the coin if (mRobot->GetCollisonRect().y < coin->GetRect().y + coin->GetRect().h) { if ((mRobot->GetCollisonRect().x < coin->GetRect().x + coin->GetRect().w) && (mRobot->GetCollisonRect().x + mRobot->GetCollisonRect().w > coin->GetRect().x)) { if ((mRobot->GetCollisonRect().y < coin->GetRect().y + coin->GetRect().h) && (mRobot->GetCollisonRect().y + mRobot->GetCollisonRect().h > coin->GetRect().y)) { //I have found that the sound is delayed...So I start it a bit earlier than the actualy delete of the Coin if (coin->GetSoundDelay() == 0) { // You get 5 points! mPoints += 5; Mix_PlayChannel(-1, mCoinSound, 0); coin->SetSoundDelay(1); } //Once it has run through 4 times then it Deletes the coin else if (coin->GetSoundDelay() == 5) { coinIt = mCoins.erase(coinIt); // remove the entry from the list and advance iterator delete coin; coin = NULL; } else { coin->SetSoundDelay(1); } } else { coin->Update(dt); ++coinIt; } } else { coin->Update(dt); ++coinIt; } } else { coin->Update(dt); ++coinIt; } } // update all crawlers std::list<Crawler*>::iterator crawlerIt = mCrawlers.begin(); while (crawlerIt != mCrawlers.end()) { Crawler *crawler = *crawlerIt; if (crawler->GetState() == Crawler::CRAWLER_DEAD) { crawlerIt = mCrawlers.erase(crawlerIt); // remove the entry from the list and advance iterator delete crawler; // delete the object } else { // If the robot is falling from a jump or just falling if (mRobot->GetVerticalVelocity() > 0.0 && (mRobot->GetJumping() || mRobot->GetFalling())) { // Check if the robot has started squashing the poor crawler if (mRobot->GetCollisonRect().x + mRobot->GetCollisonRect().w > crawler->GetCollisionRect().x && mRobot->GetCollisonRect().x < crawler->GetCollisionRect().x + crawler->GetCollisionRect().w) { if (mRobot->GetCollisonRect().y + mRobot->GetCollisonRect().h > crawler->GetCollisionRect().y && mRobot->GetCollisonRect().y < crawler->GetCollisionRect().y) { if (crawler->GetState() != CrawlerWeak::CRAWLER_DYING) { // You get 25 points! mPoints += 25; if (crawler->IsJumpedOn()) { Mix_PlayChannel(-1, mStompSound, 0); mRobot->Bounce(-400, false); crawler->SetState(Crawler::CRAWLER_DYING); } else { Mix_PlayChannel(-1, mStompSoundNoKill, 0); mRobot->Bounce(-400, false); crawler->SetState(Crawler::CRAWLER_DYING); } } } } } // If the robot runs into a crawler, the robot must die (but it should not falling onto it from above) else if (mRobot->GetCollisonRect().x + mRobot->GetCollisonRect().w > crawler->GetCollisionRect().x && mRobot->GetCollisonRect().x < crawler->GetCollisionRect().x + crawler->GetCollisionRect().w) { if (mRobot->GetCollisonRect().y + mRobot->GetCollisonRect().h > crawler->GetCollisionRect().y && mRobot->GetCollisonRect().y < crawler->GetCollisionRect().y + crawler->GetCollisionRect().h) { if (!mRobot->IsDead() && mRobot->GetVerticalVelocity() == -850.0f && crawler->GetState() != CrawlerWeak::CRAWLER_DYING) { // You lose a life:( mRobot->SetLives(mRobot->GetLives() - 1); Mix_PlayChannel(-1, mDieSound, 0); // Stop the background music Mix_HaltMusic(); if (mRobot->GetLives() == 0) { printf("\nGame over music is being played!"); Mix_VolumeMusic(32); Mix_PlayMusic(mBadGameOverMusic, 0); SetEntitiesGrayscale(true); } mRobot->Bounce(-400, true); // kill the robot } } } crawler->Update(dt); ++crawlerIt; } } // // update the explosions // std::list<Explosion*>::iterator it = mExplosions.begin(); while (it != mExplosions.end()) { Explosion* entity = *it; // get a pointer to this explosion if (entity->IsFinished()) { it = mExplosions.erase(it); // remove the entry from the list and advance iterator delete entity; // delete the object } else { entity->Update(dt); // update the entity ++it; // advance list iterator } } // // update the meteors // std::list<Meteor*>::iterator metIt = mMeteors.begin(); while (metIt != mMeteors.end()) { Meteor* entity = *metIt; // get a pointer to this meteor // If the meteor has either reached the ground, destroy it with an explosion if (entity->GetRect().y > mScrHeight-32-64) { if (!mRobot->IsDead()) { Mix_PlayChannel(-1, mThudSound, 0); } Explosion* boom = new Explosion(entity->GetRect().x + entity->GetRect().w / 2, entity->GetRect().y + entity->GetRect().h / 2); mExplosions.push_back(boom); metIt = mMeteors.erase(metIt); // remove the entry from the list and advance iterator delete entity; // delete the object } // If the meteor has hit the robot from the top, destroy it with an explosion and also kill the robot else if (entity->GetRect().y + entity->GetRect().h > mRobot->GetCollisonRect().y && entity->GetRect().y < mRobot->GetCollisonRect().y + mRobot->GetCollisonRect().h && entity->GetRect().x + entity->GetRect().w > mRobot->GetCollisonRect().x && entity->GetRect().x < mRobot->GetCollisonRect().x + mRobot->GetCollisonRect().w && !mRobot->IsDead()) { // You lose a life:( mRobot->SetLives(mRobot->GetLives() - 1); Mix_PlayChannel(-1, mThudSound, 0); Mix_PlayChannel(-1, mDieSound, 0); // Stop the background music Mix_HaltMusic(); if (mRobot->GetLives() == 0) { Mix_VolumeMusic(32); Mix_PlayMusic(mBadGameOverMusic, 0); SetEntitiesGrayscale(true); } mRobot->Bounce(-400, true); // kill the robot Explosion* boom = new Explosion(entity->GetRect().x + entity->GetRect().w / 2, entity->GetRect().y + entity->GetRect().h / 2); mExplosions.push_back(boom); metIt = mMeteors.erase(metIt); // remove the entry from the list and advance iterator delete entity; // delete the object } else { entity->Update(dt); // update the entity ++metIt; // advance list iterator } } // // update the mushrooms // std::list<Layer*>::iterator mushIt = mMushrooms.begin(); while (mushIt != mMushrooms.end()) { Layer* entity = *mushIt; // If the robot collects the mushroom, it gets an extra life! if (entity->GetRect().y + entity->GetRect().h > mRobot->GetCollisonRect().y && entity->GetRect().y < mRobot->GetCollisonRect().y + mRobot->GetCollisonRect().h && entity->GetRect().x + entity->GetRect().w > mRobot->GetCollisonRect().x && entity->GetRect().x < mRobot->GetCollisonRect().x + mRobot->GetCollisonRect().w && !mRobot->IsDead()) { mRobot->SetLives(mRobot->GetLives() + 1); SetFlashesNeeded(2); Mix_PlayChannel(-1, mOneupSound, 0); mushIt = mMushrooms.erase(mushIt); // remove the entry from the list and advance iterator delete entity; // delete the object } else { ++mushIt; // advance list iterator } } // // generates a grayscale flash every 50 ms (if needed) // if (mFlashesNeeded > 0.0f) { if (mTime - mFlashTime > 0.1) { if ((int)mFlashesNeeded % 2) { SetEntitiesGrayscale(false); } else { SetEntitiesGrayscale(true); } mFlashesNeeded--; mFlashTime = mTime; } } // // create a new meteor every 0.2 to 1.2 seconds in scene 5 // if (mTime - mMeteorTime > GG::UnitRandom() + 0.2 && mScene == 5) { int randomX = GG::RandomInt(mScrWidth-64); int randomRotation = GG::RandomInt(90) + 180; randomRotation = (randomRotation % 2) ? randomRotation : -randomRotation; Meteor* meteor = new Meteor(randomX, -64, (double)randomRotation); mMeteors.push_back(meteor); // timestamp this meteor! mMeteorTime = mTime; } // Update the points label mTexMgr->DeleteTexture("PointsLabel"); std::stringstream newLabel; newLabel << "Points = " << mPoints; SDL_Color text_color = {0, 0, 0}; mTexMgr->LoadTexture("PointsLabel", newLabel.str().c_str(), text_color); delete mPointsLabel; mPointsLabel = new Label(10.0f, -5.0f, "PointsLabel"); // Update the lives label mTexMgr->DeleteTexture("LivesLabel"); newLabel.str(std::string()); newLabel << "Lives = " << mRobot->GetLives(); text_color.r = 255; text_color.g = 50; text_color.b = 50; mTexMgr->LoadTexture("LivesLabel", newLabel.str().c_str(), text_color); delete mLivesLabel; mLivesLabel = new Label(140.0f, -5.0f, "LivesLabel"); }