物理エンジン Box2D
提供:kuhalaboWiki
				
								
				(版間での差分)
				
																
				
				
								
				 (→エラー対策)  | 
			 (→動的配列でマウスクリックで生成)  | 
			||
| 74行: | 74行: | ||
'''setPhysics()'''で力学属性を設定するが、これを省略すると、場所が固定された障壁のような働きをする。  | '''setPhysics()'''で力学属性を設定するが、これを省略すると、場所が固定された障壁のような働きをする。  | ||
| − | ==   | + | == 動的配列で動的に生成 ==  | 
;ofApp.h  | ;ofApp.h  | ||
| − | *Box2Dでは、動的配列に'''vector'''ではなく、'''vector <ofPtr  >'''を使う  | + | * Box2Dでは、動的配列に'''vector'''ではなく、'''vector <ofPtr  >'''を使う  | 
| + | * キーcを押すと、円が生成され、キーbを押すと、四角が生成される。  | ||
<pre>  | <pre>  | ||
	    ofxBox2d box2d; // Box2Dの世界  | 	    ofxBox2d box2d; // Box2Dの世界  | ||
	    ofxBox2dCircle circle;  // 円  | 	    ofxBox2dCircle circle;  // 円  | ||
| + | 	    ofxBox2dRect box;  // 四角  | ||
| + | 	    ofxBox2dRect wall;  // 壁  | ||
| − | 	    vector <ofPtr <ofxBox2dCircle> > circles;    //   | + | 	    vector <ofPtr <ofxBox2dCircle> > circles;    // Box2d円の動的配列  | 
| − | 	    vector <ofPtr <ofxBox2dRect> > boxes;        //   | + | 	    vector <ofPtr <ofxBox2dRect> > boxes;        // Box2d四角の動的配列  | 
</pre>  | </pre>  | ||
| 92行: | 95行: | ||
     ofBackground(0);  |      ofBackground(0);  | ||
| − |      //   | + |      // Box2Dの世界の設定  | 
     box2d.init();               // 初期化  |      box2d.init();               // 初期化  | ||
