openFrameworksとC++を使って始めてコードを書いてみました。恥ずかしいけど、公開しておきます。C++に慣れている人には何の得もない記事です。初心者なのでアドバイスあれば何でもおねがいします!
作ったもの
作ったものはこちらです(コードは最後の方に貼ります)。
「Beyond Interaction[改訂第2版] -クリエイティブ・コーディングのためのopenFrameworks実践ガイド」 の中にあるサンプルコードを基にしています。1,000個の円を画面に表示させて、画面の淵にぶつかったらバウンドさせています。
やったことと課題
平べったく書かれていた円の描画コードは同じことの繰り返しなので、オブジェクトにまとめてみました。円の情報をクラスにしてポインタを使って配列に入れて、それを基に描画しています。まぁ、これはそのうち解決する問題ですが、初めてということで配列の動的な個数変更ができればさらによかった。今は定数です。あと、ofMain
をCircleクラスでincludeしているのは微妙かもしれないと思った。描画処理はofAppの方で書いた方がわかりやすいかな。
speedXとspeedYなどはstructにした方がよさそう。x, yやred, green, blueも同じ。
まぁ、他にもいろいろあるけれど、とりあえずC++で動くコードを書くことができてよかった。
コード
openFrameworksは0.9.3です。
_main.cpp_
#include "ofMain.h"
#include "ofApp.h"
//========================================================================
int main( ){
ofSetupOpenGL(600, 480,OF\_WINDOW); //setup the GL context
// this kicks off the running of my app
// can be OF\_WINDOW or OF\_FULLSCREEN
// pass in width and height too:
ofRunApp(new ofApp());
}
_ofApp.h_
#pragma once
#include "ofMain.h"
#include "Circle.hpp"
#define NUM 1000
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 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:
bool mouse\_pressed;
float gravity;
float friction;
Circle \*circles\[NUM\];
};
_ofApp.cpp_
#include "ofApp.h"
//--------------------------------------------------------------
void ofApp::setup(){
ofSetBackgroundAuto(false);
ofBackground(0, 0, 0);
ofSetFrameRate(60);
ofSetCircleResolution(64);
ofEnableAlphaBlending();
mouse\_pressed = false;
gravity = 0.1;
friction = 0.999;
for (int i = 0; i < NUM; i++) {
circles\[i\] = new Circle();
}
}
//--------------------------------------------------------------
void ofApp::update(){
for (int i = 0; i < NUM; i++) { circles\[i\]->update(mouse\_pressed, mouseX, mouseY, gravity, friction);
}
}
//--------------------------------------------------------------
void ofApp::draw(){
ofSetColor(0, 0, 0, 100);
ofDrawRectangle(0, 0, ofGetWidth(), ofGetHeight());
for (int i= 0; i < NUM; i++) { circles\[i\]->draw();
}
}
//--------------------------------------------------------------
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++) { circles\[i\]->randomiseSpeed();
}
}
_Circle.h_
#ifndef Circle\_hpp
#define Circle\_hpp
class Circle {
public:
float x;
float y;
float speedX;
float speedY;
float radius;
int red;
int green;
int blue;
Circle();
void randomiseSpeed();
void update(bool mousePressed, float mouseX, float mouseY, float gravity, float friction);
void draw();
};
#endif /\* Circle\_hpp \*/
_Circle.cpp_
#include "Circle.hpp"
#include "ofMain.h"
Circle::Circle() {
x = ofGetWidth() / 2;
y = ofGetHours() / 2;
speedX = ofRandom(-10, 10);
speedY = ofRandom(-10, 10);
radius = ofRandom(1, 10);
red = ofRandom(0, 255);
green = ofRandom(0, 255);
blue = ofRandom(0, 255);
}
void::Circle::randomiseSpeed() {
speedX = ofRandom(-10, 10);
speedY = ofRandom(-10, 10);
}
void::Circle::draw() {
ofSetColor(red, green, blue, 127);
ofDrawCircle(x, y, radius);
}
void::Circle::update(bool mousePressed, float mouseX, float mouseY, float gravity, float friction) {
if (mousePressed) {
speedX = (mouseX - x) / 8.0;
speedY = (mouseY - y) / 8.0;
}
speedX = speedX \* friction;
speedY = speedY \* friction;
speedY = speedY + gravity;
x = x + speedX;
y = y + speedY;
if (x < 0) { x = 0; speedX \*= -1.0; } if (x > ofGetWidth()) {
x = ofGetWidth();
speedX \*= -1.0;
}
if (y < 0) { y = 0; speedY \*= -1.0; } if (y > ofGetHeight()) {
y = ofGetHeight();
speedY \*= -1.0;
}
}