「The Nature of Code」からBox2Dの固定オブジェクトについて取り上げます。Processingでプログラムを書いて、動作を確認します。動作を確認できるところがProcessingの楽しいところです。
固定オブジェクト
固定オブジェクトとは、所定の位置に留まるオブジェクトです。BodyDefのタイプをstaticにすると固定オブジェクトになります。
固定オブジェクトの例
以下は、固定オブジェクトの参考例です。
//Falling boxes hitting boundaries import shiffman.box2d.*; import org.jbox2d.collision.shapes.*; import org.jbox2d.common.*; import org.jbox2d.dynamics.*; Box2DProcessing box2d; ArrayList<Box> boxes; //パーティクル ArrayList<Boundary> boundaries; //固定オブジェクト void setup(){ size(200, 200); box2d = new Box2DProcessing(this); box2d.createWorld(); //重力 box2d.setGravity(0, -10); boxes = new ArrayList<Box>(); boundaries = new ArrayList<Boundary>(); //固定オブジェクトの生成・追加 boundaries.add(new Boundary(width/4, height-5, width/2-50, 10)); boundaries.add(new Boundary(3*width/4, height-50, width/2-50, 10)); } void draw(){ background(255); box2d.step(); //パーティクルの生成・追加 if(random(1) < 0.2){ Box p = new Box(width/2, 30); boxes.add(p); } //固定オブジェクトの表示 for(Boundary wall: boundaries){ wall.display(); } //パーティクルの表示 for(Box b : boxes){ b.display(); } //ウィンドウから外れたパーティクルをbox2dとArrayListから削除 for(int i = boxes.size()-1; i >=0; i--){ Box b = boxes.get(i); if(b.done()){ boxes.remove(i); } } }
class Box{ Body body; float w,h; //コンストラクタ Box(float x, float y){ w = random(4, 16); h = random(4, 16); //box2dにパーティクルを設定する makeBody(new Vec2(x, y),w, h); } //box2dからパーティクルを削除 void killBody(){ box2d.destroyBody(body); } //パーティクルの生存判定 boolean done(){ //パーティクルの位置の取得 Vec2 pos = box2d.getBodyPixelCoord(body); //ウィンドウから外れていたらパーティクルをbox2dから削除する if(pos.y > height+w*h){ killBody(); return true; } return false; } //図形の描画 void display(){ Vec2 pos = box2d.getBodyPixelCoord(body); float a = body.getAngle(); rectMode(CENTER); pushMatrix(); translate(pos.x, pos.y); rotate(-a); fill(175); stroke(0); strokeWeight(2); rect(0, 0, w, h); popMatrix(); } //box2dにパーティクルを設定する void makeBody(Vec2 center, float w_, float h_){ //ボディの定義 BodyDef bd = new BodyDef(); bd.type = BodyType.DYNAMIC; bd.position.set(box2d.coordPixelsToWorld(center)); body = box2d.createBody(bd); //シェイプの定義 PolygonShape ps = new PolygonShape(); float box2dW = box2d.scalarPixelsToWorld(w_/2); float box2dH = box2d.scalarPixelsToWorld(h_/2); ps.setAsBox(box2dW, box2dH); FixtureDef fd = new FixtureDef(); fd.shape = ps; fd.density = 1; fd.friction = 0.3; fd.restitution = 0.5; body.createFixture(fd); //速度と角速度の初期値をランダムとする body.setLinearVelocity(new Vec2(random(-5, 5), random(2, 5))); body.setAngularVelocity(random(-5, 5)); } }
//A fixed boundary class class Boundary{ float w, h; Body body; //コンストラクタ Boundary(float x, float y, float w_, float h_){ w = w_; h = h_; //ボディの定義 BodyDef bd = new BodyDef(); bd.type = BodyType.STATIC; //固定オブジェクト bd.position.set(box2d.coordPixelsToWorld(x, y)); body = box2d.createBody(bd); //シェイプの定義 float box2dW = box2d.scalarPixelsToWorld(w/2); float box2dH = box2d.scalarPixelsToWorld(h/2); PolygonShape ps = new PolygonShape(); ps.setAsBox(box2dW, box2dH); //物理パラメータを設定しない場合の記述 //密度1のシェイプを付与する body.createFixture(ps, 1); } //図形の描画 void display(){ Vec2 pos = box2d.getBodyPixelCoord(body); pushMatrix(); translate(pos.x, pos.y); fill(0); stroke(0); rectMode(CENTER); rect(0, 0, w, h); popMatrix(); } }
所定の位置に固定されたオブジェクトを作成することができました。
まとめ
「The Nature of Code」からBox2Dの固定オブジェクトについて取り上げました。引き続き、「The Nature of Code」の内容を勉強します。
参考書籍
※Javaの勉強にもなるので一石二鳥です。