X-Git-Url: https://git.yukkurigames.com/?p=featherfall2.git;a=blobdiff_plain;f=src%2Fmain.js;h=4f888ba8f92527156e00a9e53a6b3e85531d9075;hp=26ec069c6990c51fb170b8a1b555aaaf271c7c95;hb=c952777104ad747e255efd1bcc395fcb04d09ed1;hpb=c6b5fcbed00096406ca526ec55f5e945d35c916a diff --git a/src/main.js b/src/main.js index 26ec069..4f888ba 100644 --- a/src/main.js +++ b/src/main.js @@ -2,42 +2,168 @@ var storage; -/*var PlayerController = new yT(yuu.C, { - constructor: function () { - +var PlayerController = new 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.x = this.lastX = body.x; + this.y = this.lastY = body.y; + 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; + this.body.x = this.x; + this.body.y = this.y; + }, + + tick: function () { + this._updatePivots(); + var GRAVITY = -0.0004; + var THRUST = 0.00035; + var FRICTIONK = 3.5; + var FRICTIONS = 5.0; + var DRAG_FREE = 0.01; + var DRAG_OPEN = 5.0; + var DRAG_LOCK = 10.0; + var CORRECTION = 3.0; + + var leftAngle = (1 - this.leftPivot) * Math.PI / 2; + var rightAngle = (1 - this.rightPivot) * Math.PI / 2; + + var vx = this.x - this.lastX; + var vy = this.y - this.lastY; + + var cleft = Math.cos(leftAngle); + var cright = Math.cos(rightAngle); + var sleft = Math.sin(leftAngle); + var sright = Math.sin(rightAngle); + + var ax = 0; + var ay = GRAVITY; + + var thrust = +!this.free * +this.up * THRUST; + ax += thrust * (cleft - cright); + ay += thrust * (sright + sleft); + + var drag = this.up ? DRAG_OPEN : this.free ? DRAG_FREE : DRAG_LOCK; + ax += drag * Math.max(cleft, cright) * vx * vx * -Math.sign(vx); + ay += drag * (sleft + sright) * vy * vy * -Math.sign(vy); + + if (!this.up || this.free) + ax += CORRECTION * (cleft - cright) * vy * vy * Math.sign(vy); + + var origX = this.x; + var origY = this.y; + this.y += vy + ay; + var collided = this.y < 0; + if (collided) { + var friction = -Math.sign(vx) * Math.abs(ay) + * (Math.abs(vx) < 0.001 ? FRICTIONS : FRICTIONK); + ax += Math.sign(friction) * Math.min(Math.abs(friction), Math.abs(vx)); + } + this.x += vx + ax; + this.y = Math.max(0, this.y); + this.lastX = origX; + this.lastY = origY; + this._updateTransforms(); }, TAPS: ['tick'], -});*/ +}); var GameScene = yT(yuu.Scene, { constructor: function () { yuu.Scene.call(this); - this.layer0.resize(-0.5, -0.5, 1, 1); + var zoom = 2; + this.layer0.resize( + zoom * -1.3333333333/2, zoom * -0.2, zoom * 1.3333333333, zoom * 1); - 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 body, left, right; + this.player = new yuu.E(body = new yuu.Transform() + .setScale([0.081, 0.091, 1]), + new yuu.QuadC('@player') + .setAnchor('bottom') + .setPosition([0, 0])); + var leftWing = new yuu.E(left = new yuu.Transform() + .setPosition([-0.3, 0.65, 0]) + .setScale([0.45, 0.22, 1]), + new yuu.QuadC('@left') + .setZ(-1) + .setAnchor("right") + .setPosition([0, 0])); + var rightWing = new yuu.E(right = new yuu.Transform() + .setPosition([0.3, 0.65, 0]) + .setScale([0.45, 0.22, 1]), + new yuu.QuadC('@right') + .setZ(-1) + .setAnchor('left') + .setPosition([0, 0])); this.player.addChildren(leftWing, rightWing); this.entity0.addChild(this.player); + var ground = new yuu.E(new yuu.Transform() + .setPosition([0, -10, 1]) + .setScale([100, 20, 1]), + new yuu.QuadC() + .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.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', } }); @@ -50,6 +176,7 @@ function load () { yuu.audio.storage = storage; var game = new GameScene(); yuu.director.pushScene(game); + return game.ready; } window.addEventListener("load", function() {