More Related Content Similar to BNN CAMP vol.3 インタラクションデザインの現在―プログラミング初心者のためのopenFrameworks入門 2 Similar to BNN CAMP vol.3 インタラクションデザインの現在―プログラミング初心者のためのopenFrameworks入門 2 (20) More from Atsushi Tadokoro More from Atsushi Tadokoro (20) BNN CAMP vol.3 インタラクションデザインの現在―プログラミング初心者のためのopenFrameworks入門 24. サブルーチン (= 関数) とは
‣ プログラム中で意味や内容がまとまっている作業をひとつの手
続きとしたもの
‣ openFrameworks (つまり C++) では、サブルーチンのことを
「関数 (function)」と呼ぶのが一般的
‣ 関数を使用する利点
‣ 繰り返し現れる作業をまとめることができる
‣ プログラムの可読性の向上
‣ 保守性を高く保つ
6. C++ での関数の書きかた
‣ C++での関数の書き方
‣ 例えば、int型の数の二乗を計算する関数
‣ もし戻り値がない関数の場合、戻り値の型は「void」にする
戻り値の型 名前空間::関数名(引数1, 引数2, 引数3...){
関数の処理の内容
}
int testApp::poweroftwo(int a){
! return a * a;
}
16. 関数によるアニメーション:補完
‣ testApp.h に関数(手順)と変数(材料)を追加
#pragma once
#include "ofMain.h"
class testApp : public ofBaseApp{
!
public:
! void setup();
! void update();
! void draw();
...《中略》...
!
! ofPoint interpolateByPct(float pct);
!
! ofPoint startPos;
! ofPoint endPos;
! ofPoint currentPos;
! float pct;
!
};
追加
18. 関数によるアニメーション:補完
‣ testApp.cpp に関数(手順)の内容を記述
#include "testApp.h"
//--------------------------------------------------------------
void testApp::setup(){
! ofBackground(0, 0, 0);
! ofSetFrameRate(60);
! ofSetVerticalSync(true);
}
《中略》...
//--------------------------------------------------------------
ofPoint testApp::interpolateByPct(float _pct){
!
! ofPoint pos;
! pos.x = (1.0 - _pct) * startPos.x + (_pct) * endPos.x;
! pos.y = (1.0 - _pct) * startPos.y + (_pct) * endPos.y;
!
! return pos;
!
}
追加
20. 関数によるアニメーション:補完
‣ testApp.cpp に処理を追加
#include "testApp.h"
//--------------------------------------------------------------
void testApp::setup(){
! ofBackground(0, 0, 0);
! ofSetFrameRate(60);
! ofSetVerticalSync(true);
! startPos = ofPoint(10, 100);
! endPos = ofPoint(1000, 600);
! pct = 0;
}
//--------------------------------------------------------------
void testApp::update(){
! pct = pct + 0.01;
! currentPos = interpolateByPct(pct);
}
追加
追加
26. 関数によるアニメーション:補完
‣ testApp.cpp - update() に処理を追加
//--------------------------------------------------------------
void testApp::update(){
! pct = pct + 0.01;
!
! if (pct > 1.0) {
! ! pct = 0.0;
! }
!
! currentPos = interpolateByPct(pct);
}
追加
32. 高度な補完:加速と減速
‣ C++で指数計算をするには、powerf() 関数を使用する
‣ 例:10の2乗
‣ interpolateByPct 関数に、引数 shaper を追加
‣ pctを、shaperで指定した指数で乗算していく
powf(10.0, 2.0);
ofPoint testApp::interpolateByPct(float _pct, float _shaper){
! ofPoint pos;
! float shapedPct = powf(_pct, _shaper);
! pos.x = (1.0 - shapedPct) * startPos.x + shapedPct * endPos.x;
! pos.y = (1.0 - shapedPct) * startPos.y + shapedPct * endPos.y;
! return pos;
}
33. 高度な補完:加速と減速
‣ testApp.h :追加と修正
#pragma once
#include "ofMain.h"
class testApp : public ofBaseApp{
!
public:
! void setup();
! void update();
! void draw();
...《中略》...
! ofPoint interpolateByPct(float pct, float shaper);
!
! ofPoint startPos;
! ofPoint endPos;
! ofPoint currentPos;
! float pct;
! float shaper;
!
};
修正
追加
39. ‣ オブジェクト指向プログラミング
‣ Object Oriented Programming (OOP)
‣ オブジェクト指向でProcessingのプログラムを作る
‣ そもそもオブジェクト指向とは?
‣ 簡単なプログラムを、オブジェクト指向で書いてみる
‣ クラスの定義
‣ クラスの呼びだし
オブジェクト指向プログラミングとは?
46. ‣ オブジェクト指向プログラムのポイント:その3
‣ 必要のない情報は隠す (カプセル化)
‣ プログラムの実装全てを知る必要はない
‣ 必要なインターフェイス(接点)だけ見せて、あとは隠す
To invent programs, you need to be able to capture abstractions and ex
design. It’s the job of a programming language to help you do this. The
process of invention and design by letting you encode abstractions tha
It should let you make your ideas concrete in the code you write. Surf
the architecture of your program.
All programming languages provide devices that help express abstrac
are ways of grouping implementation details, hiding them, and giving
a common interface—much as a mechanical object separates its interfa
illustrated in “Interface and Implementation” .
Figure 2-1 Interface and Implementation
9
10
11
8
7
6
implementationinterface
インターフェイス 実装
OOP:ポイントその3
49. ‣ クラス
‣ クラスとは:オブジェクトの「型紙」
‣ クラスをインスタンス化 (実体化) することでインスタンス
(オブジェクト)となる
色
重さ(g)
味
リンゴ
(クラス)
実
が
な
る
成
長
す
る
落
ち
る
腐
る
赤
5.0
甘い
ふじ
(インスタンスオブジェクト)
実
が
な
る
成
長
す
る
落
ち
る
腐
る
青
4.0
すっぱい
青リンゴ
(インスタンスオブジェクト)
実
が
な
る
成
長
す
る
落
ち
る
腐
る
インスタンス化
クラス
50. ‣ いままで扱ってきた、testApp も一つのクラス
‣ メソッド - setup(), update(), draw() ...etc.
‣ プロパティ - testApp全体で使用する変数
testAppもクラス
クラス変数
setup()
update()
draw
()
exit()
testApp
65. クラスの実装
‣ MoveCircle.h - 円を描く際のレシピ!
#pragma once
#include "ofMain.h"
class MoveCircle {
!
public:
!
! void draw();
! ofPoint currentPos;
!
};
66. クラスの実装
‣ MoveCircle.h - 円を描く際のレシピ!
#pragma once
#include "ofMain.h"
class MoveCircle {
!
public:
!
! void draw();
! ofPoint currentPos;
!
};
インクルードガード
Buildの際に複数回読みこまれないためのしくみ
67. クラスの実装
‣ MoveCircle.h - 円を描く際のレシピ!
#pragma once
#include "ofMain.h"
class MoveCircle {
!
public:
!
! void draw();
!
! ofPoint currentPos;
!
};
oFの機能を使うためのライブラリを
必ず読み込む
68. クラスの実装
‣ MoveCircle.h - 円を描く際のレシピ!
#pragma once
#include "ofMain.h"
class MoveCircle {
!
public:
!
! void draw();
!
! ofPoint currentPos;
!
};
クラス名
69. クラスの実装
‣ MoveCircle.h - 円を描く際のレシピ!
#pragma once
#include "ofMain.h"
class MoveCircle {
!
public:
!
! void draw();
!
! ofPoint currentPos;
!
};
public: 以下は外部に公開される
70. クラスの実装
‣ MoveCircle.h - 円を描く際のレシピ!
#pragma once
#include "ofMain.h"
class MoveCircle {
!
public:
!
! void draw();
!
! ofPoint currentPos;
!
};
メソッド:draw() - 円を描く
71. クラスの実装
‣ MoveCircle.h - 円を描く際のレシピ!
#pragma once
#include "ofMain.h"
class MoveCircle {
!
public:
!
! void draw();
!
! ofPoint currentPos;
!
};
プロパティ:currentPos - 初期位置
72. クラスの実装
‣ MoveCircle.h - 円を描く際のレシピ!
#pragma once
#include "ofMain.h"
class MoveCircle {
!
public:
!
! void draw();
!
! ofPoint currentPos;
!
}; 最後に必ずセミコロンをつける
74. クラスの記述
‣ MoveCircle.cpp - 円を実際に描く手順
#include "MoveCircle.h"
void MoveCircle::draw() {
!
! ofFill();
! ofSetColor(31,127,255);
! ofCircle(currentPos.x, currentPos.y, 20,20);
!
}
必ずヘッダーファイルを読み込む
75. クラスの記述
‣ MoveCircle.cpp - 円を実際に描く手順
#include "MoveCircle.h"
void MoveCircle::draw() {
!
! ofFill();
! ofSetColor(31,127,255);
! ofCircle(currentPos.x, currentPos.y, 20,20);
!
}
戻り値 クラス名::関数名(引数)
クラス名を名前空間として使用している
他のクラスのdraw()関数との混同を避けている
76. クラスの記述
‣ MoveCircle.cpp - 円を実際に描く手順
#include "MoveCircle.h"
void MoveCircle::draw() {
!
! ofFill();
! ofSetColor(31,127,255);
! ofCircle(currentPos.x, currentPos.y, 20,20);
!
}
円を描画
78. クラスの実装
‣ testApp.h - MoveCircleをインスタンス化
#pragma once
#include "ofMain.h"
#include "MoveCircle.h"
class testApp : public ofBaseApp{
!
public:
! void setup();
! void update();
! void draw();
!
...《中略》...
!
! MoveCircle myCircle;
};
79. クラスの実装
‣ testApp.h - MoveCircleをインスタンス化
#pragma once
#include "ofMain.h"
#include "MoveCircle.h"
class testApp : public ofBaseApp{
!
public:
! void setup();
! void update();
! void draw();
!
...《中略》...
!
! MoveCircle myCircle;
};
MovieCircleのヘッダを読み込む
80. クラスの実装
‣ testApp.h - MoveCircleをインスタンス化
#pragma once
#include "ofMain.h"
#include "MoveCircle.h"
class testApp : public ofBaseApp{
!
public:
! void setup();
! void update();
! void draw();
!
...《中略》...
!
! MoveCircle myCircle;
};
MovieCircleをインスタンス化
82. クラスの実装
‣ testApp.cpp - MoveCircleで円を描く
#include "testApp.h"
//--------------------------------------------------------------
void testApp::setup(){
! ofSetFrameRate(60);
! ofSetVerticalSync(true);
! ofEnableAlphaBlending();
! ofBackground(0, 0, 0);
!
! myCircle.currentPos = ofPoint(400, 300);
}
//--------------------------------------------------------------
void testApp::update(){
}
//--------------------------------------------------------------
void testApp::draw(){
!
! myCircle.draw();
!
}
83. クラスの実装
‣ testApp.cpp - MoveCircleで円を描く
#include "testApp.h"
//--------------------------------------------------------------
void testApp::setup(){
! ofSetFrameRate(60);
! ofSetVerticalSync(true);
! ofEnableAlphaBlending();
! ofBackground(0, 0, 0);
!
! myCircle.currentPos = ofPoint(400, 300);
}
//--------------------------------------------------------------
void testApp::update(){
}
//--------------------------------------------------------------
void testApp::draw(){
!
! myCircle.draw();
!
}
初期位置の指定
84. クラスの実装
‣ testApp.cpp - MoveCircleで円を描く
#include "testApp.h"
//--------------------------------------------------------------
void testApp::setup(){
! ofSetFrameRate(60);
! ofSetVerticalSync(true);
! ofEnableAlphaBlending();
! ofBackground(0, 0, 0);
!
! myCircle.currentPos = ofPoint(400, 300);
}
//--------------------------------------------------------------
void testApp::update(){
}
//--------------------------------------------------------------
void testApp::draw(){
!
! myCircle.draw();
!
}
myCircleを使用して、円を描く
87. クラスの実装
‣ クラス名:MoveCircle
‣ プロパティ:
‣ ofPoint startPos - 開始位置
‣ ofPoint endPos - 終了位置
‣ ofPoint currentPos - 現在位置
‣ float pct - 現在の位置の割合(%)
‣ float shaper - 加速・減速の加減
‣ メソッド:
‣ void draw(); - 四角形の描画
‣ void update(); - 状態の更新
‣ float interpolateByPct(float myPct); - 位置の計算
88. クラスの実装
‣ クラス名:MoveCircle
‣ UMLクラス図で表現すると、こんな感じ
‣ この設計図の通りに、ヘッダーファイル(MoveCircle.h)と実装
ファイル(MoveCircle.cpp)を記述していく
+ draw():void
+ update():void
+ interpolateByPct():ofPoint
+ startPos:ofPoint
+ endPos:ofPoint
+ currentPos:ofPoint
+ pct:float
+ shaper:float
MoveCircle
89. クラスの実装
‣ MoveCircle.h - 円を描く際のレシピ!
#pragma once
#include "ofMain.h"
class MoveCircle {
!
public:
!
! void draw();
! void update();
! ofPoint interpolateByPct(float pct);
!
! ofPoint currentPos;
! ofPoint startPos;
! ofPoint endPos;
! float pct;
! float shaper;
};
90. クラスの実装
‣ MoveCircle.h - 円を描く際のレシピ!
#pragma once
#include "ofMain.h"
class MoveCircle {
!
public:
!
! void draw();
! void update();
! ofPoint interpolateByPct(float pct);
!
! ofPoint currentPos;
! ofPoint startPos;
! ofPoint endPos;
! float pct;
! float shaper;
};
メソッド
91. クラスの実装
‣ MoveCircle.h - 円を描く際のレシピ!
#pragma once
#include "ofMain.h"
class MoveCircle {
!
public:
!
! void draw();
! void update();
! ofPoint interpolateByPct(float pct);
!
! ofPoint currentPos;
! ofPoint startPos;
! ofPoint endPos;
! float pct;
! float shaper;
};
プロパティ
93. クラスの実装
‣ MoveCircle.cpp - 円を動かす
#include "MoveCircle.h"
void MoveCircle::draw() {
! ofFill();
! ofSetColor(31,127,255);
ofCircle(currentPos.x, currentPos.y, 20, 20);
!
}
void MoveCircle::update() {
! pct += 0.01f;
! if (pct > 1) {
! ! pct = 0;
! }
!
! currentPos = interpolateByPct(pct);
!
}
94. クラスの実装
‣ MoveCircle.cpp - 円を動かす
ofPoint MoveCircle::interpolateByPct(float _pct){
!
! float shapedPct = powf(_pct, shaper);
!
! ofPoint pos;
! pos.x = (1 - shapedPct) * startPos.x + shapedPct * endPos.x;
! pos.y = (1 - shapedPct) * startPos.y + shapedPct * endPos.y;
!
! return pos;
!
}
96. クラスの実装
‣ testApp.cpp - MoveCircleで円を動かす
#include "testApp.h"
//--------------------------------------------------------------
void testApp::setup(){
! ofSetFrameRate(60);
! ofBackground(0, 0, 0);
! myCircle.startPos = ofPoint(10, 400);
! myCircle.endPos = ofPoint(1000, 200);
! myCircle.shaper = 2.0;
}
//--------------------------------------------------------------
void testApp::update(){
! myCircle.update();
}
//--------------------------------------------------------------
void testApp::draw(){
! myCircle.draw();
}
...《後略》...
102. パーティクルクラスを設計する
‣ パーティクルクラスに必要な要素 (つづき)
‣ メソッド (動作)
‣ コンストラクタ(後述):Particle()
‣ デストラクタ(後述): Particle()
‣ 力のリセット:recetForce()
‣ 力を加える:addForce()
‣ 抵抗力(摩擦)を加える:addDampingForce()
‣ 状態の初期化:setInitialCondition()
‣ 位置更新:update()
‣ 描画:draw()
104. パーティクルクラスを設計する
‣ ParticleクラスのUMLクラス図
+ Particle()
+ ~Particle()
+ resetForce():void
+ addForce(float x, float y):void
+ addDumpingForce():void
+ setInitialCondition(float px, float py, float vx, float vy):void
+ update():void
+ draw():void
+ pos:ofVec2f
+ vel:ofVec2f
+ frc:ofVec2f
+ dumping:float
Particle
107. Particleクラスの実装
‣ ヘッダーファイル:Particle.h
#pragma once
#include "ofMain.h"
class Particle {
public:
!
! ofVec2f pos;
! ofVec2f vel;
! ofVec2f frc;
! float damping;
!
! Particle();
! ~Particle();
! void resetForce();
! void addForce(float x, float y);
! void addDampingForce();
! void setInitialCondition(float px, float py, float vx, float vy);
! void update();
! void draw();
!
};
111. testAppクラスの実装
‣ ヘッダーファイル:testApp.h
#pragma once
#include "ofMain.h"
#include "Particle.h"
class testApp : public ofSimpleApp{
!
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();
//クラスParticleをインスタンス化
Particle p;
};
112. testAppクラスの実装
‣ 実装ファイル:testApp.cpp
#include "testApp.h"
void testApp::setup(){!
! ofSetVerticalSync(true);
! ofSetFrameRate(60);
! ofBackground(0, 0, 0);
! p.setInitialCondition(ofGetWidth()/2, ofGetHeight()/2,
ofRandom(-10,10), ofRandom(-10,10));
}
void testApp::update(){
! p.resetForce();
! p.addDampingForce();
! p.update();
}
void testApp::draw(){
! ofSetColor(255, 255, 255);
! p.draw();
}
...《後略》...
126. void testApp::update(){
! p.resetForce();
! p.addForce(0, 0.1);
! p.addDampingForce();
! p.update();
}
複数のパーティクルを同時に動かす(Array版)
‣ update() の部分は、配列とfor文でこうなる
void testApp::update(){
! for (int i = 0; i < NUM; i++) {
! ! p[i].resetForce();
! ! p[i].addForce(0, 0.1);
! ! p[i].addDampingForce();
! ! p[i].update();
! }
}
127. void testApp::draw(){
! ofSetColor(255, 255, 255);
! p.draw();
}
複数のパーティクルを同時に動かす(Array版)
‣ draw() も同様に
void testApp::draw(){
! ofSetColor(255, 255, 255);
! for (int i = 0; i < NUM; i++) {
! ! p[i].draw();
! }
}
128. 複数のパーティクルを同時に動かす(Array版)
‣ ヘッダーファイル:testApp.h
#pragma once
#include "ofMain.h"
#include "Particle.h"
#define NUM 100
class testApp : public ofSimpleApp{
!
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();
//クラスParticleの配列 (NUM個)
Particle p[NUM];
};
129. 複数のパーティクルを同時に動かす(Array版)
‣ 実装ファイル:testApp.cpp
#include "testApp.h"
void testApp::setup(){!
! ofSetVerticalSync(true);
! ofSetFrameRate(60);
! ofBackground(0, 0, 0);
}
void testApp::update(){
for (int i = 0; i < NUM; i++) {
p[i].resetForce();
p[i].addForce(0, 0.1);
p[i].addDampingForce();
p[i].update();
}
}
void testApp::draw(){
! ofSetColor(255, 255, 255);
for (int i = 0; i < NUM; i++) {
p[i].draw();
}
}
134. 複数のパーティクルを動かす(vector版)
‣ ヘッダーファイル:testApp.h
#pragma once
#include "ofMain.h"
#include "Particle.h"
#define NUM 100
class testApp : public ofSimpleApp{
!
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();
//クラスParticleの動的配列particles
vector <Particle> particles;
};
135. 複数のパーティクルを動かす(vector版)
‣ 実装ファイル:testApp.cpp
#include "testApp.h"
void testApp::setup(){!
! ofSetVerticalSync(true);
! ofSetFrameRate(60);
! ofBackground(0, 0, 0);
}
void testApp::update(){
for (int i = 0; i < particles.size(); i++) {
particles[i].resetForce();
particles[i].addForce(0, 0.1);
particles[i].addDampingForce();
particles[i].update();
}
}
void testApp::draw(){
! ofSetColor(255, 255, 255);
for (int i = 0; i < particles.size(); i++) {
particles[i].draw();
}
}
139. 応用編:パーティクルをどんどん追加
‣ ヘッダーファイル:testApp.h
#pragma once
#include "ofMain.h"
#include "Particle.h"
class testApp : public ofSimpleApp{
!
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();
//クラスParticleの動的配列particles
vector <Particle> particles;
};
140. 応用編:パーティクルをどんどん追加
‣ 実装ファイル:testApp.cpp
#include "testApp.h"
void testApp::setup(){!
! ofSetVerticalSync(true);
! ofSetFrameRate(60);
! ofBackground(0, 0, 0);
}
void testApp::update(){
for (int i = 0; i < particles.size(); i++) {
particles[i].resetForce();
particles[i].addDampingForce();
particles[i].update();
}
}
void testApp::draw(){
! ofSetColor(255, 255, 255);
! //画面左上にメッセージを表示
! string message = "current particle num = " + ofToString(particles.size(),0);
! ofDrawBitmapString(message, 20, 20);
for (int i = 0; i < particles.size(); i++) {
particles[i].draw();
}
}
141. 応用編:パーティクルをどんどん追加
‣ 実装ファイル:testApp.cpp (つづき)
void testApp::keyPressed (int key){
! //'c'キーでパーティクルを全部消去
! if (key == 'c') {
! ! particles.clear();
! }
! //'f'キーでフルスクリーン表示
! if (key == 'f') {
! ! ofToggleFullscreen();
! }
}
...《中略》...
void testApp::mouseDragged(int x, int y, int button){
! //マウスをドラッグするとパーティクルが追加される
! Particle myParticle;
! float vx = ofRandom(-3, 3);
! float vy = ofRandom(-3, 3);
! myParticle.setInitialCondition(x, y, vx, vy);
! particles.push_back(myParticle);
}
...《後略》...
145. 実習:パーティクルをつかって表現
‣ 実装ファイル:testApp.cpp (drawのみ書き換え)
...《中略》...
void testApp::draw(){
! ofSetColor(255, 255, 255);
! //画面左上にメッセージを表示
! string message = "current particle num = "
! + ofToString(particles.size(),0);
! ofDrawBitmapString(message, 20, 20);
!
! ofNoFill();
! ofBeginShape();
! for (int i = 0; i < particles.size(); i++){
! ! ofCurveVertex(particles[i].pos.x, particles[i].pos.y);
! }
! ofEndShape();
}
...《後略》...
148. 実習:パーティクルをつかって表現
‣ ヘッダーファイル:testApp.h
#pragma once
#include "ofMain.h"
#include "Particle.h"
class testApp : public ofSimpleApp{
!
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();
//クラスParticleの動的配列particles
vector <Particle> particles;
! //ビットマップ画像
! ofImage img;
};
149. 実習:パーティクルをつかって表現
‣ 実装ファイル:testApp.cpp (1 / 3)
#include "testApp.h"
void testApp::setup(){!
! ofSetVerticalSync(true);
! ofSetFrameRate(60);
! ofBackground(0, 0, 0);
! ofEnableBlendMode(OF_BLENDMODE_ADD);
! //イメージファイルを読込み
! img.loadImage("particle32.png");
}
void testApp::update(){
for (int i = 0; i < particles.size(); i++) {
particles[i].resetForce();
particles[i].addDampingForce();
particles[i].update();
}
}
150. 実習:パーティクルをつかって表現
‣ 実装ファイル:testApp.cpp (2 / 3)
void testApp::draw(){
! //画面左上にメッセージを表示
! ofSetColor(255, 255, 255);
! string message = "current particle num = " + ofToString(particles.size(),0);
! ofDrawBitmapString(message, 20, 20);
! //パーティクルの位置に画像を表示
! for (int i = 0; i < particles.size(); i++){
! ! float posx = particles[i].pos.x - 16;
! ! float posy = particles[i].pos.y - 16;
! ! img.draw(posx, posy);
! }
}
void testApp::keyPressed (int key){
! //'c'キーでパーティクルを全部消去
! if (key == 'c') {
! ! particles.clear();
! }
! //'f'キーでフルスクリーン表示
! if (key == 'f') {
! ! ofToggleFullscreen();
! }
}
151. 実習:パーティクルをつかって表現
‣ 実装ファイル:testApp.cpp (3 / 3)
【中略】
void testApp::mouseDragged(int x, int y, int button){
! //マウスをドラッグするとパーティクルが追加される
! Particle myParticle;
! float vx = ofRandom(-1, 1);
! float vy = ofRandom(-1, 1);
! myParticle.setInitialCondition(x, y, vx, vy);
! particles.push_back(myParticle);
}
【後略】