// Update: draw background update_status ModuleParticles::Update() { p2List_item<Particle*>* tmp = active.getFirst(); p2List_item<Particle*>* tmp_next = active.getFirst(); while(tmp != NULL) { Particle* p = tmp->data; tmp_next = tmp->next; if(p->Update() == false) { delete p; active.del(tmp); } else if(SDL_GetTicks() >= p->born) { App->renderer->Blit(graphics, p->position.x, p->position.y, &(p->anim.GetCurrentFrame())); if(p->fx_played == false) { p->fx_played = true; // App->audio->PlayFx(p->fx); } } tmp = tmp_next; } return UPDATE_CONTINUE; }
update_status ModuleParticles::Update() { for(uint i = 0; i < MAX_ACTIVE_PARTICLES; ++i) { Particle* p = active[i]; if(p == nullptr) continue; if(p->Update() == false) { delete p; active[i] = nullptr; } else if(SDL_GetTicks() >= p->born) { App->render->Blit(graphics, p->position.x, p->position.y, &(p->anim.GetCurrentFrame())); if(p->fx_played == false) { p->fx_played = true; App->audio->PlayFx(p->fx); } } } return UPDATE_CONTINUE; }
// Update: draw background update_status ModuleParticles::Update() { for(uint i = 0; i < MAX_ACTIVE_PARTICLES; ++i) { Particle* p = active[i]; if(p == nullptr) continue; if(p->Update() == false) { if (p->collider_box != nullptr) p->collider_box->to_delete = true; delete p; active[i] = nullptr; } else if(SDL_GetTicks() >= p->born) { App->render->BlitParticle(p->tex, p->position.x, p->position.y, &(p->anim.GetCurrentFrame()), p->angle); if(p->fx_played == false) { p->fx_played = true; App->audio->PlaySoundEffect(p->sound); // Play particle fx here } } } return UPDATE_CONTINUE; }
// Update: draw background update_status ModuleParticles::Update() { shoot_player.speed.x = ((App->player->position.x + TILE/2) / ((SCREEN_WIDTH - TILE )/ 14)) - 7; for (uint i = 0; i < MAX_ACTIVE_PARTICLES; ++i) { Particle* p = active[i]; if (p == nullptr) continue; if (p->Update() == false) { delete p; active[i] = nullptr; } else if (SDL_GetTicks() >= p->born) { App->render->Blit(graphics, p->position.x, p->position.y, &(p->anim.GetCurrentFrame())); if (p->fx_played == false) { p->fx_played = true; //play particle fx here } } } return UPDATE_CONTINUE; }
///===================================================== /// ///===================================================== void ParticleEmitter::Update(double deltaSeconds){ double currentTime = GetCurrentSeconds(); //update existing particles for (Particles::iterator particleIter = m_particles.begin(); particleIter != m_particles.end();){ Particle* particle = *particleIter; //delete expired particles if (particle->m_expirationTime < currentTime){ delete particle; particleIter = m_particles.erase(particleIter); continue; } particle->Update(deltaSeconds); ++particleIter; } //add new particles m_timeSinceParticleEmission += deltaSeconds; if (m_timeSinceParticleEmission >= m_timeBetweenParticleEmissions){ AddParticles(); m_timeSinceParticleEmission -= m_timeBetweenParticleEmissions; } }
///========================================================================================================================================== /// Debris ///========================================================================================================================================== void DebrisEmitter::Update(double deltaSeconds){ double currentTime = GetCurrentSeconds(); //update existing particles for (Particles::iterator particleIter = m_particles.begin(); particleIter != m_particles.end();){ Particle* particle = *particleIter; //delete expired particles if (particle->m_expirationTime < currentTime){ delete particle; particleIter = m_particles.erase(particleIter); continue; } particle->m_velocity.y -= m_acceleration * (float)deltaSeconds; particle->Update(deltaSeconds); if (particle->m_position.y < m_position.y){ particle->m_velocity.y = -particle->m_velocity.y * GetRandomFloatInRange(0.6f, 0.8f); } ++particleIter; } //add new particles m_timeSinceParticleEmission += deltaSeconds; if (m_timeSinceParticleEmission >= m_timeBetweenParticleEmissions){ AddParticles(); m_timeSinceParticleEmission -= m_timeBetweenParticleEmissions; } }
// Update: draw background update_status ModuleSphere::Update() { for (uint i = 0; i < MAX_ACTIVE_SPHERES; ++i) { for (uint i = 0; i < MAX_ACTIVE_SPHERES; ++i) { Sphere* s = active[i]; if (s != nullptr) if (s->Update() == false || (s->speed.y>0 && s->particlePosition.y>SCREEN_HEIGHT*SCREEN_SIZE)) { delete s; active[i] = nullptr; } else if (SDL_GetTicks() >= s->born) { int random_time_l = rand() % 100; if (random_time_l % 5 == 0) { if (s->idle.Finished()) { s->idle.Reset(); } } App->render->Blit(graphics, s->particlePosition.x, s->particlePosition.y, &(s->idle.GetCurrentFrame())); if (s->fx_played == false) { s->fx_played = true; } } } for (uint i = 0; i < MAX_EXPLOSIONS; ++i) { Particle* p = active_explosion[i]; if (p == nullptr) continue; if (p->Update() == false) { delete p; active_explosion[i] = nullptr; continue; } App->render->Blit(graphics, p->position.x, p->position.y, &(p->anim.GetCurrentFrame())); } return UPDATE_CONTINUE; } }
update_status ModuleDrawParticles::Update(){ for (uint i = 0; i < MAX_ACTIVE_PARTICLES; ++i) { Particle* p = App->particles->active[i]; if (p == nullptr || p->drawit==AFTER_PLAYER) continue; if (p->Update() == false) { if (p->end_particle == &App->particles->bannana){ App->particles->SetParticleSpeed(&App->particles->bannana, 0, -2); App->particles->AddParticle(*p->end_particle, p->position.x + 5, p->position.y, COLLIDER_ENEMY_SHOT, nullrect); App->particles->SetParticleSpeed(&App->particles->bannana, 1.41f, -1.41f); App->particles->AddParticle(*p->end_particle, p->position.x + 5, p->position.y, COLLIDER_ENEMY_SHOT, nullrect); App->particles->SetParticleSpeed(&App->particles->bannana, 2, 0); App->particles->AddParticle(*p->end_particle, p->position.x + 5, p->position.y, COLLIDER_ENEMY_SHOT, nullrect); App->particles->SetParticleSpeed(&App->particles->bannana, 1.41f, 1.41f); App->particles->AddParticle(*p->end_particle, p->position.x + 5, p->position.y, COLLIDER_ENEMY_SHOT, nullrect); App->particles->SetParticleSpeed(&App->particles->bannana, 0, 2); App->particles->AddParticle(*p->end_particle, p->position.x + 5, p->position.y, COLLIDER_ENEMY_SHOT, nullrect); App->particles->SetParticleSpeed(&App->particles->bannana, -1.41f, 1.41f); App->particles->AddParticle(*p->end_particle, p->position.x + 5, p->position.y, COLLIDER_ENEMY_SHOT, nullrect); App->particles->SetParticleSpeed(&App->particles->bannana, -2, 0); App->particles->AddParticle(*p->end_particle, p->position.x + 5, p->position.y, COLLIDER_ENEMY_SHOT, nullrect); App->particles->SetParticleSpeed(&App->particles->bannana, -1.41f, -1.41f); App->particles->AddParticle(*p->end_particle, p->position.x + 5, p->position.y, COLLIDER_ENEMY_SHOT, nullrect); } if (p->collider_box != nullptr) p->collider_box->to_delete = true; delete p; App->particles->active[i] = nullptr; } else if (SDL_GetTicks() >= p->born) { App->render->BlitParticle(p->tex, p->position.x, p->position.y, &(p->anim.GetCurrentFrame()), p->angle); if (p->fx_played == false) { p->fx_played = true; App->audio->PlaySoundEffect(p->sound); // Play particle fx here } } } return UPDATE_CONTINUE; }
///===================================================== /// ///===================================================== void WaveEmitter::Update(double deltaSeconds){ double currentTime = GetCurrentSeconds(); //update existing particles for (Particles::iterator particleIter = m_particles.begin(); particleIter != m_particles.end();){ Particle* particle = *particleIter; //delete expired particles if (particle->m_expirationTime < currentTime){ delete particle; particleIter = m_particles.erase(particleIter); continue; } //COLORFUL SPIRAL LOL Vec2 tempVel(particle->m_velocity.x, particle->m_velocity.z); tempVel.RotateDegrees(32.0f * (float)deltaSeconds * 90.0f / (float)m_duration); particle->m_velocity = Vec3(tempVel.x, 0.0f, tempVel.y); Vec2 tempPos(particle->m_position.x, particle->m_position.z); tempPos.RotateDegrees(32.0f * (float)deltaSeconds * 90.0f / (float)m_duration); particle->m_position = Vec3(tempPos.x, particle->m_position.y, tempPos.y); if (GetRandomFloatInRange(0.0f, 1.0f) > cos(currentTime)){ particle->m_color.r -= (unsigned char)GetRandomIntInRange(0, 3); particle->m_color.g -= (unsigned char)GetRandomIntInRange(2, 6); particle->m_color.b += (unsigned char)GetRandomIntInRange(1, 9); } particle->m_position.y = m_position.y + m_waveHeight * cos((CalcDistance(Vec2(m_position.x, m_position.z), Vec2(particle->m_position.x, particle->m_position.z)) - (float)currentTime) * m_waveSpeed); particle->Update(deltaSeconds); ++particleIter; } //add new particles m_timeSinceParticleEmission += deltaSeconds; if (m_timeSinceParticleEmission >= m_timeBetweenParticleEmissions){ AddParticles(); m_timeSinceParticleEmission -= m_timeBetweenParticleEmissions; } }
int Emitter::Update(const float a_fDeltaTime) { aliveTime_ += a_fDeltaTime; if (aliveTime_ <= lifeTime_ || lifeTime_ == -1) { for (int i = 0; i < frequency_; i++) { //particles_.push_back(new Particle(particle_,Maths::Vector2(dir_.Bearing() + static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / spreadRadians_)) - spreadRadians_ * 0.5f), pos_)); particles_.push_back(new Particle(filename_, particle_->GetStartingColour(), particle_->GetEndingColour(), particle_->GetSize(),Maths::Vector2(dir_.Bearing() + static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / spreadRadians_)) - spreadRadians_ * 0.5f), pos_, particle_->GetLifeTimeSeconds(), particle_->GetSpeed())); } for (auto iter = particles_.begin(); iter != particles_.end(); ) { Particle* p = (*iter); if (p->Update(a_fDeltaTime) == 0) { iter = particles_.erase(iter); delete p; } else { ++iter; } } return 1; } for (auto iter = particles_.begin(); iter != particles_.end(); ++iter) { Particle* p = (*iter); p->StopDrawing(); } return 0; }
void Emitter::Update(long time) { if (this->texture == NULL) { return; } if (this->lastTime == -1) { this->lastTime = time; } int numberOfEmission = (int) (time - this->lastTime) / 1000.0f * this->emissionRate; for (int i = 0; i < numberOfEmission; i++) { addParticle(); } if (numberOfEmission > 0) { this->lastTime = time; } glDisable(GL_LIGHTING); glDisable(GL_DEPTH_TEST); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glTranslatef(this->position.x, this->position.y, this->position.z); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, this->texture->texID); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); if (this->texture->getMode() == MODE_DARKEN) { glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_ALPHA); } else if (this->texture->getMode() == MODE_NORMAL) { glBlendFunc(GL_SRC_ALPHA, GL_ONE); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR); } for (list<Particle *>::iterator it = this->particles.begin(); it != this->particles.end(); it++) { Particle *particle = (*it); particle->acceleration.y = -this->gravity; particle->acceleration += this->wind; particle->alpha = this->alpha; particle->rotation = this->rotation; particle->Update(time); if (particle->active == false) { delete particle; list<Particle *>::iterator pTemp = it--; this->particles.erase(pTemp); } } glBlendFunc(GL_SRC_ALPHA, GL_ONE); glMatrixMode(GL_MODELVIEW); glPopMatrix(); }
void ParticleEmitter::update() { // get current time float current_time = globalTimer::getTimerInSec(); // spawn particles float time_elapsed = current_time - this->data->last_spawn; // update while( this->data->spawn_frequency < time_elapsed ) { // spawn a particle this->SpawnParticle(); // adjust time time_elapsed -= this->data->spawn_frequency; // last time this->data->last_spawn = current_time; } //// total elapsed time_elapsed = current_time - this->data->last_loop; Particle *p = this->headParticle; // walk the particles while( p!= 0 ) { // call every particle and update its position p->Update(time_elapsed); // if it's live is greater that the max_life // and there is some on the list // remove node if((p->life > this->data->max_life) && (this->last_active_particle > 0)) { // particle to remove Particle *s = p; // need to squirrel it away. p=p->next; // remove last node this->removeParticleFromList( s ); // update the number of particles this->last_active_particle--; } else { p = p->next; } } p = this->headParticle; this->bufferCount = 0; while(p != 0) { // add to buffer // track the current count drawBuffer[this->bufferCount++] = *p; // advance ptr p = p->next; } // make sure the counts track (asserts go away in release - relax Christos) assert(bufferCount == (this->last_active_particle+1)); this->data->last_loop = current_time; }
///===================================================== /// ///===================================================== void ClothEmitter::Update(double deltaSeconds){ //constrain particles with spring forces std::vector<Vec3> totalParticleAcceleration(m_clothParticles.size(), Vec3(0.0f, 0.0f, 0.0f)); //constrain adjacent particles for (int i = 0; i < m_particlesPerEmission; ++i){ int iXparticlesPerEmission = i * m_particlesPerEmission; for (int j = 0; j < m_particlesPerEmission - 1; ++j){ CalculateSpringAcceleration(iXparticlesPerEmission + j, iXparticlesPerEmission + j + 1, m_distanceBetweenParticles, totalParticleAcceleration); } } for (int j = 0; j < m_particlesPerEmission; ++j){ for (int i = 0; i < m_particlesPerEmission - 1; ++i){ CalculateSpringAcceleration(i * m_particlesPerEmission + j, (i + 1) * m_particlesPerEmission + j, m_distanceBetweenParticles, totalParticleAcceleration); } } //constrain diagonal particles for (int i = 0; i < m_particlesPerEmission - 1; ++i){ for (int j = 0; j < m_particlesPerEmission - 1; ++j){ CalculateSpringAcceleration(i * m_particlesPerEmission + j, (i + 1) * m_particlesPerEmission + j + 1, m_distanceBetweenParticles * sqrt(2.0f), totalParticleAcceleration); } } for (int i = 0; i < m_particlesPerEmission - 1; ++i){ for (int j = 1; j < m_particlesPerEmission; ++j){ CalculateSpringAcceleration(i * m_particlesPerEmission + j, (i + 1) * m_particlesPerEmission + j - 1, m_distanceBetweenParticles * sqrt(2.0f), totalParticleAcceleration); } } //constrain 2-away adjacent particles for (int i = 0; i < m_particlesPerEmission; ++i){ int iXparticlesPerEmission = i * m_particlesPerEmission; for (int j = 0; j < m_particlesPerEmission - 2; ++j){ CalculateSpringAcceleration(iXparticlesPerEmission + j, iXparticlesPerEmission + j + 2, m_distanceBetweenParticles * 2.0f, totalParticleAcceleration); } } for (int j = 0; j < m_particlesPerEmission; ++j){ for (int i = 0; i < m_particlesPerEmission - 2; ++i){ CalculateSpringAcceleration(i * m_particlesPerEmission + j, (i + 2) * m_particlesPerEmission + j, m_distanceBetweenParticles * 2.0f, totalParticleAcceleration); } } for (unsigned int i = 0; i < m_clothParticles.size(); ++i){ m_clothParticles[i]->m_velocity += totalParticleAcceleration[i] * (float)deltaSeconds; } //update particles based on forces acting on them for (ClothParticles::iterator particleIter = m_clothParticles.begin(); particleIter != m_clothParticles.end(); ++particleIter){ Particle* particle = *particleIter; if (m_gravityEnabled) particle->m_velocity.y -= 3.0f * (0.6f + particle->m_velocity.y) * (float)deltaSeconds; //gravity particle->m_velocity -= 0.5f * (particle->m_velocity - m_wind * (0.8f + ComputePerlinNoiseValueAtPosition2D(Vec2(particle->m_position.x, particle->m_position.z), 5.0f, 8, 0.2f, 0.5f))) * (float)deltaSeconds; //wind Vec3 prevParticlePosition = particle->m_position; particle->Update(deltaSeconds); if (m_drawBox) CollideParticleWithBox(*particle, prevParticlePosition); } //pin specific particles for (int i = 0; i < 5; ++i){ Particle* particle = m_immovableParticles[i]; if (particle != nullptr) particle->m_position = particle->m_initialPosition; } }
//#define collisions ///========================================================================================================================================== /// Fireworks ///========================================================================================================================================== void FireworksEmitter::Update(double deltaSeconds){ double currentTime = GetCurrentSeconds(); #if defined collisions Vec3s initialPositions; Vec3s finalPositions; #endif //update existing particles for (Particles::iterator particleIter = m_particles.begin(); particleIter != m_particles.end();){ Particle* particle = *particleIter; //delete expired particles if (particle->m_expirationTime < currentTime){ delete particle; particleIter = m_particles.erase(particleIter); continue; } #if defined collisions initialPositions.push_back(particle->m_position); #endif particle->m_velocity.y -= m_acceleration * (float)deltaSeconds; particle->Update(deltaSeconds); #if defined collisions finalPositions.push_back(particle->m_position); #endif ++particleIter; } #if defined collisions int count1 = 0; int count2 = 0; for (Particles::iterator particleIter = m_particles.begin(); particleIter != m_particles.end();){ Particle* particle = *particleIter; Vec3 p1 = initialPositions.at(count1); if (CalcDistanceSquared(p1, m_position) < 0.5f){ ++particleIter; ++count1; continue; } Vec3 p2 = finalPositions.at(count1); count2 = ++count1; float R1 = 0.00000001f; for (Particles::iterator particleIter2 = ++particleIter; particleIter2 != m_particles.end(); ++particleIter2, ++count2){ Particle* particle2 = *particleIter2; Vec3 q1 = initialPositions.at(count2); if (CalcDistanceSquared(q1, m_position) < 0.5f){ continue; } Vec3 q2 = finalPositions.at(count2); float R2 = 0.00000001f; Vec3 x0(q1 - p1); Vec3 e(q2 - q1 - (p2 - p1)); float R = R1 + R2; float collisionTest = (DotProduct(e, x0) * DotProduct(e, x0)) - (DotProduct(e, e) * (DotProduct(x0, x0) - (R * R))); if (collisionTest >= 0.0f){ //did collide float collisionTime = (-DotProduct(e, x0) - sqrt(collisionTest)) / DotProduct(e, e); if (collisionTime < 0.0f) collisionTime = 0.0f; particle2->m_color = RGBAchars::YELLOW; particle->m_color = RGBAchars::YELLOW; particle->m_position = initialPositions.at(count1 - 1); particle2->m_position = initialPositions.at(count2); Vec3 collisionNormal = particle->m_position - particle2->m_position; float length = collisionNormal.Normalize(); if (length <= 0.001f) continue; float v1Parallel = DotProduct(particle->m_velocity, collisionNormal); Vec3 v1Perp = particle->m_velocity - v1Parallel * collisionNormal; float v2Parallel = DotProduct(particle2->m_velocity, collisionNormal); Vec3 v2Perp = particle2->m_velocity - v2Parallel * collisionNormal; float e = 0.7f; Vec3 v1ParralelFinal = (0.5f * (v1Parallel + v2Parallel + e * (v2Parallel - v1Parallel))) * collisionNormal; Vec3 v2ParralelFinal = (0.5f * (v1Parallel + v2Parallel - e * (v2Parallel - v1Parallel))) * collisionNormal; particle->m_velocity = v1ParralelFinal + v1Perp; particle2->m_velocity = v2ParralelFinal + v2Perp; } } } #endif //add new particles m_timeSinceParticleEmission += deltaSeconds; if (m_timeSinceParticleEmission >= m_timeBetweenParticleEmissions){ AddParticles(); m_timeSinceParticleEmission -= m_timeBetweenParticleEmissions; } }
void Emitter::Update(long time) { if(texture == NULL) //MUST have a texture return; if(lastTime == -1) lastTime = time; int numEmisson = (int) ( (float) time - lastTime / 50000000.0f * emmissionRate); // control emmission rate for( int i = 0; i < numEmisson; i++) { addParticle(); } if(numEmisson >0) { lastTime = time; } glDisable(GL_LIGHTING); glDisable(GL_DEPTH_TEST); //disables depth perception. particles will be drawn no matter what glMatrixMode(GL_MODELVIEW); glPushMatrix(); glTranslatef(position.x, position.y, position.z); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texture->texID); for(list<Particle *>::iterator it = particles.begin(); it != particles.end(); it++)//huge loop to go through each particle and get it's update { Particle *particle = (*it); //it points to particle particle->acceleration.y = -gravity; particle->acceleration += wind; particle->alpha = alpha; particle->rotation = rotation; particle->Update(time); if(particle->active == false)//if it is no loinger active, delete it from the list. { delete particle; //current particle list<Particle *>::iterator pTemp = it--; //current location 1 iteration back to avoid empty reference particles.erase(pTemp); } } glMatrixMode(GL_MODELVIEW); glPopMatrix(); }