元Webデザイナー兼コーダーの備忘録

ウェブデザインやプログラミング、ブログのカスタマイズなどについてアウトプットしています。

 メニュー

» HTML入門のまとめはこちらです。

Processing:マウスジョイントで物体を引っ張る

「The Nature of Code」からマウスジョイントについて取り上げます。マウスジョイントを利用して物体を引っ張ってみます。Processingでプログラムを書いて、動作を確認します。動作を確認できるところがProcessingの楽しいところです。

マウスジョイント

以下は、マウスジョイントで物体を引っ張る参考例です。

//MouseJoint demonstration
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.*;

Box2DProcessing box2d;
ArrayList<Boundary> boundaries;
Box box;
Spring spring;

void setup(){
  size(640, 360);
  
  box2d = new Box2DProcessing(this);
  box2d.createWorld();
  
  box = new Box(width/2, height/2);
  spring = new Spring();
  
  //境界
  boundaries = new ArrayList();
  boundaries.add(new Boundary(width/2, height-5, width, 10, 0));
  boundaries.add(new Boundary(width/2, 5, width, 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();

  spring.update(mouseX, mouseY);
  
  for(int i = 0; i < boundaries.size(); i++){
    Boundary wall = boundaries.get(i);
    wall.display();
  }
  
  box.display();
  spring.display();
}

//マウスを押したときの処理
void mousePressed(){
  if(box.contains(mouseX, mouseY)){
    spring.bind(mouseX, mouseY, box);
  }
}

//マウスを離したときの処理
void mouseReleased(){
  spring.destroy();
}
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_;
    
    //ボディの定義
    BodyDef bd = new BodyDef();
    bd.type = BodyType.STATIC;
    bd.angle = a;
    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(){
    noFill();
    stroke(127);
    fill(127);
    strokeWeight(1);
    rectMode(CENTER);
    
    float a = b.getAngle();
    
    pushMatrix();
    translate(x, y);
    rotate(-a);
    rect(0, 0, w, h);
    popMatrix();
  }
}
class Box{
  Body body;
  float w;
  float h;
  
  //コンストラクタ
  Box(float x_, float y_){
    float x = x_;
    float y = y_;
    w = 24;
    h = 24;
    
    makeBody(new Vec2(x, y), w, h);
  }
  
  boolean contains(float x, float y){
    Vec2 worldPoint = box2d.coordPixelsToWorld(x, y);
    Fixture f = body.getFixtureList();
    boolean inside = f.testPoint(worldPoint);
    return inside;
  }
    
  //図形の描画
  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();
  }

  void makeBody(Vec2 center, float w_, float h_){
    //ボディの定義
    BodyDef bd = new BodyDef();
    bd.type = BodyType.DYNAMIC;
    bd.position.set(box2d.coordPixelsToWorld(new Vec2(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);
    
    body.setLinearVelocity(new Vec2(random(-5, 5), random(2, 5)));
    body.setAngularVelocity(random(-5, 5));  
  }
}
class Spring{
  MouseJoint mouseJoint;
  
  //コンストラクタ
  Spring(){
    mouseJoint = null;
  }
  
  void update(float x, float y){
    if(mouseJoint != null){
      Vec2 mouseWorld = box2d.coordPixelsToWorld(x, y);
      //ターゲットをマウスの位置に設定
      mouseJoint.setTarget(mouseWorld);
    }
  }
  
  //図形の描画
  void display(){
    if(mouseJoint != null){
      Vec2 v1 = new Vec2(0, 0);
      mouseJoint.getAnchorA(v1);
      Vec2 v2 = new Vec2(0, 0);
      mouseJoint.getAnchorB(v2);
      v1 = box2d.coordWorldToPixels(v1);
      v2 = box2d.coordWorldToPixels(v2);
      stroke(0);
      strokeWeight(1);
      line(v1.x, v1.y, v2.x, v2.y);
    }
  }
  
  //マウス座標とBoxオブジェクトを紐付ける
  void bind(float x, float y, Box box){
    //マウスジョイントの定義
    MouseJointDef md = new MouseJointDef();
    md.bodyA = box2d.getGroundBody();
    md.bodyB = box.body;
    Vec2 mp = box2d.coordPixelsToWorld(x, y);
    md.target.set(mp);
    md.maxForce = 1000.0 * box.body.m_mass;
    md.frequencyHz = 5.0;
    md.dampingRatio = 0.9;
    
    mouseJoint = (MouseJoint)box2d.world.createJoint(md);
  }
 
   //マウスジョイントを取り除く
  void destroy(){
    if(mouseJoint != null){
      box2d.world.destroyJoint(mouseJoint);
      mouseJoint = null;
    }
  }
}

まとめ

「The Nature of Code」からマウスジョイントについて取り上げました。マウスジョイントを利用して物体を引っ張ってみました。引き続き、「The Nature of Code」の内容を勉強します。

参考書籍

Javaの勉強にもなるので一石二鳥です。

» HTML入門のまとめはこちらです。