時計と連動したアニメーションをOpenframeworksで制作する

2014.05.21 水曜日 23:46:11

今回は時計の秒針と連動したアニメーションをOpenframeworksで作成してみます。

スクリーンショット 2014-05-21 23.41.34

こんな感じです。

必要なアドオンはありません。
今回も新規プロジェクトを作成し、「ofApp.h」「ofApp.cpp」それぞれを編集します。

ofApp.h

#pragma once

#include "ofMain.h"
#include "ofxSyphon.h"

class ofApp : public ofBaseApp{

	public:
		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 windowResized(int w, int h);
		void dragEvent(ofDragInfo dragInfo);
		void gotMessage(ofMessage msg);
	
    /////syphon▼
	float 	counter;
	bool	bSmooth;
	
    ofTexture tex;
    
	ofxSyphonServer mainOutputSyphonServer;
	ofxSyphonServer individualTextureSyphonServer;
	
	ofxSyphonClient mClient;

};

ofApp.cpp

#include "ofApp.h"

#define NUM 200 //円の数を表す定数NUMを1000と定義

float loc_x[NUM]; //円のx座標
float loc_y[NUM]; //円のy座標
float speed_x[NUM]; //x軸方向のスピード
float speed_y[NUM]; //y軸方向のスピード
float radius[NUM]; //円の半径
int red[NUM]; //Red成分
int green[NUM]; //Green成分
int blue[NUM]; //Blue成分
bool mouse_pressed; //マウスはクリックされているか?
float gravity;
float friction;

int s;//秒
int s_num;//指標

int m;//分分
int m_num;//分指標


//--------------------------------------------------------------
void ofApp::setup(){
    ofSetBackgroundAuto(false);
    ofBackground(0, 0, 0); //背景色の設定
    ofSetFrameRate(60); //フレームレートの設定
    ofSetCircleResolution(64); //円の解像度設定
    ofEnableAlphaBlending(); //アルファチャンネルを有効に
    mouse_pressed = false; //マウス状態を「クリックされていない」に
    ofEnableSmoothing();//スムーズに

    gravity = 0.1; //重力
    friction = 0.85;
    
    
    //NUMの数だけ初期値の生成を繰り返す
    for(int i = 0; i < NUM; i++){
        loc_x[i] = 500; //円のx座標初期位置
        loc_y[i] = 10; //円のy座標初期位置
        speed_x[i] = ofRandom(-10, 10); //x軸方向スピード初期値
        speed_y[i] = ofRandom(-10, 10); //y軸方向スピード初期値
        radius[i] = ofRandom(1, 10); //円の半径を設定
        red[i] = ofRandom(0, 255); //Red成分を設定
        green[i] = ofRandom(0, 255); //Green成分を設定
        blue[i] = ofRandom(0, 255); //Blue成分を設定
    }

    
    
    ///////////////▼syphon▼//////////////
	mainOutputSyphonServer.setName("Screen Output");
	individualTextureSyphonServer.setName("Texture Output");
    
	mClient.setup();
    
    //using Syphon app Simple Server, found at http://syphon.v002.info/
    mClient.set("","Simple Server");
	
    tex.allocate(200, 100, GL_RGBA);
    
	ofSetFrameRate(60); // if vertical sync is off, we can go a bit fast... this caps the framerate at 60fps.
    
    ///////////////▲syphon▲//////////////
    

}

//--------------------------------------------------------------
void ofApp::update(){
    //NUMの数だけ座標の更新を繰り返す
    for(int i = 0; i < NUM; i++){
        
        //マウスの現在位置からスピードを//もしマウスがクリックされていたらマウスに集ってくる
        if(mouse_pressed){
            //マウスの現在位置から円のスピードを再計算
            speed_x[i] = (mouseX - loc_x[i]) / 8.0; //マウスのx座標と円のx座標の距離の1/8だけ接近
            speed_y[i] = (mouseY - loc_y[i]) / 8.0;
        }
        
        speed_x[i] = speed_x[i] * friction;
        speed_y[i] = speed_y[i] * friction;
        
        loc_x[i] = loc_x[i] + speed_x[i]; //円のx座標を更新
        loc_y[i] = loc_y[i] + speed_y[i]; //円のy座標を更新
        
        //円の跳ね返り条件
        if(loc_x[i] < 0){
            loc_x[i] = 0;
            speed_x[i] = speed_x[i] * -1.0;
        }
        if(loc_x[i] > ofGetWidth()-600){
            loc_x[i] = ofGetWidth()-600;
            speed_x[i] = speed_x[i] * -1.0;
        }
        if(loc_y[i] < 0){
            loc_y[i] = 0;
            speed_y[i] = speed_y[i] * -1.0;
        }
        if(loc_y[i] > ofGetHeight()){
            loc_y[i] = ofGetHeight();
            speed_y[i] = speed_y[i] * -1.0;
        }
    }
}

