「The Nature of Code」からオブジェクトの複合について取り上げます。2つのオブジェクトを複合して1つの物体として生成します。Processingでプログラムを書いて、動作を確認します。動作を確認できるところがProcessingの楽しいところです。
オブジェクトの複合
以下は、2つのオブジェクトを複合して1つの物体として生成する参考例です。
//Multiple shapes on one body import shiffman.box2d.*; import org.jbox2d.collision.shapes.*; import org.jbox2d.common.*; import org.jbox2d.dynamics.*; Box2DProcessing box2d; ArrayList<Boundary> boundaries; ArrayList<Lollipop> pops; void setup(){ size(200, 200); box2d = new Box2DProcessing(this, 20); box2d.createWorld(); //重力 box2d.setGravity(0, -10); //空のArrayListの生成 boundaries = new ArrayList<Boundary>(); pops = new ArrayList<Lollipop>(); //境界の追加 boundaries.add(new Boundary(width/4, height-5, width/2-50, 10, 0)); boundaries.add(new Boundary(3*width/4, height-5, width/2-50, 10, 0)); boundaries.add(new Boundary(width-5, height/2, 10, height, 0)); boundaries.add(new Boundary(5, height/2, 10, height, 0)); } void draw(){ background(255); box2d.step(); //境界の描画 for(Boundary wall: boundaries){ wall.display(); } if(random(1) < 0.2){ Lollipop p = new Lollipop(width/2, 30); pops.add(p); } //オブジェクトの表示 for(Lollipop p: pops){ p.display(); } for(int i = pops.size()-1; i >= 0; i--){ Lollipop p = pops.get(i); if(p.done()){ pops.remove(i); } } }
class Boundary{ float x; float y; float w; float h; Body b; //コンストラクタ Boundary(float x_, float y_, float w_, float h_, float a){ x = x_; y = y_; w = w_; h = h_; //ポリゴンの定義 PolygonShape sd = new PolygonShape(); //box2dの座標 float box2dW = box2d.scalarPixelsToWorld(w/2); float box2dH = box2d.scalarPixelsToWorld(h/2); sd.setAsBox(box2dW, box2dH); //ボディの定義 BodyDef bd = new BodyDef(); bd.type = BodyType.STATIC; bd.angle = a; bd.position.set(box2d.coordPixelsToWorld(x, y)); b = box2d.createBody(bd); b.createFixture(sd, 1); } //図形の描画 void display(){ fill(0); stroke(0); strokeWeight(1); rectMode(CENTER); float a = b.getAngle(); pushMatrix(); translate(x, y); rotate(-a); rect(0, 0, w, h); popMatrix(); } }
class Lollipop{ Body body; float w; float h; float r; //コンストラクタ Lollipop(float x, float y){ w = 4; h = 12; r = 4; makeBody(new Vec2(x, y)); } //削除 void killBody(){ box2d.destroyBody(body); } //削除判定 boolean done(){ Vec2 pos = box2d.getBodyPixelCoord(body); 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(127); stroke(0); strokeWeight(2); rect(0, 0, w, h); ellipse(0, -h/2, r*2, r*2); popMatrix(); } void makeBody(Vec2 center){ //ボディの定義 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); //円 CircleShape circle = new CircleShape(); circle.m_radius = box2d.scalarPixelsToWorld(r); //オフセット Vec2 offset = new Vec2(0, -h/2); offset = box2d.vectorPixelsToWorld(offset); circle.m_p.set(offset.x, offset.y); body.createFixture(ps, 1.0); body.createFixture(circle, 1.0); body.setLinearVelocity(new Vec2(random(-5, 5), random(2, 5))); body.setAngularVelocity(random(-5, 5)); } }
まとめ
「The Nature of Code」からオブジェクトの複合について取り上げました。2つのオブジェクトを複合して1つの物体として生成しました。引き続き、「The Nature of Code」の内容を勉強します。
参考書籍
※Javaの勉強にもなるので一石二鳥です。