Пример #1
0
void Tutorial::runLoop()
{
	sf::Clock clock;
	float elapsedTime;
	float fpsElapsedTime = 0;

	switchClock.restart();
	
	while (window->isOpen() && goToMenu == false){
		elapsedTime = clock.getElapsedTime().asSeconds();
		float fps = 1.f / elapsedTime;
		clock.restart();

		pollEvents();

		if (skipToMenuButton.getGlobalBounds().contains(mousePosition))	{	//hovered

			skipToMenuButton.setFillColor(sf::Color(220,0,220,255));		//magenta
			if (leftMouseClicked)
			{
				leftMouseClicked = false;
				goToMenu = true;
				break;
			}
		} else {
			skipToMenuButton.setFillColor(sf::Color::Black);
		}

		switch (loopState)
		{
		case CROSSFADE:
		{
			leftMouseClicked = false;
			rightMouseClicked = false; // check if/why needed

			if (firstFadingFrame){
				firstFadingFrame = false;
				alpha1 = 255;
				alpha2 = 0;
			}
			if (crossfade(elapsedTime, background[fadeIndexA], background[fadeIndexB])){
				loopState = WAIT;
				bool goForward = fadeIndexB < fadeIndexA;
				if (goForward){
					uint8_t temp = fadeIndexA;		// swap indices
					fadeIndexA = fadeIndexB;
					fadeIndexB = temp;
				}
				else{
					++fadeIndexA;
					++fadeIndexB;
				}
			}
		} break;

		case WAIT:
		{
			if (rightMouseClicked)
			{
				rightMouseClicked = false;			// consume events
				leftMouseClicked = false;			// just to be safe
				switchClock.restart();

				if (fadeIndexB > 1){				// at second screen or higher
					firstFadingFrame = true;
					loopState = CROSSFADE;
					fadeIndexB -= 2;				// jump to one before fadeIndexA
				}
			}
			else if (switchClock.getElapsedTime().asSeconds() > TIME_TO_WAIT_TILL_NEXT_SWITCH || leftMouseClicked) {
				if (fadeIndexB == 10)								// 10 = backgroundarray size
				{
					goToMenu = true;
					break;
				}
				leftMouseClicked = false;							// consume events
				//rightMouseClicked = false;		// not needed because of the else if // just to be safe
				loopState = CROSSFADE;
				firstFadingFrame = true;
				switchClock.restart();
			}
		} break;

		default: { assert(false);					} break;
		}

		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		//draw
		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		window->clear(sf::Color::White);
		
		window->draw(background[fadeIndexA]);
		window->draw(background[fadeIndexB]);
		if (fadeIndexA != 0 || loopState == CROSSFADE){
			window->draw(skipToMenuButton);
		} 

		window->display();

		fpsElapsedTime += elapsedTime;
		if (fpsElapsedTime > 0.75)
		{
			std::ostringstream ss;
			ss.precision(4);
			ss << WINDOW_TITLE << fps << "fps";
			window->setTitle(ss.str());
			fpsElapsedTime = 0;
		}
	}

	
}
int Narrator::script(int st, PRNG &prng)
{
    static ChaosParticles chaosA(flow, runner.config["chaosParticles"]);
    static ChaosParticles chaosB(flow, runner.config["chaosParticles"]);
    static OrderParticles orderParticles(flow, runner.config["orderParticles"]);
    static Precursor precursor(flow, runner.config["precursor"]);
    static RingsEffect ringsA(flow, runner.config["ringsA"]);
    static RingsEffect ringsB(flow, runner.config["ringsB"]);
    static RingsEffect ringsC(flow, runner.config["ringsC"]);
    static PartnerDance partnerDance(flow, runner.config["partnerDance"]);
    static CameraFlowDebugEffect flowDebugEffect(flow, runner.config["flowDebugEffect"]);
    static Forest forest(flow, runner.config["forest"]);
    static DarknessEffect darkness;

    rapidjson::Value& config = runner.config["narrator"];
    Sampler s(prng.uniform32());

    switch (st) {

        //////////////////////////////////////////////////////////////////////////////////////////////
        // Special states

        case 1: {
            // Darkness only ("off")
            crossfade(&darkness, 1);
            delayForever();
        }

        case 2: {
            // Precursor only (sleep mode)            
            precursor.reseed(prng.uniform32());
            crossfade(&precursor, 1);
            delayForever();
        }

        case 3: {
            // Debugging the computer vision system
            crossfade(&flowDebugEffect, 1);
            delayForever();
        }

        //////////////////////////////////////////////////////////////////////////////////////////////
        // Opening sequence

        case 0: {
            // Darkness until opening

            crossfade(&darkness, 1);
            delayUntilDate(config["opening"]["date"]);
            return config["opening"]["nextState"].GetInt();
        }

        //////////////////////////////////////////////////////////////////////////////////////////////
        // Cyclic states

        default: {
            endCycle();
            return 10;
        }

        case 10: {
            // Order trying to form out of the tiniest sparks; runs for an unpredictable time, fails.
            precursor.reseed(prng.uniform32());
            crossfade(&precursor, s.value(config["precursorCrossfade"]));

            // Bootstrap
            delay(s.value(config["precursorBootstrap"]));

            // Wait for darkness
            while (!precursor.isDone) {
                doFrame();
            }
            return 20;
        }

        case 20: {
            // Bang. Explosive energy, hints of self-organization

            ChaosParticles *pChaosA = &chaosA;
            ChaosParticles *pChaosB = &chaosB;
            
            int bangCount = s.value(config["bangCount"]);
            for (int i = 0; i < bangCount; i++) {
                pChaosA->reseed(prng.circularVector() * s.value(config["bangSeedRadius"]), prng.uniform32());
                crossfade(pChaosA, s.value(config["bangCrossfadeDuration"]));
                delay((1 << i) * s.value(config["bangDelayBasis"]));
                std::swap(pChaosA, pChaosB);
            }

            attention(s, config["bangAttention"]);

            return 30;
        }

        case 30: {
            // Textures of light, exploring something formless. Slow crossfade in
            ringsA.reseed(prng.uniform32());
            crossfade(&ringsA, s.value(config["ringsA-Crossfade"]));
            attention(s, config["ringsA-Attention"]);
            return 40;
        }

        case 40: {
            // Add energy, explore another layer.
            ringsB.reseed(prng.uniform32());
            crossfade(&ringsB, s.value(config["ringsB-Crossfade"]));
            attention(s, config["ringsB-Attention"]);
            return 50;
        }

        case 50: {
            // Biology happens, order emerges. Cellular look, emergent order.

            orderParticles.reseed(prng.uniform32());
            orderParticles.symmetry = 10;
            crossfade(&orderParticles, s.value(config["orderCrossfade"]));
            while (orderParticles.symmetry > 4) {
                attention(s, config["orderStepAttention"]);
                orderParticles.symmetry--;
            }
            attention(s, config["orderStepAttention"]);
            return 60;
        }

        case 60: {
            // Two partners, populations of particles.
            // Spiralling inwards. Depression. Beauty on the edge of destruction,
            // pressing forward until nothing remains.

            partnerDance.reseed(prng.uniform32());
            crossfade(&partnerDance, s.value(config["partnerCrossfade"]));
            attention(s, config["partnerAttention"]);
            return 70;
        }

        case 70: {
            // Sinking deeper. Interlude before a change.

            ringsC.reseed(prng.uniform32());
            crossfade(&ringsC, s.value(config["ringsC-Crossfade"]));
            attention(s, config["ringsC-Attention"]);
            return 80;
        }

        case 80: {
            // Continuous renewal and regrowth. Destruction happens unintentionally,
            // regrowth is quick and generative. The only way to lose is to stagnate.

            forest.reseed(prng.uniform32());
            crossfade(&forest, s.value(config["forestCrossfade"]));
            attention(s, config["forestAttention"]);
            return 90;
        }
    }
}