//--------------------------------------------------------------
void ofApp::draw(){
    //秒の取得
    int ms = ofGetElapsedTimeMillis() % 1000;
    //秒の取得
    s = ofGetSeconds();
    //分の取得
    m = ofGetMinutes() + (s/60.0);
    //時の取得
   float h = ofGetHours()%12 + (m/60);
 

    //全画面を半透明の黒でフェード
    ofSetColor(0, 0, 0, 23);
    ofRect(0, 0, ofGetWidth(), ofGetHeight());
    
    //NUMの数だけ円を描画する
    for(int i = 0; i < NUM; i++){
        ofSetColor(red[i], green[i], blue[i], 127); //描画色の設定
        ofCircle(loc_x[i], loc_y[i], radius[i]); //円1を描画
    }

    if(!(s_num==s)){
        int col1 =ofRandom(0, 255);
        int col2 =ofRandom(0, 255);
        int col3 =ofRandom(0, 255);
        
        //円のスピードを再初期化
        for(int i = 0; i < NUM; i++){
            speed_x[i] = ofRandom(-20, 20); //x軸方向スピード初期値
            speed_y[i] = ofRandom(-20, 20); //y軸方向スピード初期値
            
            red[i] = col1; //Red成分を設定
            green[i] = col2; //Green成分を設定
            blue[i] = col3; //Blue成分を設定
           radius[i] = ofRandom(1, 20); //円の半径を設定
            
        }
        s_num = s;
    }
    
    if(!(m_num==m)){
        //マウスの現在位置から円のスピードを再計算
          for(int i = 0; i < NUM; i++){
        speed_x[i] = (500 - loc_x[i]) / 6.0; //マウスのx座標と円のx座標の距離の1/8だけ接近
        speed_y[i] = (10 - loc_y[i]) / 6.0;
              
              red[i] = ofRandom(0, 255); //Red成分を設定
              green[i] = ofRandom(0, 255); //Green成分を設定
              blue[i] = ofRandom(0, 255); //Blue成分を設定
          }
        m_num=m;
    }
    
   printf("hage: %d\n", s_num);
    
    
    //時計の大きさ
    float clockSize = 200;
    
    //座標全体を中心に移動
    ofTranslate(1390, ofGetHeight()/2);
    
    //時計の背景
   // ofSetColor(255, 255, 255);
  //  ofFill();
    
    //分の目盛を描く
    for (int i=0; i<60; i++) {
        ofRotateZ(6);
        ofCircle(clockSize, 0, 2);
    }
    
    //時の目盛を描く
    for (int i=0; i<12; i++) {
        ofRotateZ(30);
        ofCircle(clockSize, 0, 4);
    }
    
    ofSetColor(255, 255, 255);
    
    //秒針
    ofPushMatrix();
    ofRotateZ(s*6.0);
    ofSetLineWidth(1);
    ofLine(0, 0, 0, -clockSize);
    ofPopMatrix();
    
    //分
    ofPushMatrix();
    ofRotateZ(m*6.0);
    ofSetLineWidth(2);
    ofLine(0, 0, 0, -clockSize);
    ofPopMatrix();
    
    //時針
    ofPushMatrix();
    ofRotateZ(h*30.0);
    ofSetLineWidth(4);
    ofLine(0, 0, 0, -clockSize*0.75);
    ofPopMatrix();
    
    
    
    ///////////////▼syphon▼//////////////
    
	// Syphon Stuff
    
    mClient.draw(50, 50);
    
	mainOutputSyphonServer.publishScreen();
    
    individualTextureSyphonServer.publishTexture(&tex);
    ///////////////▲syphon▲//////////////
    
    
    
}

//--------------------------------------------------------------
void ofApp::keyPressed(int key){

}

//--------------------------------------------------------------
void ofApp::keyReleased(int key){

}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y ){

}

//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){
    mouse_pressed = true; //マウスが押されている状態に
}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){
    mouse_pressed = false; //マウスが押されていない状態に
    
    //円のスピードを再初期化
    for(int i = 0; i < NUM; i++){
        speed_x[i] = ofRandom(-10, 10); //x軸方向スピード初期値
        speed_y[i] = ofRandom(-10, 10); //y軸方向スピード初期値
    }

}
//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){ 

}

以上です。
時間を秒単位で取得して、それを秒ごとに円を動かして描写しています。

スクリーンショット 2014-05-21 23.41.41

時間とアニメーションの連携もopenframeworksであれば簡単にできるので是非試してみてはいかがでしょうか。

Category:WORKS     Tag:animation clock WORKS 時計
Our Business
最近の記事
人気記事
Our Project
comming soon