Rewrite controller math.
[featherfall2.git] / src / main.js
index 36f874e..d252c74 100644 (file)
@@ -10,6 +10,7 @@ var PlayerController = new yT(yuu.C, {
         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;
@@ -20,11 +21,12 @@ var PlayerController = new yT(yuu.C, {
             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.03;
+        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);
@@ -40,65 +42,46 @@ var PlayerController = new yT(yuu.C, {
 
     tick: function () {
         this._updatePivots();
-        var dt = 0.016;
-        var GRAVITY = 1;
-        var DRAG_MAX = 1;
-        var LIFT_MAX = 1;
+        var GRAVITY = -0.0004;
+        var THRUST = 0.00035;
+        var FRICTIONK = 0.6;
+        var FRICTIONS = 2.0;
+        var DRAG_FREE = 0.01;
+        var DRAG_OPEN = 5.0;
+        var DRAG_LOCK = 10.0;
 
+        var leftAngle = (1 - this.leftPivot) * Math.PI / 2;
+        var rightAngle = (1 - this.rightPivot) * Math.PI / 2;
 
-        var left = (1 - this.leftPivot) * Math.PI / 2;
-        var right = (1 - this.rightPivot) * Math.PI / 2;
+        var vx = this.x - this.lastX;
+        var vy = this.y - this.lastY;
 
-        var vx = (this.x - this.lastX) / dt;
-        var vy = (this.y - this.lastY) / dt;
+        var cleft = Math.cos(leftAngle);
+        var cright = Math.cos(rightAngle);
+        var sleft = Math.sin(leftAngle);
+        var sright = Math.sin(rightAngle); 
 
-        var rotor = 1 * this.up;
+        var ax = 0;
+        var ay = GRAVITY;
 
-        var cleft = Math.cos(left);
-        var cright = Math.cos(right);
-        var sleft = Math.sin(left);
-        var sright = Math.sin(right);
+        var thrust = +!this.free * +this.up * THRUST;
+        ax += thrust * (cleft - cright); 
+        ay += thrust * (sright + sleft);
 
-        var dvyleft = sleft * rotor;
-        var dvyright = sright * rotor;
-        var dvxleft = cleft * rotor;
-        var dvxright = cright * rotor;
-
-        var dvx = (dvxleft - dvxright);
-        var dvy = (dvyleft + dvyright) - GRAVITY;
-
-        var leftarea = DRAG_MAX * Math.abs(sleft);
-        var rightarea = DRAG_MAX * Math.abs(sright);
-        var dragy = vy * vy * (leftarea + rightarea);
-
-        leftarea = DRAG_MAX * Math.abs(cleft);
-        rightarea = DRAG_MAX * Math.abs(cright);
-        var dragx = vx * vx * (leftarea + rightarea);
-
-        leftarea = LIFT_MAX * Math.abs(cleft);
-        rightarea = LIFT_MAX * Math.abs(cright);
-        var liftx = vy * vy * (rightarea - leftarea);
-
-        leftarea = LIFT_MAX * Math.abs(sleft);
-        rightarea = LIFT_MAX * Math.abs(sright);
-        var lifty = vx * vx * (rightarea - leftarea);
-
-        if (vy > 0) {
-            dragy = -dragy;
-            liftx = -liftx;
-        }
-        if (vx > 0) {
-            dragx = -dragx;
-            lifty = -lifty;
-        }
-
-        var ax = dvx + liftx + dragx;
-        var ay = dvy + lifty + dragy;
+        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);
 
         var origX = this.x;
         var origY = this.y;
-        this.x += (this.x - this.lastX) + ax * dt * dt;
-        this.y += (this.y - this.lastY) + ay * dt * dt;
+        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;
@@ -112,7 +95,9 @@ var GameScene = yT(yuu.Scene, {
     constructor: function () {
         yuu.Scene.call(this);
 
-        this.layer0.resize(-1.3333333333/2, -0.2, 1.3333333333, 1);
+        var zoom = 2;
+        this.layer0.resize(
+            zoom * -1.3333333333/2, zoom * -0.2, zoom * 1.3333333333, zoom * 1);
 
         var body, left, right;
         this.player = new yuu.E(body = new yuu.Transform()
@@ -173,6 +158,8 @@ var GameScene = yT(yuu.Scene, {
         w: '+dleftRight',
         o: '+drightLeft',
         p: '+drightRight',
+        z: '+free',
+        x: '+up',
     }
 });