前回の第28回
床をつくる
前回つくったボールは、
床の剛体を定義するb2BodyDefオブジェクトも、
マウスイベント | 剛体の種類 | 値 |
---|---|---|
b2_ | 動的 | 2 |
b2_ | キネマティック | 1 |
b2_ | 静的 | 0 |
var standardRadius = 20;
var floor = new createjs.Rectangle();
function initialize() {
floor.width = stageWidth * 0.8;
floor.x = (stageWidth - floor.width) / 2;
// initializeBox2D(gravity);
initializeBox2D(gravity, stageWidth, stageHeight);
}
// function initializeBox2D(gravity) {
function initializeBox2D(gravity, stageWidth, stageHeight) {
var floorShape = createStaticFloor(stageWidth / 2, stageHeight - standardRadius, floor.width, standardRadius, "#CCCCCC");
stage.addChild(floorShape);
}
function createStaticFloor(nX, nY, nWidth, nHeight, color) {
var staticBody = Box2D.Dynamics.b2Body.b2_staticBody
var bodyDef = defineBody(nX, nY, staticBody);
var floorShape = createVisualFloor(nWidth, nHeight, color, bodyDef);
createBody(world, bodyDef);
return floorShape;
}
function createVisualFloor(nWidth, nHeight, color, bodyDef) {
var floorShape = new createjs.Shape();
floorShape.regX = nWidth / 2;
floorShape.regY = nHeight / 2;
floorShape.graphics
.beginFill(color)
.drawRect(0, 0, nWidth, nHeight);
bodyDef.userData = floorShape;
return floorShape;
}
第28回コード1

すべての剛体を物理シミュレーションする
Ticker.
物理空間のつぎの剛体を取り出すには、
b2Bodyオブジェクト.GetNext()
今のところ、
function update(delta) {
var body = world.GetBodyList();
while (body) {
var myObject = body.GetUserData();
body = body.GetNext();
}
}
これでどうだとばかり、