| − |      box2d.setGravity(0,   | + |      box2d.setGravity(0, 1);    // 重力 (方向、強さ)  | 
     box2d.createBounds();       // 画面の周囲に壁を作成  |      box2d.createBounds();       // 画面の周囲に壁を作成  | ||
| − |      box2d.setFPS(30.0);         //   | + |      box2d.setFPS(30.0);         // box2Dの世界でのFPS  | 
     box2d.registerGrabbing();   // 物体をつかめるようにする  |      box2d.registerGrabbing();   // 物体をつかめるようにする  | ||
| − | + |      circle.setPhysics(2.0, 0.9, 1.5);  // 円の物理パラメータを設定 (重さ、反発係数、摩擦係数)  | |
| − |      circle.setPhysics(2.0, 0.9, 1.5);  // 円の物理パラメータを設定 (  | + | |
     circle.setup(box2d.getWorld(), ofGetWidth() / 2.0, 100, 40); // 円を物理世界に追く  |      circle.setup(box2d.getWorld(), ofGetWidth() / 2.0, 100, 40); // 円を物理世界に追く  | ||
| + |     box.setPhysics(2.0, 0.9, 1.5);  // 四角の物理パラメータを設定 (重さ、反発係数、摩擦係数)  | ||
| + |     box.setup(box2d.getWorld(), ofGetWidth() / 3.0, 200, 100, 40); // 四角を物理世界に追く  | ||
| + | 	wall.setup(box2d.getWorld(), ofGetWidth() / 2.0, 500, 300, 10); // 壁を物理世界に追く。物理パラメータはない  | ||
}  | }  | ||
| 111行: | 116行: | ||
//--------------------------------------------------------------  | //--------------------------------------------------------------  | ||
void ofApp::draw(){  | void ofApp::draw(){  | ||
| − | + |     ofSetColor(0, 127, 255);  | |
| − | + | 	circle.draw();           // 円の描画  | |
| − | + |     ofSetColor(255, 127, 0);  | |
| + | 	box.draw();              // 四角の描画  | ||
| + |     ofSetColor(127, 255, 0);  | ||
| + | 	wall.draw();              // 壁の描画  | ||
	for(int i=0; i<circles.size(); i++){  | 	for(int i=0; i<circles.size(); i++){  | ||
| − | + | 		ofFill();  | |
	    ofSetColor(0, 127, 255);  | 	    ofSetColor(0, 127, 255);  | ||
| − | + | 		circles[i].get()->draw();              // 円の描画  | |
	}  | 	}  | ||
	for(int i=0; i<boxes.size(); i++){  | 	for(int i=0; i<boxes.size(); i++){  | ||
| − | + | 		ofFill();  | |
	    ofSetColor(255, 127, 0);  | 	    ofSetColor(255, 127, 0);  | ||
| − | + | 		boxes[i].get()->draw();              // 円の描画  | |
	}  | 	}  | ||
| + | |||
}  | }  | ||
| + | |||
//--------------------------------------------------------------  | //--------------------------------------------------------------  | ||
| − | void ofApp::  | + | void ofApp::keyPressed(int key){  | 
| − | + | }  | |
| − | + | ||
| − | + | //--------------------------------------------------------------  | |
| − | + | void ofApp::keyReleased(int key){  | |
| + | 	if( key == 'c' ){ // キーcを押すと、円が生成される  | ||
| + | 		float r = ofRandom(10,30);  | ||
		circles.push_back(ofPtr<ofxBox2dCircle>(new ofxBox2dCircle));  | 		circles.push_back(ofPtr<ofxBox2dCircle>(new ofxBox2dCircle));  | ||
		circles.back().get()->setPhysics(3.0, 0.99, 0.1);  | 		circles.back().get()->setPhysics(3.0, 0.99, 0.1);  | ||
| − | 		circles.back().get()->setup(box2d.getWorld(),   | + | 		circles.back().get()->setup(box2d.getWorld(), ofRandom(ofGetWidth()), ofRandom(ofGetHeight()), r);  | 
| − | 	}  | + | 		circles.back().get()->setVelocity(ofRandom(-5,5),ofRandom(-5,5)); //初期速度の設定  | 
| + | 	}  | ||
| + | 	if( key == 'b' ){// キーbを押すと、四角が生成される  | ||
| + | 		float w = ofRandom(10,30);  | ||
| + | 		float h = ofRandom(10,30);  | ||
		boxes.push_back(ofPtr<ofxBox2dRect>(new ofxBox2dRect));  | 		boxes.push_back(ofPtr<ofxBox2dRect>(new ofxBox2dRect));  | ||
		boxes.back().get()->setPhysics(3.0, 0.99, 0.1);  | 		boxes.back().get()->setPhysics(3.0, 0.99, 0.1);  | ||
| − | 		boxes.back().get()->setup(box2d.getWorld(),   | + | 		boxes.back().get()->setup(box2d.getWorld(), ofRandom(ofGetWidth()), ofRandom(ofGetHeight()), w, h);  | 
| + | 		boxes.back().get()->setVelocity(ofRandom(-5,5),ofRandom(-5,5));//初期速度の設定  | ||
	}  | 	}  | ||
| − | + | ||
| + | }  | ||
</pre>  | </pre>  | ||
2014年11月25日 (火) 05:00時点における版
目次 | 
入手
https://github.com/vanderlin/ofxBox2d
- zipボタンをクリックし、ファイル一式をダンロード
 - 作成された「ofxBox2D-master」フォルダーを「ofxBox2D」に名称変更し、addonsフォルダーに移動する。
 - projectGeneratorでBox2Dアドオンを選択する。
 
エラー対策
Visual Studioのバージョンによっては、Box2Dのコンパイル時に以下のエラーの出ることがあります。
エラー 4 error C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. f:\of_v0.8.4_vs_release\addons\ofxbox2d\libs\triangle\triangle_impl.hpp
そんなときは、以下の設定変更で解決します。
- プロジェクトのプロパティ
- 構成プロパティ―「C/C++」―「すべてのオプション」-「SDLチェック」を「いいえ」にする。
 
 
単体の円と四角
- ofApp.h
 
ヘッダーの初めにBox2Dのヘッダーをインクルードする。
#include "ofxBox2d.h"
Box2dの変数を宣言する。
ofxBox2d box2d; // Box2Dの世界 ofxBox2dCircle circle; // 円 ofxBox2dRect box; // 四角 ofxBox2dRect wall; // 壁
- ofApp.cpp
 
