openFrameworks – パーティクルを動かしてみた
oFの勉強として、まずはパーティクルのアニメーションを実装してみました。
of-test01 from asialounge on Vimeo.
アニメーションは衝突+反射+バネ+摩擦のロジックで実装。
また、画面タップ時に、タップしたポイントへパーティクルが集まってくるインタラクションも実装。
#define NUM 100 //パーティクルの数 float posX[NUM]; //パーティクルのx座標 float posY[NUM]; //パーティクルのy座標 float speedX[NUM]; //パーティクルのx方向の移動量 float speedY[NUM]; //パーティクルのy方向の移動量 float radius[NUM]; //パーティクルの半径 float bounce = -1.0; //反射の係数 float friction = 0.95; //摩擦の係数 float spring = 0.4; //バネの係数 int red[NUM]; int green[NUM]; int blue[NUM]; bool isMousePressed; //-------------------------------------------------------------- void ofApp::setup() { ofSetBackgroundAuto(NO); ofBackground(0, 0, 0); ofSetFrameRate(60); ofSetCircleResolution(64); ofEnableSmoothing(); isMousePressed = NO; for (int i=0; i<NUM; i++) { posX[i] = ofRandom(0, ofGetWidth()); posY[i] = ofRandom(0, ofGetHeight()); speedX[i] = ofRandom(-4, 4); speedY[i] = ofRandom(-4, 4); radius[i] = ofRandom(5, 15); red[i] = ofRandom(0, 255); green[i] = ofRandom(0, 255); blue[i] = ofRandom(0, 255); } } //-------------------------------------------------------------- void ofApp::update() { for (int i=0; i<NUM; i++) { for (int j=i+1; j<NUM; j++) { float dx = posX[j] - posX[i]; float dy = posY[j] - posY[i]; float dist = sqrt(dx * dx + dy * dy); float minDist = radius[i] + radius[j]; if (dist < minDist) { float angle = atan2(dy, dx); float tx = posX[i] + cos(angle) * minDist; float ty = posY[i] + sin(angle) * minDist; float ax = (tx - posX[j]) * spring; float ay = (ty - posY[j]) * spring; speedX[i] -= ax; speedY[i] -= ay; speedX[j] += ax; speedY[j] += ay; speedX[i] *= friction; speedY[i] *= friction; speedX[j] *= friction; speedY[j] *= friction; } } } for (int i=0; i<NUM; i++) { if (isMousePressed) { speedX[i] = (mouseX - posX[i]) * 0.1; speedY[i] = (mouseY - posY[i]) * 0.1; } posX[i] += speedX[i]; posY[i] += speedY[i]; if (posX[i] - radius[i] < 0){ posX[i] = radius[i]; speedX[i] *= bounce; } else if (posX[i] + radius[i] > ofGetWidth()) { posX[i] = ofGetWidth() - radius[i]; speedX[i] *= bounce; } if (posY[i] - radius[i] < 0) { posY[i] = radius[i]; speedY[i] *= bounce; } if (posY[i] + radius[i] > ofGetHeight()) { posY[i] = ofGetHeight() - radius[i]; speedY[i] *= bounce; } } } //-------------------------------------------------------------- void ofApp::draw() { ofSetColor(0, 0, 0, 23); ofRect(0, 0, ofGetWidth(), ofGetHeight()); for (int i=0; i<NUM; i++) { ofSetColor(red[i], green[i], blue[i]); ofCircle(posX[i], posY[i], radius[i]); } } //-------------------------------------------------------------- void ofApp::touchUp(ofTouchEventArgs & touch) { isMousePressed = NO; for (int i=0; i<NUM; i++) { speedX[i] = ofRandom(-5, 5); speedY[i] = ofRandom(-5, 5); } }
次回は音や映像の取り込み方について勉強してみたいと思います。
TAG
エンジニア
意識 高丸 takamaru
Rubyについて日々勉強している新人エンジニアです。初心者向けRuby勉強会のレポートなどを投稿していきます。
TAG
- Android
- AWS
- Bitrise
- CodePipeline
- Firebase
- HTML
- iOS
- IoT
- JavaScript
- KPI
- Linux
- Mac
- Memcached
- MGRe
- MGReのゆるガチエンジニアブログ
- MySQL
- PHP
- PICK UP
- PR
- Python
- Ruby
- Ruby on Rails
- SEO
- Swift
- TIPS
- UI/UX
- VirtualBox
- Wantedly
- Windows
- アクセス解析
- イベントレポート
- エンジニアブログ
- ガジェット
- カスタマーサクセス
- サーバ技術
- サービス
- セキュリティ
- セミナー・展示会
- テクノロジー
- デザイン
- プレスリリース
- マーケティング施策
- マネジメント
- ラボ
- リーンスタートアップ
- 企画
- 会社紹介
- 会社紹介資料
- 勉強会
- 実績紹介
- 拡張性
- 採用
- 日常
- 書籍紹介
- 歓迎会
- 社内イベント
- 社員インタビュー
- 社長ブログ
- 視察
- 開発環境