예제 #1
0
//----------------------------------------------------------------------------
Smoke2D::Smoke2D (Renderer* renderer, float x0, float y0, float x1, float y1,
    float dt, float denViscosity, float velViscosity, int imax, int jmax,
    int numGaussSeidelIterations, int numVortices)
    :
    mX0(x0),
    mY0(y0),
    mX1(x1),
    mY1(y1),
    mDt(dt),
    mDenViscosity(denViscosity),
    mVelViscosity(velViscosity),
    mIMax(imax),
    mJMax(jmax),
    mNumGaussSeidelIterations(numGaussSeidelIterations),
    mNumVortices(numVortices),
    mNumActive(0),
    mGravity(Vector2f::ZERO),
    mRenderer(renderer),
    mIP(0),
    mUseVortexOverlay(false)
{
    mIMaxM1 = mIMax - 1;
    mJMaxM1 = mJMax - 1;
    mIMaxP1 = mIMax + 1;
    mJMaxP1 = mJMax + 1;
    mNumPixels = mIMaxP1*mJMaxP1;
    mDx = (mX1 - mX0)/(float)mIMax;
    mDy = (mY1 - mY0)/(float)mJMax;
    mDxDx = mDx*mDx;
    mDyDy = mDy*mDy;
    mHalfDivDx = 0.5f/mDx;
    mHalfDivDy = 0.5f/mDy;
    mDtDivDx = mDt/mDx;
    mDtDivDy = mDt/mDy;
    mDtDivDxDx = mDt/mDxDx;
    mDtDivDyDy = mDt/mDyDy;
    mEpsilon0 = 0.5f*mDxDx*mDyDy/(mDxDx + mDyDy);
    mEpsilonX = mEpsilon0/mDxDx;
    mEpsilonY = mEpsilon0/mDyDy;
    mDenLambdaX = mDenViscosity*mDtDivDxDx;
    mDenLambdaY = mDenViscosity*mDtDivDyDy;
    mVelLambdaX = mVelViscosity*mDtDivDxDx;
    mVelLambdaY = mVelViscosity*mDtDivDyDy;
    mDenGamma0 = 1.0f/(1.0f + 2.0f*(mDenLambdaX + mDenLambdaY));
    mDenGammaX = mDenLambdaX*mDenGamma0;
    mDenGammaY = mDenLambdaY*mDenGamma0;
    mVelGamma0 = 1.0f/(1.0f + 2.0f*(mVelLambdaX + mVelLambdaY));
    mVelGammaX = mVelLambdaX*mVelGamma0;
    mVelGammaY = mVelLambdaY*mVelGamma0;
    mTime = 0.0f;

    mVortexCenter = new1<Vector2f>(mNumVortices);
    mVortexVariance = new1<float>(mNumVortices);
    mVortexAmplitude = new1<float>(mNumVortices);
    mTimelessDensity = new2<float>(mIMaxP1, mJMaxP1);
    mTimelessVortex = new3<Vector2f>(mNumVortices, mIMaxP1, mJMaxP1);
    mTimelessWind = new2<Vector2f>(mIMaxP1, mJMaxP1);
    mTimelessVelocity = new2<Vector2f>(mIMaxP1, mJMaxP1);

    int v;
    for (v = 0; v < mNumVortices; ++v)
    {
        mVortexCenter[v][0] = Mathf::UnitRandom();
        mVortexCenter[v][1] = Mathf::UnitRandom();
        mVortexVariance[v] = Mathf::IntervalRandom(0.001f, 0.01f);
        mVortexAmplitude[v] = Mathf::IntervalRandom(128.0f, 256.0f);
        if (Mathf::SymmetricRandom() < 0.0f)
        {
            mVortexAmplitude[v] *= -1.0f;
        }
    }

    for (int j = 0; j <= mJMax; ++j)
    {
        float y = mY0 + mDy*(float)j;

        for (int i = 0; i <= mIMax; ++i)
        {
            float x = mX0 + mDx*(float)i;

            // density source
            float dx = x - 0.25f;
            float dy = y - 0.75f;
            float arg = -(dx*dx + dy*dy)/0.01f;
            mTimelessDensity[j][i] = 2.0f*Mathf::Exp(arg);

            // density sink
            dx = x - 0.75f;
            dy = y - 0.25f;
            arg = -(dx*dx + dy*dy)/0.01f;
            mTimelessDensity[j][i] -= 2.0f*Mathf::Exp(arg);

            // velocity vortex source
            for (v = 0; v < mNumVortices; ++v)
            {
                dx = x - mVortexCenter[v][0];
                dy = y - mVortexCenter[v][1];
                arg = -(dx*dx + dy*dy)/mVortexVariance[v];
                Vector2f vortex(dy, -dx);
                vortex *= mVortexAmplitude[v]*Mathf::Exp(arg);
                mTimelessVortex[j][i][v] = vortex;
            }

            // velocity wind source
            float diff = y - 0.5f;
            float ampl = 32.0f*Mathf::Exp(-diff*diff/0.001f);
            Vector2f wind(ampl, 0.0f);
            mTimelessWind[j][i] = wind;
            mTimelessVelocity[j][i] = wind;
        }
    }
}
예제 #2
0
Smoke2D<Real>::Smoke2D (Real x0, Real y0, Real x1, Real y1, Real dt,
    Real denViscosity, Real velViscosity, int imax, int jmax,
    int numGaussSeidelIterations, bool densityDirichlet, int numVortices)
    :
    FLUIDBASE(x0, y0, x1, y1, dt, denViscosity, velViscosity, imax, jmax,
        numGaussSeidelIterations, densityDirichlet),
    mNumVortices(numVortices),
    mNumActive(0),
    mGravity((Real)0)
{
    mVortexCenter = new1<Vector2<Real> >(mNumVortices);
    mVortexVariance = new1<Real>(mNumVortices);
    mVortexAmplitude = new1<Real>(mNumVortices);
    mTimelessDensity = new2<Real>(mIMaxP1, mJMaxP1);
    mTimelessVortex = new3<Vector2<Real> >(mNumVortices, mIMaxP1, mJMaxP1);
    mTimelessWind = new2<Vector2<Real> >(mIMaxP1, mJMaxP1);

    int v;
    for (v = 0; v < mNumVortices; ++v)
    {
        mVortexCenter[v][0] = Math<Real>::UnitRandom();
        mVortexCenter[v][1] = Math<Real>::UnitRandom();
        mVortexVariance[v] = Math<Real>::IntervalRandom((Real)0.001,
            (Real)0.01);
        mVortexAmplitude[v] = Math<Real>::IntervalRandom((Real)128,
            (Real)256);
        if (Math<Real>::SymmetricRandom() < (Real)0)
        {
            mVortexAmplitude[v] *= (Real)-1;
        }
    }

    for (int j = 0; j <= mJMax; ++j)
    {
        Real y = mY[j];

        for (int i = 0; i <= mIMax; ++i)
        {
            Real x = mX[i];

            // density source
            Real dx = x - (Real)0.25;
            Real dy = y - (Real)0.75;
            Real arg = -(dx*dx + dy*dy)/(Real)0.01;
            mTimelessDensity[j][i] = ((Real)2)*Math<Real>::Exp(arg);

            // density sink
            dx = x - (Real)0.75;
            dy = y - (Real)0.25;
            arg = -(dx*dx + dy*dy)/(Real)0.01;
            mTimelessDensity[j][i] -= ((Real)2)*Math<Real>::Exp(arg);

            // velocity vortex source
            for (v = 0; v < mNumVortices; ++v)
            {
                dx = x - mVortexCenter[v][0];
                dy = y - mVortexCenter[v][1];
                arg = -(dx*dx + dy*dy)/mVortexVariance[v];
                Vector2<Real> vortex(dy, -dx);
                vortex *= mVortexAmplitude[v]*Math<Real>::Exp(arg);
                mTimelessVortex[j][i][v] = vortex;
            }

            // velocity wind source
            Real diff = y - (Real)0.5;
            Real ampl = ((Real)32)*Math<Real>::Exp(-diff*diff/(Real)0.001);
            Vector2<Real> wind(ampl, (Real)0);
            mTimelessWind[j][i] = wind;
        }
    }
}
예제 #3
0
파일: level.cpp 프로젝트: AlexStopar/Bound
void playLevel(SDL_Renderer* renderer, SDL_Window* window)
{
	TextureStorage::getInstance().setDifficultyBackground(renderer);
	bool isScoreRecording = false;
	bool isHighScore = false;
	bool isPaused = false;
	std::random_device rd;
	std::mt19937 eng(rd());
	std::uniform_int_distribution<> randomX(2 * WALL_WIDTH, SCREEN_WIDTH - (2 * WALL_WIDTH));
	std::uniform_int_distribution<> randomY(2 * WALL_WIDTH, SCREEN_HEIGHT - (2 * WALL_WIDTH));
	std::uniform_int_distribution<> randomVortex(0, VORTEX_LIMIT);
	std::string inputText = "";

	SDL_Event e;

	Player player(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, PLAYER_WIDTH, PLAYER_HEIGHT, PLAYER_VEL);
	Collectible collectible(randomX(eng), randomY(eng), resolveCoinWidth(), COIN_HEIGHT, 0);
	Skull skull(0, 0, SKULL_WIDTH, SKULL_HEIGHT, 0);

	std::vector<SDL_Rect> walls = getBoundaries();
	SoundPlayer::getInstance().playMusic();

	while (!isQuitting)
	{
		if (player.isDead)
		{
			SoundPlayer::getInstance().stopMusic();
			if (!isScoreRecording)
			{
				isScoreRecording = HighScore::getInstance().checkAndAddNewScore(score, gameDifficulty);
				if (isScoreRecording)
				{
					isHighScore = true;
					SoundPlayer::getInstance().playHighScore();
				}
			}			
		}
		while (SDL_PollEvent(&e) != 0)
		{
			if (!isPaused) SDL_EventState(SDL_KEYUP, SDL_ENABLE);
			if (e.type == SDL_QUIT)
			{
				isQuitting = true;
				isResetting = false;
				reset();
			}		
			else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_ESCAPE) toggleFullscreen(window);
			else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_RETURN && !player.isDead)
			{
				SoundPlayer::getInstance().pauseMusic();
				SoundPlayer::getInstance().playPause();
				if (isPaused) isPaused = false;
				else
				{
					isPaused = true;
					SDL_EventState(SDL_KEYUP, SDL_IGNORE);
				}
					
			}
			if (isPaused) SDL_EventState(SDL_KEYDOWN, SDL_IGNORE);
			if (!player.isDead)
			{
				if (!isPaused) player.handleEvent(e);
			}
			else 
			{
				if (e.type == SDL_TEXTINPUT)
				{
					if (inputText.size() < 3 && e.text.text[0] != ',') inputText += e.text.text;
				}
				else if (e.type == SDL_KEYDOWN)
				{
					if (e.key.keysym.sym == SDLK_n && !isHighScore)
					{
						isResetting = false;
						reset();
						return;
					}
					else if (e.key.keysym.sym == SDLK_y && !isHighScore)
					{
						isResetting = true;
						reset();
						return;
					}	
					else if (e.key.keysym.sym == SDLK_BACKSPACE)
					{
						if (inputText.size() != 0) inputText.pop_back();
					}
					else if (e.key.keysym.sym == SDLK_RETURN)
					{
						if (isHighScore) HighScore::getInstance().addInitials(inputText);
						isHighScore = false;
					}
				}
			}
			SDL_EventState(SDL_KEYDOWN, SDL_ENABLE);
		}
		if (!isPaused)
		{
			if (!player.isDead) player.move(walls, enemies, skull);
			else skull.move(walls);
			for (std::vector<Enemy>::iterator it = enemies.begin(); it != enemies.end(); ++it) {
				it->move(walls);
			}

			if (!collectible.isHit)
			{
				prevX = collectible.getX();
				prevY = collectible.getY();
			}

			collectible.move(player, randomX(eng), randomY(eng));
		}

		SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
		SDL_RenderClear(renderer);

		TextureStorage::getInstance().bgTexture.render(0, 0, renderer);
		renderWalls(renderer, walls);
		
		for (std::vector<Enemy>::iterator it = enemies.begin(); it != enemies.end(); ++it) {
			it->render(renderer);
		}
		collectible.render(renderer);

		if (!player.isDead) player.render(renderer);
		else skull.render(renderer);

		TextDraw::getInstance().renderHUD(renderer);
		if (collectible.isHit)
		{
			time++;
			TextDraw::getInstance().renderScoreGain(prevX, prevY, renderer);
			prevX++;
			prevY--;
			if (time == 20)
			{
				time = 0;
				Enemy enemy(randomX(eng), randomY(eng), ENEMY_WIDTH, ENEMY_HEIGHT, ENEMY_VEL * (int)gameDifficulty, EnemyType::SPIKEBALL);
				if (randomVortex(eng) > VORTEX_LIMIT / (int)gameDifficulty)
				{
					Enemy vortex(randomX(eng), randomY(eng), ENEMY_WIDTH, ENEMY_HEIGHT, 0, EnemyType::VORTEX);
					while (checkCollision(vortex.getHitbox(), player.getHitbox()))
					{
						vortex.setX(randomX(eng));
						vortex.setY(randomY(eng));
						vortex.setHitbox();
					}
					enemies.push_back(vortex);
				}
				while (checkCollision(enemy.getHitbox(), player.getHitbox()))
				{
					enemy.setX(randomX(eng));
					enemy.setY(randomY(eng));
					enemy.setHitbox();
				}
				enemies.push_back(enemy);
				collectible.isHit = false;
			}
		}
		if (player.isDead) TextDraw::getInstance().renderGameOver(renderer, isHighScore, inputText);
		if (isPaused)TextDraw::getInstance().renderPause(renderer);
		SDL_RenderPresent(renderer);
		frameCount++;
		if (frameCount == DISPLAY_LIMIT) frameCount = 0;
	}
}