void ofApp::setup(){
    ofSetFrameRate(60);
    ofBackground(0);
    
    // Box2Dの世界の設定
    box2d.init();               // 初期化
    box2d.setGravity(0, 1);    // 重力 (方向、強さ)
    box2d.createBounds();       // 画面の周囲に壁を作成
    box2d.setFPS(30.0);         // box2Dの世界でのFPS
    box2d.registerGrabbing();   // 物体をつかめるようにする
    circle.setPhysics(2.0, 0.9, 1.5);  // 円の物理パラメータを設定 (重さ、反発係数、摩擦係数)
    circle.setup(box2d.getWorld(), ofGetWidth() / 2.0, 100, 40); // 円を物理世界に追く
    box.setPhysics(2.0, 0.9, 1.5);  // 四角の物理パラメータを設定 (重さ、反発係数、摩擦係数)
    box.setup(box2d.getWorld(), ofGetWidth() / 3.0, 200, 100, 40); // 四角を物理世界に追く
    wall.setup(box2d.getWorld(), ofGetWidth() / 2.0, 500, 300, 10); // 壁を物理世界に追く。物理パラメータはない
}
//--------------------------------------------------------------
void ofApp::update(){
    box2d.update();             // box2Dの更新
}
//--------------------------------------------------------------
void ofApp::draw(){
    ofSetColor(0, 127, 255);
    circle.draw();           // 円の描画
    ofSetColor(255, 127, 0);
    box.draw();              // 四角の描画
    ofSetColor(127, 255, 0);
    wall.draw();              // 壁の描画
}
setPhysics()で力学属性を設定するが、これを省略すると、場所が固定された障壁のような働きをする。
動的配列で動的に生成
- ofApp.h
 
- Box2Dでは、動的配列にvectorではなく、vector <ofPtr >を使う
 - キーcを押すと、円が生成され、キーbを押すと、四角が生成される。
 
ofxBox2d box2d; // Box2Dの世界 ofxBox2dCircle circle; // 円 ofxBox2dRect box; // 四角 ofxBox2dRect wall; // 壁 vector <ofPtr <ofxBox2dCircle> > circles; // Box2d円の動的配列 vector <ofPtr <ofxBox2dRect> > boxes; // Box2d四角の動的配列
- ofApp.cpp
 
void ofApp::setup(){
    ofSetFrameRate(60);
    ofBackground(0);
    
    // Box2Dの世界の設定
    box2d.init();               // 初期化
    box2d.setGravity(0, 1);    // 重力 (方向、強さ)
    box2d.createBounds();       // 画面の周囲に壁を作成
    box2d.setFPS(30.0);         // box2Dの世界でのFPS
    box2d.registerGrabbing();   // 物体をつかめるようにする
    circle.setPhysics(2.0, 0.9, 1.5);  // 円の物理パラメータを設定 (重さ、反発係数、摩擦係数)
    circle.setup(box2d.getWorld(), ofGetWidth() / 2.0, 100, 40); // 円を物理世界に追く
    box.setPhysics(2.0, 0.9, 1.5);  // 四角の物理パラメータを設定 (重さ、反発係数、摩擦係数)
    box.setup(box2d.getWorld(), ofGetWidth() / 3.0, 200, 100, 40); // 四角を物理世界に追く
	wall.setup(box2d.getWorld(), ofGetWidth() / 2.0, 500, 300, 10); // 壁を物理世界に追く。物理パラメータはない
}
//--------------------------------------------------------------
void ofApp::update(){
    box2d.update();             // box2Dの更新
}
//--------------------------------------------------------------
void ofApp::draw(){
    ofSetColor(0, 127, 255);
	circle.draw();           // 円の描画
    ofSetColor(255, 127, 0);
	box.draw();              // 四角の描画
    ofSetColor(127, 255, 0);
	wall.draw();              // 壁の描画
	for(int i=0; i<circles.size(); i++){
		ofFill();
	    ofSetColor(0, 127, 255);
		circles[i].get()->draw();              // 円の描画
	}
	for(int i=0; i<boxes.size(); i++){
		ofFill();
	    ofSetColor(255, 127, 0);
		boxes[i].get()->draw();              // 円の描画
	}
}
//--------------------------------------------------------------
void ofApp::keyPressed(int key){
}
//--------------------------------------------------------------
void ofApp::keyReleased(int key){
	if( key == 'c' ){ // キーcを押すと、円が生成される
		float r = ofRandom(10,30);
		circles.push_back(ofPtr<ofxBox2dCircle>(new ofxBox2dCircle));
		circles.back().get()->setPhysics(3.0, 0.99, 0.1);
		circles.back().get()->setup(box2d.getWorld(), ofRandom(ofGetWidth()), ofRandom(ofGetHeight()), r);
		circles.back().get()->setVelocity(ofRandom(-5,5),ofRandom(-5,5)); //初期速度の設定
	}
	if( key == 'b' ){// キーbを押すと、四角が生成される
		float w = ofRandom(10,30);
		float h = ofRandom(10,30);
		boxes.push_back(ofPtr<ofxBox2dRect>(new ofxBox2dRect));
		boxes.back().get()->setPhysics(3.0, 0.99, 0.1);
		boxes.back().get()->setup(box2d.getWorld(), ofRandom(ofGetWidth()), ofRandom(ofGetHeight()), w, h);
		boxes.back().get()->setVelocity(ofRandom(-5,5),ofRandom(-5,5));//初期速度の設定
	}
}