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

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

 メニュー

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

Processing:車を走らせる

「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の勉強にもなるので一石二鳥です。

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