「The Nature of Code」からBox2Dの復習として車を走らせてみます。車を走らせるには、回転ジョイント、チェインを使います。Processingでプログラムを書いて、動作を確認します。動作を確認できるところがProcessingの楽しいところです。
車を走らせる
車を走らせるには、回転ジョイントを使います。道はチェインで作ります。
以下は、車を走らせる参考例です。
//Example demonstrating revolute joints import shiffman.box2d.*; import org.jbox2d.common.*; import org.jbox2d.dynamics.joints.*; import org.jbox2d.collision.shapes.*; import org.jbox2d.collision.shapes.Shape; import org.jbox2d.dynamics.*; import org.jbox2d.dynamics.contacts.*; Box2DProcessing box2d; Car car; Surface surface; void setup(){ size(640, 360); box2d = new Box2DProcessing(this); box2d.createWorld(); surface = new Surface(); car = new Car(100, 120); } void draw(){ background(255); box2d.step(); surface.display(); car.display(); }
class Car{ Box box; Particle wheel1; Particle wheel2; //コンストラクタ Car(float x, float y){ //ボックスの初期座標 box = new Box(x, y, 100, 30, false); wheel1 = new Particle(x-28, y+16, 12); wheel2 = new Particle(x+28, y+16, 12); //回転ジョイントの定義 RevoluteJointDef rjd1 = new RevoluteJointDef(); rjd1.initialize(box.body, wheel1.body, wheel1.body.getWorldCenter()); rjd1.motorSpeed = -PI*2; rjd1.maxMotorTorque = 300.0; rjd1.enableMotor = true; box2d.world.createJoint(rjd1); //回転ジョイントの定義 RevoluteJointDef rjd2 = new RevoluteJointDef(); rjd2.initialize(box.body, wheel2.body, wheel2.body.getWorldCenter()); rjd2.motorSpeed = -PI*2; rjd2.maxMotorTorque = 300.0; rjd2.enableMotor = true; box2d.world.createJoint(rjd2); } //図形の描画 void display(){ box.display(); wheel1.display(); wheel2.display(); } }
class Box{ Body body; float w; float h; //コンストラクタ Box(float x, float y, float w_, float h_, boolean lock){ w = w_; h = h_; //ポリゴンの定義 PolygonShape sd = new PolygonShape(); float box2dW = box2d.scalarPixelsToWorld(w_/2); float box2dH = box2d.scalarPixelsToWorld(h_/2); sd.setAsBox(box2dW, box2dH); FixtureDef fd = new FixtureDef(); fd.shape = sd; fd.density = 1; fd.friction = 0.1; fd.restitution = 0.5; //ボディの定義 BodyDef bd = new BodyDef(); bd.position.set(box2d.coordPixelsToWorld(new Vec2(x, y))); if(lock){ bd.type = BodyType.STATIC; }else{ bd.type = BodyType.DYNAMIC; } body = box2d.createBody(bd); body.createFixture(fd); body.setLinearVelocity(new Vec2(0, 0)); body.setAngularVelocity(0); } //図形の描画 void display(){ Vec2 pos = box2d.getBodyPixelCoord(body); float a = body.getAngle(); rectMode(PConstants.CENTER); pushMatrix(); translate(pos.x, pos.y); rotate(-a); stroke(0); fill(127); strokeWeight(2); rect(0, 0, w, h); popMatrix(); } }
class Particle{ Body body; float r; //コンストラクタ Particle(float x, float y, float r_){ r = r_; makeBody(x, y, r); } //図形の描画 void display(){ Vec2 pos = box2d.getBodyPixelCoord(body); float a = body.getAngle(); pushMatrix(); translate(pos.x, pos.y); rotate(a); fill(127); stroke(0); strokeWeight(2); ellipse(0, 0, r*2, r*2); line(0, 0, r, 0); popMatrix(); } //ボディの定義 void makeBody(float x, float y, float r){ //ボディの定義 BodyDef bd = new BodyDef(); bd.type = BodyType.DYNAMIC; bd.position = box2d.coordPixelsToWorld(x, y); body = box2d.world.createBody(bd); //形状の定義 CircleShape cs = new CircleShape(); cs.m_radius = box2d.scalarPixelsToWorld(r); FixtureDef fd = new FixtureDef(); fd.shape = cs; fd.density = 1.0; fd.friction = 0.3; fd.restitution = 0.1; body.createFixture(fd); body.setLinearVelocity(new Vec2(random(-10f, 10f), random(5f, 10f))); body.setAngularVelocity(random(-10, 10)); } }
class Surface{ ArrayList<Vec2> surface; //コンストラクタ Surface(){ surface = new ArrayList<Vec2>(); float theta = 0; //ベクトルデータの作成 for(float x = width+10; x > -10; x -= 5){ float y = map(sin(theta), -1, 1, 180, 200); theta += 0.15; surface.add(new Vec2(x, y)); } //チェインの作成 ChainShape chain = new ChainShape(); Vec2[] vertices = new Vec2[surface.size()]; for(int i = 0; i < vertices.length; i++){ vertices[i] = box2d.coordPixelsToWorld(surface.get(i)); } chain.createChain(vertices, vertices.length); //ボディの定義 BodyDef bd = new BodyDef(); Body body = box2d.world.createBody(bd); body.createFixture(chain, 1); } //図形の描画 void display(){ strokeWeight(1); stroke(0); noFill(); beginShape(); for(Vec2 v: surface){ vertex(v.x, v.y); } endShape(); } }
まとめ
「The Nature of Code」からBox2Dの復習として車を走らせてました。引き続き、「The Nature of Code」の内容を勉強します。
参考書籍
※Javaの勉強にもなるので一石二鳥です。