Adds time dilation for testing.
authordsc <david.schoonover@gmail.com>
Mon, 13 Dec 2010 14:47:02 +0000 (06:47 -0800)
committerdsc <david.schoonover@gmail.com>
Mon, 13 Dec 2010 14:47:02 +0000 (06:47 -0800)
src/ezl/layer.cjs
src/ezl/loop/cooldown.cjs
src/ezl/loop/eventloop.cjs
src/tanks/config.cjs
src/tanks/fx/explosion.cjs
src/tanks/game.cjs
src/tanks/thing/bullet.cjs
src/tanks/thing/thing.cjs

index bda0d81..6857efb 100644 (file)
@@ -551,13 +551,15 @@ Y.subclass('Layer', {
      *          properties to either of the above.
      *      * {Function} [complete] Function called on animation completion.
      *      * {Function} [step] Function called after each step of the animation.
+     * @param {Float} [now] Time (ms) to use as the start-time. If omitted, the
+     *  current time is used.
      */
-    animate : function animate(duration, props, options) {
+    animate : function animate(duration, props, options, now) {
         var A = new Animation(this, duration, props, options);
         if ( A.options.queue && this.animActive.length )
             this.animQueue.push(A);
         else
-            this.animActive.push(A.start(NOW)); // XXX: Need another way to pass NOW in
+            this.animActive.push(A.start(now || new Date().getTime()));
         return this;
     },
     
index ae6961c..3c30c07 100644 (file)
@@ -7,40 +7,35 @@ Y.subclass('Cooldown', {
     'init' : function(cooldown, isReady){
         this.cooldown = cooldown; // ms
         this.ready    = isReady || true;
-        this.last     = new Date().getTime();
+        this.elapsed  = (this.isReady ? this.cooldown : 0);
     },
     
-    'activate' : function(now){
-        now = now || new Date().getTime();
+    'activate' : function(){
         if ( this.ready ) {
-            this.ready = false;
-            this.last  = now;
+            this.ready   = false;
+            this.elapsed = 0;
             return true;
         }
         return false;
     },
     
-    'update' : function(now){
+    'tick' : function(elapsed){
         if (this.ready) return true;
         
-        now = now || new Date().getTime();
-        if ( (this.last+this.cooldown) <= now )
+        this.elapsed += elapsed || 0;
+        if (this.elapsed >= this.cooldown)
             this.ready = true;
         
         return this.ready;
     },
     
-    'setCooldown' : function(cooldown, now){
+    'setCooldown' : function(cooldown){
         this.cooldown = cooldown;
-        return this.update(now);
+        return this.tick();
     },
     
-    'ratio' : function(now){
-        now = now || new Date().getTime();
-        if ( this.update(now) )
-            return 1.0;
-        else
-            return now / (this.last+this.cooldown);
+    'ratio' : function(){
+        return Math.min(1.0, this.elapsed / this.cooldown);
     }
     
 });
index f363926..aaccdd5 100644 (file)
@@ -21,15 +21,24 @@ methods = {
     // times     : null, // Last `samples` frame durations
     
     
-    init : function init(target, framerate, samples){
+    /**
+     * @param framerate Target number of frames per second.
+     * @param [target] Object to decorate with start, stop, reset methods.
+     * @param [dilation=1] Number of real milliseconds that must elapse for 1
+     *  perceived millisecond to elapse.
+     * @param [samples=33] Number of frames to track for effective fps
+     */
+    init : function init(framerate, target, dilation, samples){
         Emitter.init.call(this, target);
         decorate.call(this, target);
-        this.tick = this.tick.bind(this);
+        
+        this.tick     = this.tick.bind(this);
         this.decorate = decorate.bind(this);
         
-        this.framerate = framerate;
+        this.framerate  = framerate;
         this.targetTime = 1000 / framerate;
-        this.samples = samples || NUM_SAMPLES;
+        this.samples    = samples || NUM_SAMPLES;
+        this.dilation   = dilation || 1.0;
         
         this.reset();
     },
@@ -79,14 +88,15 @@ methods = {
         var lastTick = this.now;
         this.now     = new Date().getTime();
         this.elapsed = this.now - lastTick;
+        this.perceived = this.elapsed/this.dilation;
         
         clearTimeout(this.timer);
         this.timer = null;
         
         this.fire('tick', this, {
-            now     : this.now,
-            elapsed : this.elapsed,
-            ticks   : ++this.ticks
+            'now'     : this.now,
+            'elapsed' : this.perceived,
+            'ticks'   : ++this.ticks
         });
         
         var tFrame = this.tFrame = new Date().getTime() - this.now;
index 5d10793..c7f2989 100644 (file)
@@ -3,6 +3,10 @@ var Y = require('Y').Y
 
 ,   defaults =
 exports['defaults'] = {
+    game : {
+        timeDilation     : 1.0,
+        gameoverDelay    : 1000
+    },
     ui : {
         createGridCanvas : 1,
         createGridTable  : 0,
index 5014f4a..d8069ea 100644 (file)
@@ -15,13 +15,17 @@ Circle.subclass('Explosion', {
      * @param {Number} start Starting diameter value.
      * @param {Number} end Ending diameter value.
      * @param {Number} duration Duration (ms) of the animation.
+     * @param {Float} [now] Time (ms) to use as the start-time. If omitted, the
+     *  current time is used.
      */
-    init : function initExplosion(start, end, duration){
+    init : function initExplosion(start, end, duration, now){
         start = 0.5 * start;
         end   = 0.5 * end;
+        now   = now || new Date().getTime();
         
         Circle.init.call(this, start);
-        this.animate(duration, {'radius':end}, { 'complete':this.remove.bind(this) });
+        this.animate(duration, { 'radius':end },
+            { 'complete':this.remove.bind(this) }, now);
         
         var prev    = this
         ,   options = { 'step':this.updateRing }
@@ -35,7 +39,7 @@ Circle.subclass('Explosion', {
             ;
             prev = new Circle(ringStart)
                         .fill(color)
-                        .animate(duration, { 'radius':ringEnd }, options)
+                        .animate(duration, { 'radius':ringEnd }, options, now)
                         .appendTo(prev);
         }, this);
     },
index 6cf740c..4d0787d 100644 (file)
@@ -6,7 +6,7 @@ var Y         = require('Y').Y
 ,   EventLoop = require('ezl/loop').EventLoop
 ,   Circle    = require('ezl/shape').Circle
 
-,   config = require('tanks/config')
+,   config = require('tanks/config').values
 ,   map    = require('tanks/map')
 ,   thing  = require('tanks/thing')
 ,   Grid   = require('tanks/ui/grid').Grid
@@ -19,11 +19,12 @@ var Y         = require('Y').Y
 Game =
 exports['Game'] = 
 Y.subclass('Game', {
-    overlayPathmap : false,
+    overlayPathmap : config.pathing.overlayPathmap,
+    overlayAIPaths : config.pathing.overlayAIPaths,
+    timeDilation   : config.game.timeDilation,
+    gameoverDelay  : config.game.gameoverDelay,
     
     gameover      : false,
-    gameoverDelay : 1000,
-    
     
     
     init : function initGame(viewport){
@@ -36,7 +37,7 @@ Y.subclass('Game', {
         this.animations = new Y.YArray();
         
         this.viewport = $(viewport || GRID_ELEMENT);
-        this.loop = new EventLoop(this, FRAME_RATE);
+        this.loop = new EventLoop(FRAME_RATE, this, this.timeDilation);
         
         this.root = 
         this.grid = 
@@ -74,7 +75,7 @@ Y.subclass('Game', {
         this.root.draw();
         
         this.pathmap.removeOverlay(this.viewport);
-        if (config.values.pathing.overlayPathmap)
+        if (this.overlayPathmap)
             this.pathmap.overlay(this.viewport);
     },
     
@@ -91,10 +92,10 @@ Y.subclass('Game', {
         SECONDTH = ELAPSED / 1000;
         SQUARETH = REF_SIZE * SECONDTH
         
-        if (!tanks.config.values.pathing.overlayAIPaths)
+        if (!this.overlayAIPaths)
             this.pathmap.hidePaths();
         
-        this.active.invoke('updateCooldowns', NOW);
+        this.active.invoke('updateCooldowns', ELAPSED, NOW);
         this.active.invoke('act');
         this.animations = this.animations.filter(this.tickAnimations, this);
         
index e6f3992..2f2b155 100644 (file)
@@ -125,7 +125,7 @@ Thing.subclass('Bullet', {
         var dur = ex.timeBase + ex.timeInc*end;
         start = ex.start * start;
         end   = ex.end   * end;
-        this.game.addAnimation(new Explosion(start, end, dur).position(x,y));
+        this.game.addAnimation(new Explosion(start, end, dur, NOW).position(x,y));
     },
     
     render : function render(parent){
index efd59a6..56b5f95 100644 (file)
@@ -83,7 +83,6 @@ new evt.Class('Thing', {
     
     remove : function remove(){
         if (this.shape) this.shape.remove();
-        // if (this.game)  this.game.killUnit(this);
         return this;
     },
     
@@ -103,9 +102,9 @@ new evt.Class('Thing', {
         this._ai = Y(this.ai);
     },
     
-    updateCooldowns : function updateCooldowns(){
-        this._cooldowns.invoke('update', NOW);
-        this._ai.invoke('update', NOW);
+    updateCooldowns : function updateCooldowns(elapsed, now){
+        this._cooldowns.invoke('tick', elapsed, now);
+        this._ai.invoke('tick', elapsed, now);
         return this;
     },