DYNAMIC_BODY: 'b2_dynamicBody'
});
-function accessor (T, p) {
- if (p[0].toLowerCase() === p[0])
- return { get: T.prototype['get_' + p],
- set: T.prototype['set_' + p] };
- else
- return { get: T.prototype['Get' + p],
- set: T.prototype['Set' + p] };
+function camelizeCase (s) {
+ return s.replace(/_([a-z])/g, function (m) {
+ return m[1].toUpperCase();
+ });
}
+function wrapEmscriptenType (T) {
+ var P = T.prototype;
+ var keys = Object.keys(P);
+ var members = keys.filter(function (k) { return k.startsWith("get_"); });
+ var accessors = keys.filter(function (k) { return k.startsWith("Get"); });
+ members.forEach(function (k) {
+ var name = camelizeCase(k.slice(4));
+ if (!name || name in P) return;
+ Object.defineProperty(P, name, {
+ get: P[k], set: P['s' + k.slice(1)]
+ });
+
+ });
+ accessors.forEach(function (k) {
+ var name = k.slice(3);
+ name = name[0].toLowerCase() + name.slice(1);
+ if (!name || name in P) return;
+ Object.defineProperty(P, name, {
+ get: P[k], set: P['S' + k.slice(1)]
+ });
+
+ });
+}
+
+yf.each(wrapEmscriptenType, [
+ Box2D.b2Vec2, Box2D.b2BodyDef, Box2D.b2Body,
+ Box2D.b2JointDef, Box2D.b2RevoluteJointDef,
+ Box2D.b2Joint, Box2D.b2DistanceJoint, Box2D.b2RevoluteJoint,
+]);
+
yT.defineProperties(Box2D.b2Vec2.prototype, {
- x: accessor(Box2D.b2Vec2, 'x'),
- y: accessor(Box2D.b2Vec2, 'y'),
0: { alias: 'x' },
1: { alias: 'y' },
});
-yT.defineProperties(Box2D.b2BodyDef.prototype, {
- type: accessor(Box2D.b2BodyDef, 'type'),
- position: accessor(Box2D.b2BodyDef, 'position'),
-});
-
-yT.defineProperties(Box2D.b2Body.prototype, {
- position: accessor(Box2D.b2Body, 'Position'),
- linearVelocity: accessor(Box2D.b2Body, 'LinearVelocity'),
- angle: accessor(Box2D.b2Body, 'Angle'),
-});
-
var storage;
SLOTS: ['transform'],
constructor: function (body, size) {
- this._body = body;
+ this.body = body;
this._matrix = mat4.create();
},
- position: { alias: '_body.position' },
- linearVelocity: { alias: '_body.linearVelocity' },
- ApplyForce: { proxy: '_body.ApplyForce' },
+ position: { alias: 'body.position' },
+ linearVelocity: { alias: 'body.linearVelocity' },
+ ApplyForce: { proxy: 'body.ApplyForce' },
matrix: { get: function () {
var mat = this._matrix;
mat4.identity(mat);
- mat4.rotateZ(mat, mat, this._body.angle);
- var pos = this._body.position;
+ var pos = this.body.position;
mat4.translate(mat, mat, [pos.x, pos.y, 0]);
+ mat4.rotateZ(mat, mat, this.body.angle);
return mat;
} }
});
var PlayerController = yT(yuu.C, {
- constructor: function (body, left, right) {
+ constructor: function (body, left, right, leftJoint, rightJoint) {
this.body = body;
this.left = left;
this.right = right;
+ this.leftJoint = leftJoint;
+ this.rightJoint = rightJoint;
this.dleftLeft = this.dleftRight =
this.drightLeft = this.drightRight = 0;
this.up = 0;
},
_updateTransforms: function () {
- this.left.yaw = -this.leftPivot * Math.PI / 2;
- this.right.yaw = this.rightPivot * Math.PI / 2;
+ var gain = 1.0;
+ var leftTarget = this.leftPivot * Math.PI / 2;
+ var rightTarget = -this.rightPivot * Math.PI / 2;
+ var leftError = this.leftJoint.jointAngle - leftTarget;
+ var rightError = this.rightJoint.jointAngle - rightTarget;
+ this.leftJoint.motorSpeed = -gain * leftError;
+ this.rightJoint.motorSpeed = -gain * rightError;
},
tick: function () {
function bodyFromAABB (world, position, aabb, density) {
var bd = new Box2D.b2BodyDef();
var shape = new Box2D.b2PolygonShape();
- shape.SetAsBox(aabb.w / 2, aabb.h / 2);
+ shape.SetAsBox(aabb.hw, aabb.hh);
if (density)
bd.type = Box2D.DYNAMIC_BODY;
bd.position = new b2Vec2(position[0], position[1]);
return body;
}
+function pinJoint (world, bodyA, bodyB, anchor) {
+ var dfn = new Box2D.b2RevoluteJointDef();
+ dfn.Initialize(bodyA, bodyB, new b2Vec2(anchor));
+ dfn.maxMotorTorque = 10.0;
+ dfn.motorSpeed = 0.0;
+ dfn.enableMotor = true;
+ return Box2D.castObject(world.CreateJoint(dfn), Box2D.b2RevoluteJoint);
+}
+
var GameScene = yT(yuu.Scene, {
constructor: function () {
yuu.Scene.call(this);
.setSize([0.89, 1.0])
);
- var leftWing = new yuu.E(left = new yuu.Transform()
- .setPosition([-0.25, 0.15, 0]),
- new yuu.QuadC('@left')
- .setZ(-1)
- .setAnchor("right")
- .setSize([0.45, 0.22])
- .setPosition([0, 0]));
- var rightWing = new yuu.E(right = new yuu.Transform()
- .setPosition([0.25, 0.15, 0]),
- new yuu.QuadC('@right')
- .setZ(-1)
- .setAnchor('left')
- .setSize([0.45, 0.22])
- .setPosition([0, 0]));
+ var leftWing = new yuu.E(left = new BodyC(
+ bodyFromAABB(world, [-0.50, 5.15], new yuu.AABB(0.45, 0.22), 1.0)),
+ new yuu.QuadC('@left')
+ .setZ(-1)
+ .setSize([0.45, 0.22]));
+ var leftJoint = pinJoint(world, left.body, body.body, [-0.1, 5.15]);
+ var rightWing = new yuu.E(right = new BodyC(
+ bodyFromAABB(world, [0.50, 5.15], new yuu.AABB(0.45, 0.22), 1.0)),
+ new yuu.QuadC('@right')
+ .setZ(-1)
+ .setSize([0.45, 0.22]));
+ var rightJoint = pinJoint(world, right.body, body.body, [0.1, 5.15]);
this.player.addChildren(leftWing, rightWing);
this.entity0.addChild(this.player);
this.entity0.addChild(ground);
this.player.attach(
- this.controller = new PlayerController(body, left, right));
+ this.controller = new PlayerController(body, left, right,
+ leftJoint, rightJoint));
Object.assign(this.commands, this.controller.commands);
this.entity0.attach(new yuu.Ticker(function () {
- world.Step(1/60, 4, 4);
+ world.Step(1/60, 8, 8);
return true;
}, 1));