QuadSequenceParticleSystemDrawerBase::QuadSequenceParticleSystemDrawerBase(void) :
    Inherited(),
    _sfSequenceDimensions     (Vec2b(2,1)),
    _sfBorderOffsets          (Vec2b(0,0)),
    _sfSequenceFunction       (NULL),
    _sfImageDimensions        (Vec2us(250,250))
{
}
int main(int argc, char **argv)
{
    preloadSharedObject("OSGImageFileIO");
    // OSG init
    osgInit(argc,argv);

    {
        // Set up Window
        WindowEventProducerRecPtr TutorialWindow = createNativeWindow();
        TutorialWindow->initWindow();

        // Create the SimpleSceneManager helper
        SimpleSceneManager sceneManager;
        TutorialWindow->setDisplayCallback(boost::bind(display, &sceneManager));
        TutorialWindow->setReshapeCallback(boost::bind(reshape, _1, &sceneManager));

        // Tell the Manager what to manage
        sceneManager.setWindow(TutorialWindow);

        //Attach to events
        TutorialWindow->connectMousePressed(boost::bind(mousePressed, _1, &sceneManager));
        TutorialWindow->connectMouseReleased(boost::bind(mouseReleased, _1, &sceneManager));
        TutorialWindow->connectMouseMoved(boost::bind(mouseMoved, _1, &sceneManager));
        TutorialWindow->connectMouseDragged(boost::bind(mouseDragged, _1, &sceneManager));
        TutorialWindow->connectMouseWheelMoved(boost::bind(mouseWheelMoved, _1, &sceneManager));

        // Creating the Particle System Material
        // Here, the image is loaded.  The entire image sequence is conatined in one image,
        // which reduces texture memory overhead and runs faster.
        TextureObjChunkRefPtr QuadTextureChunk = TextureObjChunk::create();
        ImageRefPtr LoadedImage = ImageFileHandler::the()->read("Data/SpriteExplode.png");    
        QuadTextureChunk->setImage(LoadedImage);

        TextureEnvChunkRefPtr QuadTextureEnvChunk = TextureEnvChunk::create();
        QuadTextureEnvChunk->setEnvMode(GL_MODULATE);

        BlendChunkRefPtr PSBlendChunk = BlendChunk::create();
        PSBlendChunk->setSrcFactor(GL_SRC_ALPHA);
        PSBlendChunk->setDestFactor(GL_ONE_MINUS_SRC_ALPHA);

        MaterialChunkRefPtr PSMaterialChunk = MaterialChunk::create();
        PSMaterialChunk->setAmbient(Color4f(0.3f,0.0f,0.0f,1.0f));
        PSMaterialChunk->setDiffuse(Color4f(0.7f,0.0f,0.0f,1.0f));
        PSMaterialChunk->setSpecular(Color4f(0.9f,0.0f,0.0f,1.0f));
        PSMaterialChunk->setColorMaterial(GL_AMBIENT_AND_DIFFUSE);

        ChunkMaterialRefPtr PSMaterial = ChunkMaterial::create();
        PSMaterial->addChunk(QuadTextureChunk);
        PSMaterial->addChunk(QuadTextureEnvChunk);
        PSMaterial->addChunk(PSMaterialChunk);
        PSMaterial->addChunk(PSBlendChunk);

        //Particle System
        ParticleSystemRecPtr ExampleParticleSystem = ParticleSystem::create();
        ExampleParticleSystem->attachUpdateProducer(TutorialWindow);

        //Age Particle Function.  Controls which image is shown when, based on the age of a particle.
        AgeParticleFunctionRecPtr AgeFunc = AgeParticleFunction::create();
        AgeFunc->setSequenceTime(0.1f); // image changes every 0.1 seconds.
        AgeFunc->setSequenceOrder(AgeParticleFunction::CUSTOM); // using the custom sequence below.
        /*
           Here, a custom sequence for the image ordering is assembled.  The image sequence will be shown in 
           the order specified here.  Once the end of the sequence is reached, the sequence repeats.
           */
        AgeFunc->editMFCustomSequence()->push_back(0);
        AgeFunc->editMFCustomSequence()->push_back(1);
        AgeFunc->editMFCustomSequence()->push_back(2);
        AgeFunc->editMFCustomSequence()->push_back(3);
        AgeFunc->editMFCustomSequence()->push_back(4);
        AgeFunc->editMFCustomSequence()->push_back(5);
        AgeFunc->editMFCustomSequence()->push_back(4);
        AgeFunc->editMFCustomSequence()->push_back(3);
        AgeFunc->editMFCustomSequence()->push_back(2);
        AgeFunc->editMFCustomSequence()->push_back(1);

        //Particle System Drawer - 
        QuadSequenceParticleSystemDrawerRecPtr ExampleParticleSystemDrawer = QuadSequenceParticleSystemDrawer::create();
        // image dimensions (in pixels) are required if there is a border on the images.
        ExampleParticleSystemDrawer->setImageDimensions(Vec2us(780,520));
        // The "dimensions" of the sequence contained in the image.  For this image,
        // there are 3 images in the "x" direction, and two in the "y" direction, for a 
        // total of 6.
        ExampleParticleSystemDrawer->setSequenceDimensions(Vec2b(3,2));
        // width of the border on each side of the image, in pixels.
        ExampleParticleSystemDrawer->setBorderOffsets(Vec2b(0,0));
        // this is the age function we just created above.
        ExampleParticleSystemDrawer->setSequenceFunction(AgeFunc);

        RateParticleGeneratorRecPtr ExampleParticleGenerator = RateParticleGenerator::create();
        //Attach the function objects to the Generator
        ExampleParticleGenerator->setPositionDistribution(createPositionDistribution());
        ExampleParticleGenerator->setLifespanDistribution(createLifespanDistribution());
        ExampleParticleGenerator->setVelocityDistribution(createVelocityDistribution());
        ExampleParticleGenerator->setAccelerationDistribution(createAccelerationDistribution());
        ExampleParticleGenerator->setSizeDistribution(createSizeDistribution());
        ExampleParticleGenerator->setGenerationRate(40.0f);

        //Particle System Node
        ParticleSystemCoreRefPtr ParticleNodeCore = ParticleSystemCore::create();
        ParticleNodeCore->setSystem(ExampleParticleSystem);
        ParticleNodeCore->setDrawer(ExampleParticleSystemDrawer);
        ParticleNodeCore->setMaterial(PSMaterial);
        ParticleNodeCore->setSortingMode(ParticleSystemCore::BACK_TO_FRONT);

        NodeRefPtr ParticleNode = Node::create();
        ParticleNode->setCore(ParticleNodeCore);

        ExampleParticleSystem->addParticle(Pnt3f(10.0,0.0,0.0),
                                           Vec3f(0.0,1.0,0.0),
                                           Color4f(1.0,1.0,1.0,1.0),
                                           Vec3f(1.0,1.0,1.0),
                                           0.01,
                                           Vec3f(0.0,0.0,0.0),
                                           Vec3f(0.0,0.0,0.0));

        ExampleParticleSystem->addParticle(Pnt3f(-10.0,0.0,0.0),
                                           Vec3f(0.0,1.0,0.0),
                                           Color4f(1.0,1.0,1.0,1.0),
                                           Vec3f(1.0,1.0,1.0),
                                           0.01,
                                           Vec3f(0.0,0.0,0.0),
                                           Vec3f(0.0,0.0,0.0));

        ExampleParticleSystem->pushToGenerators(ExampleParticleGenerator);
        // Make Main Scene Node and add the Torus
        NodeRefPtr scene = makeCoredNode<Group>();
        scene->addChild(ParticleNode);

        TutorialWindow->connectKeyTyped(boost::bind(keyTyped, _1,
                                                    &sceneManager,
                                                    AgeFunc.get()));

        sceneManager.setRoot(scene);

        // Show the whole Scene
        sceneManager.showAll();

        //Open Window
        Vec2f WinSize(TutorialWindow->getDesktopSize() * 0.85f);
        Pnt2f WinPos((TutorialWindow->getDesktopSize() - WinSize) *0.5);
        TutorialWindow->openWindow(WinPos,
                                   WinSize,
                                   "05a - QuadSequenceParticleDrawer");

        //Enter main Loop
        TutorialWindow->mainLoop();
    }

    osgExit();

    return 0;
}
예제 #3
0
void Fire::onUpdate()
{
	// Feuer
	ParticleSystem* p_particleSystem = level.getParticleSystem();
	ParticleSystem* p_fireParticleSystem = level.getFireParticleSystem();
	ParticleSystem::Particle p;
	p.lifetime = random(60, 100);
	p.damping = 0.9f;
	p.gravity = -0.04f;
	p.positionOnTexture = Vec2b(32, 0);
	p.sizeOnTexture = Vec2b(16, 16);
	p.position = position * 16 + Vec2i(random(6, 10), random(6, 10));
	p.velocity = Vec2d(random(-0.5, 0.5), random(-0.5, 0.5));
	p.color = Vec4d(random(0.5, 1.0), random(0.8, 1.0), random(0.0, 0.25), random(0.2, 0.4));
	const double dc = -1.5 / (p.lifetime + random(-25, 25));
	p.deltaColor = Vec4d(dc, dc, dc, -p.color.a / p.lifetime);
	p.rotation = random(0.0f, 10.0f);
	p.deltaRotation = random(-0.1f, 0.1f);
	p.size = random(0.5f, 0.9f);
	p.deltaSize = random(-0.015f, -0.0075f);
	if(random() % 2) p_particleSystem->addParticle(p);
	else p_fireParticleSystem->addParticle(p);

	// Befindet sich ein Objekt auf dem Feuer?
	const std::vector<Object*> objectsOnMe = level.getObjectsAt(position);
	for(std::vector<Object*>::const_iterator i = objectsOnMe.begin(); i != objectsOnMe.end(); ++i)
	{
		Object* p_obj = *i;
		if(p_obj == this) continue;

		p_obj->onFire();

		if(p_obj->getFlags() & OF_DESTROYABLE)
		{
			p_obj->setDestroyTime(p_obj->getDestroyTime() - 1);
			if(!p_obj->getDestroyTime())
			{
				p_obj->disappear(0.2);
				debrisColor = p_obj->getDebrisColor();

				Engine::inst().playSound("vaporize.ogg", false, 0.15);

				// Trümmer
				int n = random(50, 80);
				for(int i = 0; i < n; i++)
				{
					p.lifetime = random(60, 120);
					p.damping = 0.9f;
					p.gravity = -0.1f;
					p.positionOnTexture = Vec2b(96, 0);
					p.sizeOnTexture = Vec2b(16, 16);
					p.position = p_obj->getPosition() * 16 + Vec2i(random(-2, 18), random(-2, 18));
					p.velocity = Vec2d(random(-0.2, 0.2), random(-0.2, 0.2));
					p.color = debrisColor + Vec4d(random(-0.1, 0.1), random(-0.1, 0.1), random(-0.1, 0.1), 0.0);
					p.deltaColor = Vec4d(0.0, 0.0, 0.0, -p.color.a / p.lifetime);
					p.rotation = random(0.0f, 10.0f);
					p.deltaRotation = random(-0.1f, 0.1f);
					p.size = random(0.5f, 1.5f);
					p.deltaSize = random(0.01f, 0.05f);
					if(random() % 2) p_particleSystem->addParticle(p);
					else p_fireParticleSystem->addParticle(p);
				}

				if(p_obj->getFlags() & OF_KILL_FIRE)
				{
					// Das Feuer geht jetzt aus!
					for(int i = 0; i < 50; i++)
					{
						p.lifetime = random(80, 150);
						p.damping = 0.9f;
						p.gravity = -0.03f;
						p.positionOnTexture = Vec2b(0, 0);
						p.sizeOnTexture = Vec2b(16, 16);
						p.position = position * 16 + Vec2i(random(6, 10), random(6, 10));
						const double r = random(0.0, 6.283);
						p.velocity = Vec2d(random(-0.5, 0.5), random(-0.5, 0.5));
						p.color = debrisColor + Vec4d(random(-0.1, 0.1), random(-0.1, 0.1), random(-0.1, 0.1), 0.0);
						const double dc = -0.5 / (p.lifetime + random(-25, 25));
						p.deltaColor = Vec4d(dc, dc, dc, -p.color.a / p.lifetime);
						p.rotation = random(0.0f, 10.0f);
						p.deltaRotation = random(-0.1f, 0.1f);
						p.size = random(0.6f, 0.9f);
						p.deltaSize = random(0.01f, 0.02f);
						if(random() % 2) p_particleSystem->addParticle(p);
						else p_fireParticleSystem->addParticle(p);
					}

					disappear(0.2);
				}
			}
		}
	}

	anim++;
}
예제 #4
0
void ToxicGas::onUpdate()
{
	if(!(random() % 3))
	{
		ParticleSystem* p_particleSystem = level.getParticleSystem();
		ParticleSystem* p_fireParticleSystem = level.getFireParticleSystem();
		ParticleSystem::Particle p;

		p.lifetime = random(10, 20);
		p.damping = 0.96f;
		p.gravity = -0.005f;
		if(random() % 2) p.positionOnTexture = Vec2b(0, 64);
		else p.positionOnTexture = Vec2b(0, 0);
		p.sizeOnTexture = Vec2b(16, 16);
		p.position = position * 16 + Vec2i(random(2, 14), random(2, 14));
		const double r = random(0.0, 6.283);
		p.velocity = random(0.0, 1.0) * Vec2d(sin(r), cos(r));
		p.color = Vec4d(random(0.4, 1.0), random(0.75, 1.0), random(0.0, 0.5), random(0.5, 1.5));
		p.deltaColor = Vec4d(0.0, 0.0, 0.0, -p.color.a / p.lifetime);
		p.rotation = random(0.0f, 10.0f);
		p.deltaRotation = random(-0.05f, 0.05f);
		p.size = 0.01f;
		p.deltaSize = random(0.05f, 0.25f);
		if(random() % 2) p_particleSystem->addParticle(p);
		else p_fireParticleSystem->addParticle(p);
	}

	std::vector<Object*> objects = level.getObjectsAt(position);
	for(std::vector<Object*>::const_iterator i = objects.begin(); i != objects.end(); ++i)
	{
		if((*i)->getFlags() & OF_BLOCK_GAS)
		{
			disappear(0.0);
			return;
		}
	}

	if(spreadCounter > 0) spreadCounter--;
	else if(spreadCounter == 0)
	{
		// in alle freien Richtungen ausbreiten
		for(int dir = 0; dir < 4; dir++)
		{
			Vec2i p = position + intToDir(dir);
			if(!level.isValidPosition(p)) continue;

			// wenn da schon Gas ist, abbrechen
			if(level.getAIFlags(p) & 2) continue;

			// Tiles blockieren das Gas.
			uint tileID = level.getTileAt(1, p);
			const TileSet::TileInfo& tileInfo = level.getTileSet()->getTileInfo(tileID);
			if(tileInfo.type == 1 || tileInfo.type == 2) continue;

			// Objekte?
			objects = level.getObjectsAt(p);
			bool blocked = false;
			for(std::vector<Object*>::const_iterator i = objects.begin(); i != objects.end(); ++i)
			{
				if((*i)->getFlags() & OF_BLOCK_GAS)
				{
					blocked = true;
					break;
				}
			}

			if(blocked) continue;

			// neues Gasobjekt erzeugen
			new ToxicGas(level, p);
		}

		spreadCounter = random(50, 80);
	}
}
예제 #5
0
int main(int argc, char **argv)
{
    preloadSharedObject("OSGImageFileIO");
    // OSG init
    osgInit(argc,argv);

    {
        // Set up Window
        WindowEventProducerRecPtr TutorialWindow = createNativeWindow();
        TutorialWindow->initWindow();

        // Create the SimpleSceneManager helper
        SimpleSceneManager sceneManager;
        TutorialWindow->setDisplayCallback(boost::bind(display, &sceneManager));
        TutorialWindow->setReshapeCallback(boost::bind(reshape, _1, &sceneManager));

        // Tell the Manager what to manage
        sceneManager.setWindow(TutorialWindow);

        //Attach to events
        TutorialWindow->connectMousePressed(boost::bind(mousePressed, _1, &sceneManager));
        TutorialWindow->connectMouseReleased(boost::bind(mouseReleased, _1, &sceneManager));
        TutorialWindow->connectMouseMoved(boost::bind(mouseMoved, _1, &sceneManager));
        TutorialWindow->connectMouseDragged(boost::bind(mouseDragged, _1, &sceneManager));
        TutorialWindow->connectMouseWheelMoved(boost::bind(mouseWheelMoved, _1, &sceneManager));

        // Creating the Particle System Material
        // Here, the image is loaded.  The entire image sequence is conatined in one image,
        // which reduces texture memory overhead and runs faster.
        TextureObjChunkRefPtr QuadTextureChunk = TextureObjChunk::create();
        ImageRefPtr LoadedImage = ImageFileHandler::the()->read("Data/Explosion.png");
        QuadTextureChunk->setImage(LoadedImage);

        TextureEnvChunkRefPtr QuadTextureEnvChunk = TextureEnvChunk::create();
        QuadTextureEnvChunk->setEnvMode(GL_MODULATE);

        BlendChunkRefPtr PSBlendChunk = BlendChunk::create();
        PSBlendChunk->setSrcFactor(GL_SRC_ALPHA);
        PSBlendChunk->setDestFactor(GL_ONE_MINUS_SRC_ALPHA);

        MaterialChunkRefPtr PSMaterialChunk = MaterialChunk::create();
        PSMaterialChunk->setLit(false);

        ChunkMaterialRefPtr PSMaterial = ChunkMaterial::create();
        PSMaterial->addChunk(QuadTextureChunk);
        PSMaterial->addChunk(QuadTextureEnvChunk);
        PSMaterial->addChunk(PSMaterialChunk);
        PSMaterial->addChunk(PSBlendChunk);

        //Particle System
        ParticleSystemRecPtr ExplosionParticleSystem = ParticleSystem::create();
        ExplosionParticleSystem->attachUpdateProducer(TutorialWindow);

        //Age Particle Function.  Controls which image is shown when, based on the age of a particle.
        AgeParticleFunctionRecPtr AgeFunc = AgeParticleFunction::create();
        AgeFunc->setSequenceTime(0.07f); // image changes every 0.1 seconds.
        AgeFunc->setSequenceOrder(AgeParticleFunction::CUSTOM); // using the custom sequence below.
        /*
           Here, a custom sequence for the image ordering is assembled.  The image sequence will be shown in
           the order specified here.  Once the end of the sequence is reached, the sequence repeats.
           */
        UInt32 NumImages(25);
        for(UInt32 i(0) ; i<NumImages ; ++i)
        {
            AgeFunc->editMFCustomSequence()->push_back(i);
        }

        //Particle System Drawer -
        QuadSequenceParticleSystemDrawerRecPtr ExplosionParticleSystemDrawer = QuadSequenceParticleSystemDrawer::create();
        // image dimensions (in pixels) are required if there is a border on the images.
        ExplosionParticleSystemDrawer->setImageDimensions(Vec2us(320,320));
        // The "dimensions" of the sequence contained in the image.  For this image,
        // there are 3 images in the "x" direction, and two in the "y" direction, for a
        // total of 6.
        ExplosionParticleSystemDrawer->setSequenceDimensions(Vec2b(5,5));
        // width of the border on each side of the image, in pixels.
        ExplosionParticleSystemDrawer->setBorderOffsets(Vec2b(0,0));
        // this is the age function we just created above.
        ExplosionParticleSystemDrawer->setSequenceFunction(AgeFunc);

        RateParticleGeneratorRecPtr ExplosionParticleGenerator = RateParticleGenerator::create();
        //Attach the function objects to the Generator
        ExplosionParticleGenerator->setPositionDistribution(createPositionDistribution());
        ExplosionParticleGenerator->setLifespanDistribution(createLifespanDistribution());
        ExplosionParticleGenerator->setVelocityDistribution(createVelocityDistribution());
        ExplosionParticleGenerator->setAccelerationDistribution(createAccelerationDistribution());
        ExplosionParticleGenerator->setSizeDistribution(createSizeDistribution());
        ExplosionParticleGenerator->setGenerationRate(100.0f);

        //Particle System Node
        ParticleSystemCoreRefPtr ExplosionParticleCore = ParticleSystemCore::create();
        ExplosionParticleCore->setSystem(ExplosionParticleSystem);
        ExplosionParticleCore->setDrawer(ExplosionParticleSystemDrawer);
        ExplosionParticleCore->setMaterial(PSMaterial);
        ExplosionParticleCore->setSortingMode(ParticleSystemCore::BACK_TO_FRONT);

        NodeRefPtr ExplosionParticleNode = Node::create();
        ExplosionParticleNode->setCore(ExplosionParticleCore);

        ExplosionParticleSystem->addParticle(Pnt3f(10.0,0.0,0.0),
                                             Vec3f(0.0,1.0,0.0),
                                             Color4f(1.0,1.0,1.0,1.0),
                                             Vec3f(1.0,1.0,1.0),
                                             0.01,
                                             Vec3f(0.0,0.0,0.0),
                                             Vec3f(0.0,0.0,0.0));

        ExplosionParticleSystem->addParticle(Pnt3f(-10.0,0.0,0.0),
                                             Vec3f(0.0,1.0,0.0),
                                             Color4f(1.0,1.0,1.0,1.0),
                                             Vec3f(1.0,1.0,1.0),
                                             0.01,
                                             Vec3f(0.0,0.0,0.0),
                                             Vec3f(0.0,0.0,0.0));

        ExplosionParticleSystem->pushToGenerators(ExplosionParticleGenerator);

        AgeSizeParticleAffectorRecPtr ExampleAgeSizeParticleAffector = AgeSizeParticleAffector::create();

        //Age and size
        ExampleAgeSizeParticleAffector->editMFAges()->push_back(0.0);
        ExampleAgeSizeParticleAffector->editMFSizes()->push_back(Vec3f(0.2,0.2,0.2));
        ExampleAgeSizeParticleAffector->editMFAges()->push_back(1.0);
        ExampleAgeSizeParticleAffector->editMFSizes()->push_back(Vec3f(4.0,4.0,4.0));
        ExampleAgeSizeParticleAffector->editMFAges()->push_back(1.8);
        ExampleAgeSizeParticleAffector->editMFSizes()->push_back(Vec3f(2.2,2.2,0.1));

        //Age Fade Affector
        AgeFadeParticleAffectorRecPtr ExampleAgeFadeParticleAffector = AgeFadeParticleAffector::create();

        //Age and size
        ExampleAgeFadeParticleAffector->setStartAlpha(0.0f);
        ExampleAgeFadeParticleAffector->setFadeInTime(0.5f);
        ExampleAgeFadeParticleAffector->setFadeToAlpha(1.0f);
        ExampleAgeFadeParticleAffector->setFadeOutTime(0.5f);
        ExampleAgeFadeParticleAffector->setEndAlpha(0.0f);
        ExplosionParticleSystem->pushToAffectors(ExampleAgeFadeParticleAffector);

        //Smoke Particle System
        VortexParticleAffectorRecPtr SmokeVortexAffector = VortexParticleAffector::create();
        SmokeVortexAffector->setMagnitude(0.2);
        SmokeVortexAffector->setVortexAxis(Vec3f(0.0,1.0,0.0)); // field rotates around y axis
        NodeRefPtr VortexBeacon = makeCoredNode<Group>();
        SmokeVortexAffector->setBeacon(VortexBeacon); // set to 'emulate' from (0,0,0)
        SmokeVortexAffector->setMaxDistance(-1.0); // particles affected regardless of distance
        SmokeVortexAffector->setAttenuation(0.25); // strength of uniform field dimishes by dist^attenuation

        AgeFadeParticleAffectorRecPtr SmokeAgeFadeParticleAffector = AgeFadeParticleAffector::create();

        //Age and size
        SmokeAgeFadeParticleAffector->setStartAlpha(0.0f);
        SmokeAgeFadeParticleAffector->setFadeInTime(0.2f);
        SmokeAgeFadeParticleAffector->setFadeToAlpha(1.0f);
        SmokeAgeFadeParticleAffector->setFadeOutTime(3.5f);
        SmokeAgeFadeParticleAffector->setEndAlpha(0.0f);

        RateParticleGeneratorRecPtr SmokeParticleGenerator = RateParticleGenerator::create();
        SmokeParticleGenerator->setSizeDistribution(createSmokeSizeDistribution());
        SmokeParticleGenerator->setPositionDistribution(createSmokePositionDistribution());
        SmokeParticleGenerator->setLifespanDistribution(createSmokeLifespanDistribution());
        SmokeParticleGenerator->setVelocityDistribution(createSmokeVelocityDistribution());
        SmokeParticleGenerator->setColorDistribution(createSmokeColorDistribution());
        SmokeParticleGenerator->setGenerationRate(80.0f);

        ParticleSystemRecPtr SmokeParticleSystem = ParticleSystem::create();
        SmokeParticleSystem->pushToGenerators(SmokeParticleGenerator);
        SmokeParticleSystem->attachUpdateProducer(TutorialWindow);
        SmokeParticleSystem->pushToAffectors(SmokeAgeFadeParticleAffector);
        SmokeParticleSystem->pushToAffectors(SmokeVortexAffector);

        TextureObjChunkRefPtr SmokeTextureObjChunk = TextureObjChunk::create();
        ImageRefPtr SmokeImage = ImageFileHandler::the()->read("Data/Smoke.png");
        SmokeTextureObjChunk->setImage(SmokeImage);

        ChunkMaterialRefPtr SmokeMaterial = ChunkMaterial::create();
        SmokeMaterial->addChunk(SmokeTextureObjChunk);
        SmokeMaterial->addChunk(QuadTextureEnvChunk);
        SmokeMaterial->addChunk(PSMaterialChunk);
        SmokeMaterial->addChunk(PSBlendChunk);
        SmokeMaterial->setSortKey(-1.0f);

        QuadParticleSystemDrawerRecPtr SmokeParticleSystemDrawer = QuadParticleSystemDrawer::create();

        ParticleSystemCoreRefPtr SmokeParticleCore = ParticleSystemCore::create();
        SmokeParticleCore->setSystem(SmokeParticleSystem);
        SmokeParticleCore->setDrawer(SmokeParticleSystemDrawer);
        SmokeParticleCore->setMaterial(SmokeMaterial);
        SmokeParticleCore->setSortingMode(ParticleSystemCore::BACK_TO_FRONT);

        NodeRefPtr SmokeParticleNode = Node::create();
        SmokeParticleNode->setCore(SmokeParticleCore);

        // Make Main Scene Node and add the Torus
        NodeRefPtr scene = makeCoredNode<Group>();
        scene->addChild(ExplosionParticleNode);
        scene->addChild(SmokeParticleNode);
        scene->addChild(VortexBeacon);

        TutorialWindow->connectKeyTyped(boost::bind(keyTyped, _1,
                                        &sceneManager,
                                        AgeFunc.get()));

        sceneManager.setRoot(scene);

        // Show the whole Scene
        sceneManager.showAll();

        //Open Window
        Vec2f WinSize(TutorialWindow->getDesktopSize() * 0.85f);
        Pnt2f WinPos((TutorialWindow->getDesktopSize() - WinSize) *0.5);
        TutorialWindow->openWindow(WinPos,
                                   WinSize,
                                   "06Explosion");

        //Enter main Loop
        TutorialWindow->mainLoop();
    }

    osgExit();

    return 0;
}
예제 #6
0
void Enemy::onUpdate()
{
	if(invisibility) invisibility--;

	Vec2i facing = intToDir(dir);

	if(level.getAIFlags(position) & 2)
	{
		// Vergiftung
		contamination--;
	}

	if(contamination <= 0) burst();

	if(!thinkCounter--)
	{
		// den nächsten Spieler suchen, der für den Gegner sichtbar ist
		Player* p_closestPlayer = 0;
		int closestDist = 0;
		const std::list<Player*>& players = Player::getInstances();
		for(std::list<Player*>::const_iterator i = players.begin(); i != players.end(); ++i)
		{
			if(!(*i)->isTeleporting())
			{
				int dist = (position - (*i)->getPosition()).lengthSq();
				if(dist < closestDist || !p_closestPlayer)
				{
					if(canSee((*i)->getPosition()))
					{
						p_closestPlayer = *i;
						closestDist = dist;
					}
				}
			}
		}

		if(p_closestPlayer)
		{
			targetPosition = p_closestPlayer->getPosition();
			interest += 2225 - closestDist;
		}

		thinkCounter = random(2, 5);
	}

	if(subType == 0)
	{
		int oldDir = dir;

		if(moveCounter-- <= 0 && fabs(shownDir - dir) < 0.4)
		{
			int r = random(0, 8);
			if(interest >= 10000) r = random(0, 40);

			if(contamination < 50)
			{
				if(random() % 2) r = 0;
			}

			interest /= 2;

			switch(r)
			{
			case 0:
				{
					int d = random(-22, 22) / 10;
					if(d) dir += d, anim += 16;
				}
				break;
			case 1:
			case 2:
			case 3:
				if(!tryToMove(facing)) dir += random(-22, 22) / 10;
				anim += 16;
				break;
			default:
				if(r >= 6 && targetPosition.x != -1)
				{
					// zum Ziel laufen
					Vec2i toTarget = targetPosition - position;
					if(toTarget.x && toTarget.y) toTarget.value[random(0, 1)] = 0;
					int d = dirToInt(toTarget);
					toTarget = intToDir(d);
					if(tryToMove(toTarget))
					{
						dir = d;
						anim += 16;
						interest *= 2;
					}
				}
				break;
			}

			if(position == targetPosition || interest < 10)
			{
				targetPosition = Vec2i(-1, -1);
				interest = 0;
			}

			while(dir < 0) dir += 4, shownDir += 4.0;
			dir %= 4;

			moveCounter = random(4, 7);
		}

		if(anim) anim--;

		double dd = static_cast<double>(dir) - shownDir;
		if(dd > 2.0) shownDir += 4.0;
		else if(dd < -2.0) shownDir -= 4.0;
		shownDir = 0.125 * dir + 0.875 * shownDir;

		if(!soundCounter)
		{
			if(oldDir != dir)
			{
				// Kratz-Sound abspielen
				Engine::inst().playSound("enemy1_turn.ogg", false, 0.1, -100);
				soundCounter = random(15, 55);
			}
		}
		else soundCounter--;

		if(burpCounter)
		{
			burpCounter--;
			if(!burpCounter)
			{
				int s = random(0, 1);
				std::string sound;
				if(s == 0) sound = "enemy1_burp1.ogg";
				else if(s == 1) sound = "enemy1_burp2.ogg";
				Engine::inst().playSound(sound, false, 0.1);

				// Rülpspartikel erzeugen
				ParticleSystem* p_particleSystem = level.getParticleSystem();
				ParticleSystem::Particle p;
				for(int i = 0; i < 10; i++)
				{
					p.lifetime = random(50, 75);
					p.damping = 0.99f;
					p.gravity = random(-0.005f, -0.02f);
					p.positionOnTexture = Vec2b(96, 32);
					p.sizeOnTexture = Vec2b(16, 16);
					p.position = position * 16 + Vec2i(8 + random(-4, 4), 6);
					p.velocity = Vec2d(random(-0.5, 0.5), random(-1.0, -0.5));
					p.color = Vec4d(random(0.8, 1.0), random(0.8, 1.0), random(0.8, 1.0), 0.25);
					p.deltaColor = Vec4d(0.0, 0.0, 0.0, -p.color.a / p.lifetime);
					p.rotation = random(-0.5f, 0.5f);
					p.deltaRotation = random(-0.05f, 0.05f);
					p.size = random(0.2f, 1.0f);
					p.deltaSize = random(0.0f, 0.01f);
					p_particleSystem->addParticle(p);
				}
			}
		}
	}
	else if(subType == 1)
	{
		if(random() % 2) anim++;

		if(moveCounter-- <= 0)
		{
			int r = random(0, 1);
			if(interest > 6000) r = random(0, 50);

			if(contamination < 50)
			{
				if(random() % 2) r = 0;
			}

			interest /= 2;

			switch(r)
			{
			case 0:
				tryToMove(intToDir(random(0, 4)));
				break;
			default:
				if(targetPosition.x != -1)
				{
					// zum Ziel laufen
					Vec2i toTarget = targetPosition - position;
					if(toTarget.x && toTarget.y) toTarget.value[random(0, 1)] = 0;
					int d = dirToInt(toTarget);
					toTarget = intToDir(d);
					if(tryToMove(toTarget)) interest *= 2;
				}
				else
				{
					// Wo ist die Spur am heißesten?
					int bestDir = 0;
					uint bestTrace = 0;
					for(int dir = 0; dir < 4; dir++)
					{
						uint trace = level.getAITrace(position + intToDir(dir));
						if(trace > bestTrace)
						{
							bestTrace = trace;
							bestDir = dir;
						}
					}

					if(bestTrace)
					{
						Vec2i bestDirV = intToDir(bestDir);
						if(!tryToMove(bestDirV))
						{
							// Das ging nicht. Ist da ein anderer Gegner?
							bool reduceTrace = true;
							Object* p_obj = level.getFrontObjectAt(position + bestDirV);
							if(p_obj)
							{
								// Wenn da ein anderer Gegner ist, ist es egal.
								if(p_obj->getType() == "Enemy") reduceTrace = false;
							}

							if(reduceTrace)
							{
								// Die Spur dort etwas uninteressanter machen!
								level.setAITrace(position + bestDirV, bestTrace / 2);
							}
						}
						else
						{
							if(bestTrace > 850) interest = 160000;
							else if(bestTrace > 100) interest = 20000;
						}
					}
				}
				break;
			}

			if(position == targetPosition || interest < 10)
			{
				targetPosition = Vec2i(-1, -1);
				interest = 0;
			}

			moveCounter = random(4, 7);
		}

		if(height == 0.0)
		{
			if(!(random() % 25))
			{
				vy = random(40.0, 80.0);
				height = 0.5;
			}
		}
		else
		{
			height += 0.02 * vy;
			vy -= 0.02 * 400.0;

			if(height < 0.5)
			{
				height = 0.0;
				vy = 0.0;
			}
		}

		int pr = 700;
		if(interest >= 10000) pr = 350;
		if(!(random() % pr))
		{
			// Lachen abspielen
			Engine::inst().playSound("enemy2_laugh.ogg", false, 0.15, -100);
		}

		if(interest >= 40000)
		{
			if(!(random() % 200))
			{
				// Knurren abspielen
				Engine::inst().playSound("enemy2_growl.ogg", false, 0.15, -100);
			}
		}

		if(interest >= 10000)
		{
			// Feuer
			ParticleSystem* p_particleSystem = level.getParticleSystem();
			ParticleSystem* p_fireParticleSystem = level.getFireParticleSystem();
			ParticleSystem::Particle p;
			p.lifetime = random(40, 50);
			p.damping = 0.9f;
			p.gravity = -0.04f;
			p.positionOnTexture = Vec2b(32, 0);
			p.sizeOnTexture = Vec2b(16, 16);
			const double r = random(0.0, 6.283);
			const Vec2d vr(sin(r), cos(r));
			p.position = position * 16 + Vec2d(7.5, 7.5 - height) + 7.5 * vr;
			p.velocity = vr;
			p.color = Vec4d(random(0.5, 1.0), random(0.8, 1.0), random(0.0, 0.25), random(0.2, 0.4));
			const double dc = -1.5 / (p.lifetime + random(-25, 25));
			p.deltaColor = Vec4d(dc, dc, dc, -p.color.a / p.lifetime);
			p.rotation = random(0.0f, 10.0f);
			p.deltaRotation = random(-0.1f, 0.1f);
			p.size = random(0.5f, 0.9f);
			p.deltaSize = random(0.0075f, 0.015f);
			if(random() % 2) p_particleSystem->addParticle(p);
			else p_fireParticleSystem->addParticle(p);
		}
	}

	if(eatCounter) eatCounter--;
}
예제 #7
0
void Enemy::onCollect(Player* p_player)
{
	if(p_player->isTeleporting()) return;

	if(subType == 0)
	{
		if(!eatCounter)
		{
			ParticleSystem* p_particleSystem = level.getParticleSystem();
			ParticleSystem::Particle p;

			// die Metzelei hinter einer Staubwolke verstecken
			for(int i = 0; i < 150; i++)
			{
				p.lifetime = 100;
				p.damping = 0.99f;
				p.gravity = 0.005f;
				p.positionOnTexture = Vec2b(0, 0);
				p.sizeOnTexture = Vec2b(16, 16);
				p.position = position * 16 + Vec2i(random(4, 12), random(4, 12));
				double a = random(0.0, 1000.0);
				p.velocity = Vec2d(sin(a), cos(a)) * random(0.05, 1.0);
				double c = random(0.6, 1.0);
				p.color = p_player->getDebrisColor();
				p.color.a *= random(0.5f, 1.2f);
				p.deltaColor = Vec4d(0.0, 0.0, 0.0, -p.color.a / p.lifetime);
				p.rotation = random(0.0f, 10.0f);
				p.deltaRotation = random(-0.1f, 0.1f);
				p.size = random(0.3f, 0.5f);
				p.deltaSize = random(0.01f, 0.05f);
				p_particleSystem->addParticle(p);
			}

			Engine::inst().playSound("enemy1_eat.ogg", false, 0.1);
			p_player->disappear(1.5);
			p_player->censored = true;
			moveCounter = 130;
			eatCounter = 130;
			burpCounter = 100;

			slideDir = -1;
		}
	}
	else if(subType == 1)
	{
		if(!eatCounter)
		{
			ParticleSystem* p_particleSystem = level.getParticleSystem();
			ParticleSystem::Particle p;

			// die Metzelei hinter einer Staubwolke verstecken
			for(int i = 0; i < 150; i++)
			{
				p.lifetime = 100;
				p.damping = 0.99f;
				p.gravity = 0.005f;
				p.positionOnTexture = Vec2b(0, 0);
				p.sizeOnTexture = Vec2b(16, 16);
				p.position = position * 16 + Vec2i(random(4, 12), random(4, 12));
				double a = random(0.0, 1000.0);
				p.velocity = Vec2d(sin(a), cos(a)) * random(0.05, 1.0);
				double c = random(0.6, 1.0);
				p.color = p_player->getDebrisColor();
				p.color.a *= random(0.5f, 1.2f);
				p.deltaColor = Vec4d(0.0, 0.0, 0.0, -p.color.a / p.lifetime);
				p.rotation = random(0.0f, 10.0f);
				p.deltaRotation = random(-0.1f, 0.1f);
				p.size = random(0.3f, 0.5f);
				p.deltaSize = random(0.01f, 0.05f);
				p_particleSystem->addParticle(p);
			}

			Engine::inst().playSound("enemy2_eat.ogg", false, 0.1);
			p_player->disappear(1.5);
			p_player->censored = true;
			moveCounter = 130;
			eatCounter = 130;
			burpCounter = 100;

			slideDir = -1;
		}
	}
}