まだ物理シミュレーションとしてでき上がっていないものの、
var SCALE = 1 / 30;
var stage;
var world;
var gravityVertical = 15;
var velocityIterations = 8;
var positionIterations = 3;
var stageWidth;
var stageHeight;
var ballImage;
var imageRadius;
var standardRadius = 20;
var floor = new createjs.Rectangle();
function initialize() {
var canvasElement = document.getElementById("myCanvas");
var gravity = new Box2D.Common.Math.b2Vec2(0, gravityVertical);
stage = new createjs.Stage(canvasElement);
stageWidth = canvasElement.width;
stageHeight = canvasElement.height;
floor.width = stageWidth * 0.8;
floor.x = (stageWidth - floor.width) / 2;
initializeBox2D(gravity, stageWidth, stageHeight);
createjs.Ticker.timingMode = createjs.Ticker.RAF;
preloadImage("images/Pen.png");
}
function initializeBox2D(gravity, stageWidth, stageHeight) {
world = new Box2D.Dynamics.b2World(gravity, true);
var floorShape = createStaticFloor(stageWidth / 2, stageHeight - standardRadius, floor.width, standardRadius, "#CCCCCC");
stage.addChild(floorShape);
}
function tick(eventObject) {
var delta = eventObject.delta;
update(delta);
stage.update();
}
function addBall() {
var ball = createDynamicBall(stageWidth / 2, -imageRadius, imageRadius);
stage.addChild(ball);
}
function createDynamicBall(nX, nY, radius) {
var dynamicBody = Box2D.Dynamics.b2Body.b2_dynamicBody;
var bodyDef = defineBody(nX, nY, dynamicBody);
var ball = createVisualBall(radius, bodyDef);
createBody(world, bodyDef);
return ball;
}
function createStaticFloor(nX, nY, nWidth, nHeight, color) {
var staticBody = Box2D.Dynamics.b2Body.b2_staticBody
var bodyDef = defineBody(nX, nY, staticBody);
var floorShape = createVisualFloor(nWidth, nHeight, color, bodyDef);
createBody(world, bodyDef);
return floorShape;
}
function defineBody(nX , nY, bodyType) {
var bodyDef = new Box2D.Dynamics.b2BodyDef();
bodyDef.position.Set(nX * SCALE, nY * SCALE);
bodyDef.type = bodyType;
return bodyDef;
}
function createBody(world, bodyDef) {
var body = world.CreateBody(bodyDef);
}
function update(delta) {
world.Step(delta / 1000, velocityIterations, positionIterations);
var body = world.GetBodyList();
while (body) {
var myObject = body.GetUserData();
if (myObject) {
var position = body.GetPosition();
myObject.x = position.x / SCALE;
myObject.y = position.y / SCALE;
myObject.rotation = body.GetAngle()/createjs.Matrix2D.DEG_TO_RAD;
}
body = body.GetNext();
}
}
function createVisualBall(radius, bodyDef) {
var ball = new createjs.Bitmap(ballImage);
ball.regX = ballImage.width / 2;
ball.regY = ballImage.height / 2;
ball.scaleX = ball.scaleY = radius / imageRadius;
bodyDef.userData = ball;
return ball;
}
function createVisualFloor(nWidth, nHeight, color, bodyDef) {
var floorShape = new createjs.Shape();
floorShape.regX = nWidth / 2;
floorShape.regY = nHeight / 2;
floorShape.graphics
.beginFill(color)
.drawRect(0, 0, nWidth, nHeight);
bodyDef.userData = floorShape;
return floorShape;
}
function preloadImage(file) {
var loader = new createjs.LoadQueue(false);
loader.addEventListener("fileload", loadFinished);
loader.loadFile(file);
}
function loadFinished(eventObject) {
ballImage = eventObject.result;
imageRadius = ballImage.width / 2;
createjs.Ticker.addEventListener("tick", tick);
addBall();
}
かたちを定める
剛体の大きさやかたちはフィクスチャというオブジェクトで決める。例によって、
フィクスチャを定義する関数
function createDynamicBall(nX, nY, radius) {
var circleShape = new Box2D.Collision.Shapes.b2CircleShape(radius * SCALE);
var fixtureDef = defineFixture(circleShape);
// createBody(world, bodyDef);
createBody(world, bodyDef, fixtureDef);
}
function createStaticFloor(nX, nY, nWidth, nHeight, color) {
var boxShape = new Box2D.Collision.Shapes.b2PolygonShape();
var fixtureDef = defineFixture(boxShape);
boxShape.SetAsBox(nWidth / 2 * SCALE, nHeight / 2 * SCALE);
// createBody(world, bodyDef);
createBody(world, bodyDef, fixtureDef);
}
function defineFixture(myShape) {
var fixtureDef = new Box2D.Dynamics.b2FixtureDef();
fixtureDef.shape = myShape;
return fixtureDef;
}
// function createBody(world, bodyDef) {
function createBody(world, bodyDef, fixtureDef) {
body.CreateFixture(fixtureDef);
}
黒子のBox2Dに、

材質を定める
物理演算エンジンは教えたことしかやらない。しかし、
b2FixtureDefプロパティ | 意味 | 値 |
---|---|---|
density | 密度 | 重さ |
friction | 摩擦 | 0から1の間の数値 |
restitution | 弾性 | 0から1の間の数値 |
function createDynamicBall(nX, nY, radius) {
setFixture(fixtureDef, 1, 0.1, 0.8);
}
function setFixture(fixtureDef, density, friction, restitution) {
fixtureDef.density = density;
fixtureDef.friction = friction;
fixtureDef.restitution = restitution;
}
これでようやく、

