box2djsの作法 その8

# 概要

box2djsの作法、調べてみた。
threeで表示してみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/a8d44277-9cca-020d-4ade-d71032366395.png)


# サンプルコード


```

var canvas0 = document.getElementById("c");
canvas0.width = 460;
canvas0.height = 400;
var state = false,
    b2Vec2 = Box2D.Common.Math.b2Vec2,
    b2BodyDef = Box2D.Dynamics.b2BodyDef,
    b2Body = Box2D.Dynamics.b2Body,
    b2FixtureDef = Box2D.Dynamics.b2FixtureDef,
    b2Fixture = Box2D.Dynamics.b2Fixture,
    b2World = Box2D.Dynamics.b2World,
    b2MassData = Box2D.Collision.Shapes.b2MassData,
    b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape,
    b2CircleShape = Box2D.Collision.Shapes.b2CircleShape,
    b2DebugDraw = Box2D.Dynamics.b2DebugDraw,
    viewport = document.getElementById('c'),
    renderer = new THREE.WebGLRenderer({ 
      canvas: viewport 
    }),
    scene = new THREE.Scene, 
    camera = new THREE.PerspectiveCamera(35, 1, 1, 1000),
    ball_geometry = new THREE.SphereGeometry(3),
    ball_material = new THREE.MeshLambertMaterial({ 
      color: 0x0000ff, 
      overdraw: true 
    }), 
    large_ball_geometry = new THREE.SphereGeometry(4),
    large_ball_material = new THREE.MeshLambertMaterial({ 
      color: 0x00ff00, 
      overdraw: true 
    }),
    time_last_run,
    world,
    bodyDef = new b2BodyDef,
    fixDef = new b2FixtureDef;
fixDef.density = 1.0;
fixDef.friction = 0.3;
fixDef.restitution = 0.3;
renderer.setSize(viewport.clientWidth, viewport.clientHeight);
camera.position.set(-10, 30, -200);
camera.lookAt(scene.position);
scene.add(camera);
function addLights() {
    var ambientLight = new THREE.AmbientLight(0x555555);
    //scene.add(ambientLight);
    var directionalLight = new THREE.DirectionalLight(0xffffff );
    directionalLight.position.set(-.5, .5, -1.5).normalize();
    scene.add(directionalLight);
}
function buildScene() {
    world = new b2World(new b2Vec2(0, -20), true);
    bodyDef.type = b2Body.b2_staticBody;
    var ramp_geometry= new THREE.CubeGeometry(50, 2, 10),
        material_red = new THREE.MeshLambertMaterial({ 
          color: 0xdd0000, 
          overdraw: true
        }),
        material_green = new THREE.MeshLambertMaterial({ 
          color: 0x00bb00, 
          overdraw: true 
        });    
    var ramp_1 = new THREE.Mesh(ramp_geometry, material_red);
    scene.add(ramp_1);
    bodyDef.position.x = ramp_1.position.x = -20;
    bodyDef.position.y = ramp_1.position.y = 25;
    bodyDef.angle = ramp_1.rotation.z = -Math.PI / 28;
    fixDef.shape = new b2PolygonShape;
    fixDef.shape.SetAsBox(25, 1);
    bodyDef.userData = ramp_1;
    world.CreateBody(bodyDef).CreateFixture(fixDef);
    var ramp_2 = new THREE.Mesh(ramp_geometry, material_red);
    scene.add(ramp_2);
    bodyDef.position.x = ramp_2.position.x = 25;
    bodyDef.position.y = ramp_2.position.y = 5;
    bodyDef.angle = ramp_2.rotation.z = Math.PI / 16;
    fixDef.shape = new b2PolygonShape;
    fixDef.shape.SetAsBox(25, 1);
    bodyDef.userData = ramp_2;
    var body_a = world.CreateBody(bodyDef).CreateFixture(fixDef);
    var floor = new THREE.Mesh(new THREE.PlaneGeometry(100, 50), material_red);
    scene.add(floor);
    bodyDef.position.x = 0;
    bodyDef.position.y = floor.position.y = -15;
    bodyDef.angle = 0;
    fixDef.shape = new b2PolygonShape;
    fixDef.shape.SetAsBox(50, .1);
    bodyDef.userData = floor;
    world.CreateBody(bodyDef).CreateFixture(fixDef);
}
function addBall() {
    var ball;
    if (!state) return;
    fixDef.shape = new b2CircleShape;
    if (Math.random() >= .3)
    {
        ball = new THREE.Mesh(ball_geometry, ball_material);
        fixDef.shape.SetRadius(3);
    } 
    else 
    {
        ball = new THREE.Mesh(large_ball_geometry, large_ball_material);
        fixDef.shape.SetRadius(4);
    }
    scene.add(ball);
    bodyDef.type = b2Body.b2_dynamicBody;
    bodyDef.position.y = ball.position.y = 50;
    bodyDef.position.x = Math.random() * 40 - 20;
    bodyDef.userData = ball;
    world.CreateBody(bodyDef).CreateFixture(fixDef);
}
function updateWorld() {
    requestAnimationFrame(updateWorld);
    if (!state) return;
    var delta, 
        now = (new Date()).getTime();
    if (time_last_run) 
    {
        delta = (now - time_last_run) / 1000;
    } 
    else 
    {
        delta = 1 / 60;
    }
    time_last_run = now; 
    world.Step(delta * 2, 10, 10);
    var object = world.GetBodyList(), 
        mesh, 
        position;
    while (object) 
    {
        mesh = object.GetUserData();
        if (mesh) 
        {
            position = object.GetPosition();
            mesh.position.x = position.x;
            mesh.position.y = position.y;
            mesh.rotation.z = object.GetAngle();
        }
        object = object.GetNext();
    }
    renderer.render(scene, camera);
}
addLights();
buildScene();
document.getElementById('startStop').addEventListener('click', function() {
    if (this.innerHTML === 'Start') 
    {
        this.innerHTML = 'Stop';
        time_last_run = (new Date()).getTime();
        state = true;
    } 
    else 
    {
        this.innerHTML = 'Start';
        state = false;
    }
});
updateWorld();
setInterval(addBall, 500);




```

# 成果物

https://embed.plnkr.co/plunk/uR8Yw5H48mDRFOzz


以上。