예제 #1
0
/*
================================================================================

Game::Draw

    Gets called once per frame to draw the current snapshot of the game.

================================================================================
*/
void Game::Draw()
{
    // clear the screen
    SDL_SetRenderDrawColor(mRenderer, 0, 0, 0, 255);
    SDL_RenderClear(mRenderer);
	
	if (mBackground)
	{
		Render(mBackground->GetRenderable(), &mBackground->GetRect(), SDL_FLIP_NONE);
	}
	if (mForeground)
	{
		//Render(mForeground->GetRenderable(), &mForeground->GetRect(), SDL_FLIP_NONE);
	}
	if (mFlagPole)
	{
		Render(mFlagPole->GetRenderable(), &mFlagPole->GetRect(), SDL_FLIP_NONE);
	}

    //
    // draw the grid
    //
    if (mGrid)
	{
        int tileWidth = mGrid->TileWidth();
        int tileHeight = mGrid->TileHeight();
        GG::Rect tileRect(0, 0, tileWidth, tileHeight);
        for (int y = 0; y < mGrid->NumRows(); y++)
		{
            for (int x = 0; x < mGrid->NumCols(); x++)
			{
                const GG::Renderable* renderable = mGrid->GetTile(y, x)->GetRenderable();
                if (renderable)
				{
                    Render(renderable, &tileRect, SDL_FLIP_NONE);
                }
                tileRect.x += tileWidth;
            }
            tileRect.y += tileHeight;
            tileRect.x = 0;
        }
    }

	// Draw the collision rectangles
	if (rectVisible)
	{
		SDL_SetRenderDrawColor(mRenderer, 255, 0, 0, 255);
		SDL_RenderFillRect(mRenderer, &mRobot->GetBottomTileRect());
		SDL_SetRenderDrawColor(mRenderer, 150, 0, 0, 255);
		SDL_RenderFillRect(mRenderer, &mRobot->GetTopTileRect());
		SDL_SetRenderDrawColor(mRenderer, 255, 255, 0, 255);
		SDL_RenderFillRect(mRenderer, &mRobot->GetCollisonRect());
		for (auto coinIt = mCoins.begin(); coinIt != mCoins.end(); ++coinIt)
		{
			Coin* coin = *coinIt;
			SDL_RenderFillRect(mRenderer, &coin->GetRect());
		}
		for (auto crawlerIt = mCrawlers.begin(); crawlerIt != mCrawlers.end(); ++crawlerIt)
		{
			Crawler* crawler = *crawlerIt;
			SDL_RenderFillRect(mRenderer, &crawler->GetCollisionRect());
		}
		for (auto meteorIt = mMeteors.begin(); meteorIt != mMeteors.end(); ++meteorIt)
		{
			Meteor* meteor = *meteorIt;
			SDL_RenderFillRect(mRenderer, &meteor->GetRect());
		}
		SDL_SetRenderDrawColor(mRenderer, 0, 0, 255, 255);
		for (auto crawlerIt = mCrawlers.begin(); crawlerIt != mCrawlers.end(); ++crawlerIt)
		{
			Crawler* crawler = *crawlerIt;
			SDL_RenderFillRect(mRenderer, &crawler->GetTileRect());
		}
	}

	//
    // draw the robot
    //
	if (mRobot)
	{
		Render(mRobot->GetRenderable(), &mRobot->GetRect(), mRobot->GetDirection()?SDL_FLIP_HORIZONTAL:SDL_FLIP_NONE);
	}

	//
    // draw the coins
    //
	std::list<Coin*>::iterator coinIt = mCoins.begin();
    for ( ; coinIt != mCoins.end(); ++coinIt)
	{
        Coin* coin = *coinIt;
        Render(coin->GetRenderable(), &coin->GetRect(), SDL_FLIP_NONE);
    }

	//
    // draw the mushrooms
    //
	std::list<Layer*>::iterator mushIter = mMushrooms.begin();
    for ( ; mushIter != mMushrooms.end(); ++mushIter)
	{
        Layer* mushroom = *mushIter;
        Render(mushroom->GetRenderable(), &mushroom->GetRect(), SDL_FLIP_NONE);
    }

	//
    // draw the crawlers
    //
    for (auto crawlerIt = mCrawlers.begin(); crawlerIt != mCrawlers.end(); ++crawlerIt)
	{
        Crawler* crawler = *crawlerIt;
		if (crawler->GetDirection() == 1)
		{
			Render(crawler->GetRenderable(), &crawler->GetRect(), SDL_FLIP_HORIZONTAL);
		}
		else
		{
			Render(crawler->GetRenderable(), &crawler->GetRect(), SDL_FLIP_NONE);
		}
    }

    //
    // draw the explosions
    //
    std::list<Explosion*>::iterator it = mExplosions.begin();
    for ( ; it != mExplosions.end(); ++it)
	{
        Explosion* boom = *it;
        Render(boom->GetRenderable(), &boom->GetRect(), SDL_FLIP_NONE);
    }

	//
    // draw the meteors
    //
    std::list<Meteor*>::iterator metIt = mMeteors.begin();
    for ( ; metIt != mMeteors.end(); ++metIt)
	{
        Meteor* meteor = *metIt;
        Render(meteor->GetRenderable(), &meteor->GetRect(), SDL_FLIP_NONE);
    }

	// Draw the points label
	if (mPointsLabel)
	{
		Render(mPointsLabel->GetRenderable(), &mPointsLabel->GetRect(), SDL_FLIP_NONE);
	}

	// Draw the lives label
	if (mLivesLabel)
	{
		Render(mLivesLabel->GetRenderable(), &mLivesLabel->GetRect(), SDL_FLIP_NONE);
	}

    // display everything we just drew
    SDL_RenderPresent(mRenderer);
}
예제 #2
0
/*
================================================================================

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");
}