「The Nature of Code」からマウスに引き寄せられる力ついて取り上げます。マウスでクリックした場所に物体を引き寄せます。Processingでプログラムを書いて、動作を確認します。動作を確認できるところがProcessingの楽しいところです。
マウスに引き寄せられる力
Box2DのapplyForce()メソッドを利用して、物体に力を適用します。以下は、その参考例です。
//Basic example of falling rectangles //ApplyForceAttractMouse import shiffman.box2d.*; import org.jbox2d.common.*; import org.jbox2d.collision.shapes.*; import org.jbox2d.dynamics.*; Box2DProcessing box2d; ArrayList<Boundary> boundaries; ArrayList<Box> boxes; void setup(){ size(200, 200); box2d = new Box2DProcessing(this); box2d.createWorld(); box2d.setGravity(0, -20); //空のArrayListを作る boxes = new ArrayList<Box>(); boundaries = new ArrayList<Boundary>(); boundaries = new ArrayList(); boundaries.add(new Boundary(width/4,height-5,width/2-50,10)); boundaries.add(new Boundary(3*width/4,height-5,width/2-50,10)); boundaries.add(new Boundary(width-5,height/2,10,height)); boundaries.add(new Boundary(5,height/2,10,height)); } void draw(){ background(255); box2d.step(); //ボックスの生成・追加 if(random(1) < 0.1){ Box p = new Box(random(width), 10); boxes.add(p); } //マウスがクリックされたときの処理 if(mousePressed){ for(Box b: boxes){ b.attract(mouseX, mouseY); } } //境界の表示 for(Boundary wall: boundaries){ wall.display(); } //ボックスの表示 for(Box b: boxes){ b.display(); } for(int i = boxes.size()-1; i >= 0; i--){ Box b = boxes.get(i); if(b.done()){ boxes.remove(i); } } fill(0); text("Click mouse to attract boxes", 20, 20); }
class Boundary{ float x; float y; float w; float h; Body b; //コンストラクタ Boundary(float x_, float y_, float w_, float h_){ x = x_; y = y_; w = w_; h = h_; //ボディの定義 BodyDef bd = new BodyDef(); bd.type = BodyType.STATIC; bd.position.set(box2d.coordPixelsToWorld(x, y)); b = box2d.createBody(bd); //ポリゴンの定義 PolygonShape sd = new PolygonShape(); float box2dW = box2d.scalarPixelsToWorld(w/2); float box2dH = box2d.scalarPixelsToWorld(h/2); sd.setAsBox(box2dW, box2dH); b.createFixture(sd, 1); } //図形の描画 void display(){ fill(0); stroke(0); rectMode(CENTER); rect(x, y, w, h); } }
class Box{ Body body; float w; float h; //コンストラクタ Box(float x, float y){ w = random(8, 16); h = w; makeBody(new Vec2(x, y), w, h); } void killBody(){ box2d.destroyBody(body); } boolean done(){ Vec2 pos = box2d.getBodyPixelCoord(body); if(pos.y > height+w*h){ killBody(); return true; } return false; } //引力 void attract(float x, float y){ Vec2 worldTarget = box2d.coordPixelsToWorld(x, y); Vec2 bodyVec = body.getWorldCenter(); worldTarget.subLocal(bodyVec); worldTarget.normalize(); worldTarget.mulLocal((float)50); body.applyForce(worldTarget, bodyVec); } //図形の描画 void display(){ Vec2 pos = box2d.getBodyPixelCoord(body); float a = body.getAngle(); rectMode(CENTER); pushMatrix(); translate(pos.x, pos.y); rotate(-a); stroke(0); fill(127); rect(0, 0, w, h); popMatrix(); } 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 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.3; fd.restitution = 0.5; body.createFixture(fd); } }
まとめ
「The Nature of Code」からマウスに引き寄せられる力について取り上げました。マウスでクリックした場所に物体を引き寄せることができました。引き続き、「The Nature of Code」の内容を勉強します。
参考書籍
※Javaの勉強にもなるので一石二鳥です。