今回はここまでとしよう。JavaScript全体はコード2にまとめた。また、
var SCALE = 1 / 30;
var stage;
var world;
var gravityVertical = 15;
var velocityIterations = 8;
var positionIterations = 3;
var stageWidth;
var stageHeight;
var ballImage;
var imageRadius;
var standardRadius = 20;
var floor = new createjs.Rectangle();
function initialize() {
var canvasElement = document.getElementById("myCanvas");
var gravity = new Box2D.Common.Math.b2Vec2(0, gravityVertical);
stage = new createjs.Stage(canvasElement);
stageWidth = canvasElement.width;
stageHeight = canvasElement.height;
floor.width = stageWidth * 0.8;
floor.x = (stageWidth - floor.width) / 2;
initializeBox2D(gravity, stageWidth, stageHeight);
createjs.Ticker.timingMode = createjs.Ticker.RAF;
preloadImage("images/Pen.png");
}
function initializeBox2D(gravity, stageWidth, stageHeight) {
world = new Box2D.Dynamics.b2World(gravity, true);
var floorShape = createStaticFloor(stageWidth / 2, stageHeight - standardRadius, floor.width, standardRadius, "#CCCCCC");
stage.addChild(floorShape);
}
function tick(eventObject) {
var delta = eventObject.delta;
update(delta);
stage.update();
}
function addBall() {
var ball = createDynamicBall(stageWidth / 2, -imageRadius, imageRadius);
stage.addChild(ball);
}
function createDynamicBall(nX, nY, radius) {
var dynamicBody = Box2D.Dynamics.b2Body.b2_dynamicBody;
var bodyDef = defineBody(nX, nY, dynamicBody);
var ball = createVisualBall(radius, bodyDef);
var circleShape = new Box2D.Collision.Shapes.b2CircleShape(radius * SCALE);
var fixtureDef = defineFixture(circleShape);
setFixture(fixtureDef, 1, 0.1, 0.8);
createBody(world, bodyDef, fixtureDef);
return ball;
}
function createStaticFloor(nX, nY, nWidth, nHeight, color) {
var staticBody = Box2D.Dynamics.b2Body.b2_staticBody;
var bodyDef = defineBody(nX, nY, staticBody);
var floorShape = createVisualFloor(nWidth, nHeight, color, bodyDef);
var boxShape = new Box2D.Collision.Shapes.b2PolygonShape();
var fixtureDef = defineFixture(boxShape);
boxShape.SetAsBox(nWidth / 2 * SCALE, nHeight / 2 * SCALE);
createBody(world, bodyDef, fixtureDef);
return floorShape;
}
function defineBody(nX , nY, bodyType) {
var bodyDef = new Box2D.Dynamics.b2BodyDef();
bodyDef.position.Set(nX * SCALE, nY * SCALE);
bodyDef.type = bodyType;
return bodyDef;
}
function defineFixture(myShape) {
var fixtureDef = new Box2D.Dynamics.b2FixtureDef();
fixtureDef.shape = myShape;
return fixtureDef;
}
function setFixture(fixtureDef, density, friction, restitution) {
fixtureDef.density = density;
fixtureDef.friction = friction;
fixtureDef.restitution = restitution;
}
function createBody(world, bodyDef, fixtureDef) {
var body = world.CreateBody(bodyDef);
body.CreateFixture(fixtureDef);
}
function update(delta) {
world.Step(delta / 1000, velocityIterations, positionIterations);
var body = world.GetBodyList();
while (body) {
var myObject = body.GetUserData();
if (myObject) {
var position = body.GetPosition();
myObject.x = position.x / SCALE;
myObject.y = position.y / SCALE;
myObject.rotation = body.GetAngle()/createjs.Matrix2D.DEG_TO_RAD;
}
body = body.GetNext();
}
}
function createVisualBall(radius, bodyDef) {
var ball = new createjs.Bitmap(ballImage);
ball.regX = ballImage.width / 2;
ball.regY = ballImage.height / 2;
ball.scaleX = ball.scaleY = radius / imageRadius;
bodyDef.userData = ball;
return ball;
}
function createVisualFloor(nWidth, nHeight, color, bodyDef) {
var floorShape = new createjs.Shape();
floorShape.regX = nWidth / 2;
floorShape.regY = nHeight / 2;
floorShape.graphics
.beginFill(color)
.drawRect(0, 0, nWidth, nHeight);
bodyDef.userData = floorShape;
return floorShape;
}
function preloadImage(file) {
var loader = new createjs.LoadQueue(false);
loader.addEventListener("fileload", loadFinished);
loader.loadFile(file);
}
function loadFinished(eventObject) {
ballImage = eventObject.result;
imageRadius = ballImage.width / 2;
createjs.Ticker.addEventListener("tick", tick);
addBall();
}