[work 17] Fireworks

[work 17] Fireworks

Movie

Source code

about

  • 花火のように粒子が飛び出す様子を表現する

file

  • 上部にあるファイル名が表示されているボタンを押すと、表示されるファイルが切り替わります
  • 別ウィンドウ表示したい時や行番号などが無いRawMode表示したい時は、コード内右上のボタンを押してください(ボタンはマウスオーバーすると表示されます)
#include "ofMain.h"
#include "ofApp.h"

//================================
int main( ){

    // 4K:4096x2160
    // 2K:2048x1080
    // FullHD:1920x1080
    // HD:1440x1080
    // HD720p:1280x720
    // DVD:720x480
    // setup the GL context
	ofSetupOpenGL(1280,720, OF_WINDOW);

	// this kicks off the running of my app
	// can be OF_WINDOW or OF_FULLSCREEN
	// pass in width and height too:
	ofRunApp( new ofApp());

}
#pragma once

#include "ofMain.h"

#include "ParticleSystem.hpp"



class ofApp : public ofBaseApp{
	public:
    ofApp();
    ~ofApp();
    
		void setup();
		void update();
		void draw();
		
		void keyPressed(int key);
		void keyReleased(int key);
		void mouseMoved(int x, int y);
		void mouseDragged(int x, int y, int button);
		void mousePressed(int x, int y, int button);
		void mouseReleased(int x, int y, int button);
		void mouseEntered(int x, int y);
		void mouseExited(int x, int y);
		void windowResized(int w, int h);
		void dragEvent(ofDragInfo dragInfo);
		void gotMessage(ofMessage msg);
    
private:
    std::vector<std::unique_ptr<ParticleSystem>> psList;
};
#include "ofApp.h"


ofApp::ofApp(){
    
}

ofApp::~ofApp(){
    
}

//--------------------------------------------------------------
void ofApp::setup(){
    double fps = 30;
    
    ofSetFrameRate(fps);
    ofBackground(0);
    ofSetBackgroundAuto(true);
}

//--------------------------------------------------------------
void ofApp::update(){
    for (std::unique_ptr<ParticleSystem> &ps : psList) {
        ps->applyForce(ofVec2f(0, 0.1));
        ps->update();
    }
}

//--------------------------------------------------------------
void ofApp::draw(){
    auto itr = psList.begin();
    while (itr != psList.end()) {
        (*itr)->run();
        
        if ((*itr)->isDead()) {
            itr = psList.erase(itr);
        } else {
            ++itr;
        }
        
        if (psList.empty()) {
            break;
        }
    }
}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){
    std::unique_ptr<ParticleSystem> tmp(new ParticleSystem(ofVec2f(x, y)));
    tmp->setup();
    psList.push_back(std::move(tmp));
}
#ifndef ParticleSystem_hpp
#define ParticleSystem_hpp

#include <stdio.h>
#include "ofMain.h"

#include "Particle.hpp"

#define MAX_PARTICLES (100)

class ParticleSystem {
public:
    ParticleSystem(ofVec2f org);
    ~ParticleSystem();
    void setOrigin(ofVec2f org);
    void applyForce(ofVec2f f);
    bool isDead();
    void setup();
    void update();
    void run();
private:
    bool isBreak();
    
    ofVec2f origin;
    ofVec2f velocity;
    ofVec2f acceleration;
    float radius;
    bool sysEnd;
    bool breakObj;
    int particleNum;
    std::vector<std::unique_ptr<Particle>> particles;
};
#endif /* ParticleSystem_hpp */
#include "ParticleSystem.hpp"



ParticleSystem::ParticleSystem(ofVec2f org)
{
    origin = org;
    radius = 4;
    sysEnd = false;
    particleNum = 0;
    velocity = ofVec2f(0, -10);
}


ParticleSystem::~ParticleSystem()
{
    
}


void ParticleSystem::setOrigin(ofVec2f org)
{
    origin = org;
}


void ParticleSystem::applyForce(ofVec2f f)
{
    if (isBreak()) {
        for (auto itr = particles.begin(); itr != particles.end(); ++itr) {
            (*itr)->applyForce(f);
        }
    } else {
        acceleration += f;
    }
}


bool ParticleSystem::isDead()
{
    return sysEnd;
}


bool ParticleSystem::isBreak()
{
    bool ret = false;
    
    if (velocity.y > 0) {
        ret = true;
    }
    return ret;
}


void ParticleSystem::setup()
{
    for (int i = 0; i < 4; i++) {
        ofVec2f v(1,0);
        for (int j = 0; j < MAX_PARTICLES; j++) {
            v.rotate(360 / MAX_PARTICLES * j);
            std::unique_ptr<Particle> tmp(new Particle(v * 0.5 * (i + 1)));
            particles.push_back(std::move(tmp));
        }
    }
}


void ParticleSystem::update()
{
    if (!isBreak()) {
        velocity += acceleration;
        origin += velocity;
        acceleration *= 0;
    
        for (std::unique_ptr<Particle> &p: particles) {
            p->setOrg(origin);
        }
    } else {
        for (std::unique_ptr<Particle> &p: particles) {
            p->update();
        }
    }
}


void ParticleSystem::run()
{
    if (!isBreak()) {
        ofSetColor(255);
        ofDrawCircle(origin.x, origin.y, radius);
    } else {
        auto itr = particles.begin();
        while (itr != particles.end()) {
            (*itr)->display();
            
            if ((*itr)->isDead()) {
                itr = particles.erase(itr);
            } else {
                ++itr;
            }
            
            if (particles.empty()) {
                sysEnd = true;
                break;
            }
        }
    }
}
#ifndef Particle_hpp
#define Particle_hpp

#include <stdio.h>
#include "ofMain.h"

class Particle {
public:
    Particle(ofVec2f v);
    ~Particle();
    
    void setOrg(ofVec2f l);
    void update();
    void display();
    bool isDead();
    void applyForce(ofVec2f f);
private:
    ofVec2f location;
    ofVec2f velocity;
    ofVec2f acceleration;
    int lifeSpan;
    ofColor c;
};
#endif /* Particle_hpp */
#include "Particle.hpp"




Particle::Particle(ofVec2f v)
{
    location = ofVec2f(0, 0);
    acceleration = ofVec2f(0, 0);
    velocity = v;
    lifeSpan = 128;
    c = ofColor(ofRandom(255), ofRandom(255), ofRandom(255));
}


Particle::~Particle()
{
    std::cout << "Delete Particle" << std::endl;
}


void Particle::setOrg(ofVec2f l)
{
    location = l;
}


void Particle::update()
{
    velocity += acceleration;
    location += velocity;
    lifeSpan -= 2;
    acceleration *= 0;
}


void Particle::display()
{
    c.a = lifeSpan * 2;
    ofSetColor(c);
    ofPushMatrix();
    ofTranslate(location.x, location.y);
    ofDrawCircle(0, 0, 5);
    ofPopMatrix();
}


bool Particle::isDead()
{
    bool dead = false;
    if (lifeSpan <= 0) {
        dead = true;
    }
    
    return dead;
}


void Particle::applyForce(ofVec2f f)
{
    acceleration += f;
}

Link to the reference page

ソースコードで使用したAPIの中から要点になりそうなものをいくつか選んでリストアップしました。

categoryAPI/Lib
c++std::vector
c++std::unique_ptr

Development environment

  • openframeworks 0.10.1
  • c++
  • macOS
  • Xcode