"use strict";
+var b2Vec2 = yf.argcd(
+ function (a) {
+ return b2Vec2.call(this, a[0] || a.x || 0.0, a[1] || a.y || 0.0);
+ },
+ Box2D.b2Vec2
+);
+
+
+yf.ipairs(function (k, v) { Box2D[k] = Box2D[v]; }, {
+ 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] };
+}
+
+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;
-/*var PlayerController = new yT(yuu.C, {
- constructor: function () {
-
+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);
+ mat4.rotateZ(mat, mat, this._body.angle);
+ var pos = this._body.position;
+ mat4.translate(mat, mat, [pos.x, pos.y, 0]);
+ return mat;
+ } }
+});
+
+var PlayerController = yT(yuu.C, {
+ constructor: function (body, left, right) {
+ this.body = body;
+ this.left = left;
+ this.right = right;
+ 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 () {
+ this.left.yaw = -this.leftPivot * Math.PI / 2;
+ this.right.yaw = this.rightPivot * Math.PI / 2;
+ },
+
+ 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();
},
TAPS: ['tick'],
-});*/
+});
+
+function bodyFromAABB (world, position, aabb, density) {
+ var bd = new Box2D.b2BodyDef();
+ var shape = new Box2D.b2PolygonShape();
+ shape.SetAsBox(aabb.w / 2, aabb.h / 2);
+ if (density)
+ bd.type = Box2D.DYNAMIC_BODY;
+ bd.position = new b2Vec2(position[0], position[1]);
+ var body = world.CreateBody(bd);
+ body.CreateFixture(shape, density || 0);
+ return body;
+}
+
+function bodyFromLine (world, p0, p1) {
+ var bd = new Box2D.b2BodyDef();
+ var shape = new Box2D.b2EdgeShape();
+ shape.Set(new b2Vec2(p0), new b2Vec2(p1));
+ var body = world.CreateBody(bd);
+ body.CreateFixture(shape, 0);
+ return body;
+}
var GameScene = yT(yuu.Scene, {
constructor: function () {
yuu.Scene.call(this);
- this.layer0.resize(-0.5, -0.5, 1, 1);
+ var zoom = 10;
+ this.layer0.resize(
+ zoom * -1.3333333333/2, zoom * -0.2, zoom * 1.3333333333, zoom * 1);
+
+ var world = new Box2D.b2World(new b2Vec2(0, -5));
+
+ var body, left, right;
+ this.player = new yuu.E(
+ body = new BodyC(bodyFromAABB(
+ world, [0, 5], new yuu.AABB(0.89, 1.0), 1.0)),
+ new yuu.QuadC('@player')
+ .setSize([0.89, 1.0])
+ );
- this.player = new yuu.E(new yuu.Transform(),
- new yuu.QuadC('@player'));
- var leftWing = new yuu.E(new yuu.Transform(),
- new yuu.QuadC('@left'));
- var rightWing = new yuu.E(new yuu.Transform(),
- new yuu.QuadC('@right'));
+ 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]));
this.player.addChildren(leftWing, rightWing);
this.entity0.addChild(this.player);
+ var ground = new yuu.E(
+ new BodyC(bodyFromLine(world, [-100, 0], [100, 0])),
+ new yuu.QuadC()
+ .setAnchorAtPosition('top')
+ .setSize([100, 1])
+ .setColor([0, 0.5, 0, 1]));
+ this.entity0.addChild(ground);
+
+ this.player.attach(
+ this.controller = new PlayerController(body, left, right));
+ Object.assign(this.commands, this.controller.commands);
+
+ this.entity0.attach(new yuu.Ticker(function () {
+ world.Step(1/60, 4, 4);
+ return true;
+ }, 1));
+
this.ready = yuu.ready([
new yuu.Material('@player'),
new yuu.Material('@left'),
new yuu.Material('@right')]);
},
+ init: function () {
+ var audio0 = new Audio();
+ audio0.src = audio0.canPlayType('audio/ogg')
+ ? "data/sound/starting-line.ogg"
+ : "data/sound/starting-line.mp3";
+ audio0.autoplay = true;
+ audio0.loop = true;
+ document.body.appendChild(audio0);
+ var source = yuu.audio.createMediaElementSource(audio0);
+ source.connect(yuu.audio.music);
+ },
+
KEYBINDS: {
space: '+up',
up: '+up',
- q: '+dleft_left',
- w: '+dleft_right',
- o: '+dright_left',
- p: '+dright_right',
+ q: '+dleftLeft',
+ w: '+dleftRight',
+ o: '+drightLeft',
+ p: '+drightRight',
+ z: '+free',
+ x: '+up',
}
});
yuu.audio.storage = storage;
var game = new GameScene();
yuu.director.pushScene(game);
+ return game.ready;
}
window.addEventListener("load", function() {