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