+var BodyC = yT(yuu.C, {
+ SLOTS: ['transform'],
+
+ constructor: function (body, size) {
+ this.body = body;
+ this._matrix = mat4.create();
+ },
+
+ position: { alias: 'body.position' },
+ linearVelocity: { alias: 'body.linearVelocity' },
+ ApplyForce: { proxy: 'body.ApplyForce' },
+
+ matrix: { get: function () {
+ var mat = this._matrix;
+ mat4.identity(mat);
+ 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, 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;
+ this.free = 0;
+ this.leftPivot = 0;
+ this.rightPivot = 0;
+ this.commands = {
+ dleftLeft: yuu.propcmd(this, 'dleftLeft'),
+ dleftRight: yuu.propcmd(this, 'dleftRight'),
+ drightLeft: yuu.propcmd(this, 'drightLeft'),
+ drightRight: yuu.propcmd(this, 'drightRight'),
+ up: yuu.propcmd(this, 'up'),
+ free: yuu.propcmd(this, 'free'),
+ };
+ },
+
+ _updatePivots: function () {
+ var PIVOT_SPEED = 0.05;
+ var leftSpeed = (this.dleftRight - this.dleftLeft) * PIVOT_SPEED;
+ var rightSpeed = (this.drightLeft - this.drightRight) * PIVOT_SPEED;
+ this.leftPivot = yf.clamp(this.leftPivot + leftSpeed, 0, 1);
+ this.rightPivot = yf.clamp(this.rightPivot + rightSpeed, 0, 1);
+ },
+
+ _updateTransforms: function () {
+ 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 () {
+ this._updatePivots();
+ var THRUST = 3.5;
+ var DRAG_FREE = 0.01;
+ var DRAG_OPEN = 0.5;
+ var DRAG_LOCK = 1;
+ var CORRECTION = 1;
+
+ var leftAngle = (1 - this.leftPivot) * Math.PI / 2;
+ var rightAngle = (1 - this.rightPivot) * Math.PI / 2;
+
+ var cleft = Math.cos(leftAngle);
+ var cright = Math.cos(rightAngle);
+ var sleft = Math.sin(leftAngle);
+ var sright = Math.sin(rightAngle);
+
+ var thrust = +!this.free * +this.up * THRUST;
+ var ax = thrust * (cleft - cright);
+ var ay = thrust * (sright + sleft);
+
+ var v = this.body.linearVelocity;
+ var drag = this.up ? DRAG_OPEN : this.free ? DRAG_FREE : DRAG_LOCK;
+ ax += drag * Math.max(cleft, cright) * v.x * v.x * -Math.sign(v.x);
+ ay += drag * (sleft + sright) * v.y * v.y * -Math.sign(v.y);
+
+ if (!this.up || this.free)
+ ax += CORRECTION * (cleft - cright) * v.y * v.y * Math.sign(v.y);
+
+ this.body.ApplyForce(new b2Vec2(ax, ay), this.body.position);
+
+ this._updateTransforms();