Ah ha. Finally found the bug in the math test page's UI.
authordsc <david.schoonover@gmail.com>
Tue, 9 Nov 2010 23:32:32 +0000 (15:32 -0800)
committerdsc <david.schoonover@gmail.com>
Tue, 9 Nov 2010 23:32:32 +0000 (15:32 -0800)
17 files changed:
bin/deploy.sh
index.php
src/Y/y-array.js
src/portal/layer.js
src/portal/math/line.js
src/portal/math/math.js
src/portal/math/vec.js
src/portal/shape.js
src/portal/util/loc.js
src/tanks/game/level.js [new file with mode: 0644]
src/tanks/game/map.js
src/tanks/lttl.js
src/tanks/thing/bullet.js
src/tanks/util/grid.js
src/tanks/util/pathmap.js
test/math/index.php
test/math/math.test.js

index 4a6a94f..5251783 100755 (executable)
@@ -4,31 +4,19 @@ function halp () {
     cat >&2 <<-HALP
 The Littlest Deployer of Battletanks
 
-Usage:     $( basename $0 ) [options] 
-
-Deploys Simoon files.
-
-Options:
-    -h              Displays this help.
+Usage:     $( basename $0 ) [exclude...]
 HALP
 }
 
 SHIFT=0
 function incshift () { SHIFT=$(( $SHIFT + ${1:-1} )); }
-function join () { seps="$IFS"; IFS="$1"; shift; echo "$*"; IFS="$seps"; }
 function fail () { echo "PREDICTABLE FAILURE. $1" >&2; exit 1; }
 
 for opt in $*; do
-    egrep -xq -e '--?h(e(lp?)?)?' && { halp; exit 0; }
+    echo $opt | egrep -xq -e '--?h(e(lp?)?)?' && { halp; exit 0; }
 done
-# while getopts "b:" opt; do
-#     case $opt in
-#         b ) B=$OPTARG; incshift 2 ;;
-#     esac
-# done
-# shift $SHIFT
-
-rsync -Cavz --delete --exclude=tmp ./* less.ly:lessly/hacking/tanks/
-
 
+EXCLUDE="--exclude=$(join ' --exclude=' 'tmp' $*)"
+echo "rsync -Cavz --delete $EXCLUDE ./* less.ly:lessly/hacking/tanks/"
+rsync -Cavz --delete $EXCLUDE ./* less.ly:lessly/hacking/tanks/
 
index 2a76380..330dc95 100644 (file)
--- a/index.php
+++ b/index.php
@@ -48,18 +48,20 @@ $scripts = array(
     "src/portal/math/vec.js",
     "src/portal/math/line.js",
     
+    "src/portal/util/loc.js",
     "src/portal/util/quadtree.js",
     "src/portal/util/rbtree.js",
+    
     "src/portal/util/eventloop.js",
     "src/portal/util/fps.js",
     "src/portal/util/cooldown.js",
-    "src/portal/util/loc.js",
     
     "src/tanks/globals.js",
     "src/tanks/util/calc.js",
     "src/tanks/util/grid.js",
     "src/tanks/util/pathmap.js",
     
+    "src/tanks/game/level.js",
     "src/tanks/game/game.js",
     "src/tanks/game/map.js",
     
index de7a26c..7e9b140 100644 (file)
@@ -27,8 +27,10 @@ function array_remove(v){
 
 YArray.prototype.unique = array_unique;
 function array_unique(){
-    // Executes in the context of the new array
     return this.filter(function(v, i){
+        // Executes in the context of the new array, so
+        // `this.indexOf` is checking what we've already
+        // collected.
         return (this.indexOf(v) === -1);
     });
 }
index db019dd..b3a2f7f 100644 (file)
@@ -321,6 +321,53 @@ Layer = new Y.Class('Layer', {
     
     
     
+    
+    
+    
+    
+    /// Iterators ///
+    
+    invoke : function invoke(name){
+        var args = Y(arguments,1);
+        
+        this[name].apply(this, args);
+        this.children.invoke.apply(this.children, ['invoke', name].concat(args));
+        return this;
+    },
+    
+    setAll : function setAll(k,v){
+        this[k] = v;
+        this.children.invoke('setAll', k,v);
+        return this;
+    },
+    
+    /**
+     * Reduce "up", across this and parents, inner to outer:
+     *      acc = fn.call(context || node, acc, node)
+     */
+    reduceup : function reduceup(acc, fn, context){
+        // if ( Y.isFunction(fn) )
+        //     acc = fn.call(context || this, acc, this);
+        // else
+        //     acc = this[fn].call(context || this, acc, this);
+        acc = fn.call(context || this, acc, this);
+        return ( this.parent ? this.parent.reduceup(acc, fn, context) : acc );
+    },
+    
+    /**
+     * Reduce "down", across this and children, depth-first:
+     *      acc = fn.call(context || node, acc, node)
+     */
+    reduce : function reduce(acc, fn, context){
+        acc = fn.call(context || this, acc, this);
+        return this.children.reduce(acc, fn, context);
+    },
+    
+    
+    
+    
+    
+    
     /// Drawing Functions ///
     
     /**
@@ -352,25 +399,23 @@ Layer = new Y.Class('Layer', {
         ctx.clearRect(-w,-h, 2*w,2*h);
         ctx.translate(neg.x, neg.y);
         
-        // ctx.rotate(this.absRotation);
-        // ctx.translate(-this.originX, -this.originY);
-        
-        // ctx.scale(this.absScaleX, this.absScaleY);
-        
         // Set context attributes
+        var alwaysClear = !!this.alwaysClear;
         CONTEXT_ATTRS.forEach(function(name){
-            if (self[name] === undefined)
-                delete ctx[name];
-            else
+            if (self[name] !== undefined)
                 ctx[name] = self[name];
+            else if (alwaysClear)
+                delete ctx[name];
         });
         
+        // ctx.rotate(this.absRotation);
+        // ctx.translate(-this.originX, -this.originY);
+        // ctx.scale(this.absScaleX, this.absScaleY);
+        
         return this;
     },
     
-    /**
-     * To be implemented by subclasses.
-     */
+    /** To be implemented by subclasses. */
     drawShape : function drawShape(ctx){ return this; },
     
     _closePath : function _closePath(ctx){
@@ -411,60 +456,13 @@ Layer = new Y.Class('Layer', {
     
     
     
-    
-    
-    
-    /// Iterators ///
-    
-    invoke : function invoke(name){
-        var args = Y(arguments,1);
-        
-        this[name].apply(this, args);
-        this.children.invoke.apply(this.children, ['invoke', name].concat(args));
-        return this;
-    },
-    
-    setAll : function setAll(k,v){
-        this[k] = v;
-        this.children.invoke('setAll', k,v);
-        return this;
-    },
-    
-    /**
-     * Reduce "up", across this and parents, inner to outer:
-     *      acc = fn.call(context || node, acc, node)
-     */
-    reduceup : function reduceup(acc, fn, context){
-        // if ( Y.isFunction(fn) )
-        //     acc = fn.call(context || this, acc, this);
-        // else
-        //     acc = this[fn].call(context || this, acc, this);
-        acc = fn.call(context || this, acc, this);
-        return ( this.parent ? this.parent.reduceup(acc, fn, context) : acc );
-    },
-    
-    /**
-     * Reduce "down", across this and children, depth-first:
-     *      acc = fn.call(context || node, acc, node)
-     */
-    reduce : function reduce(acc, fn, context){
-        acc = fn.call(context || this, acc, this);
-        return this.children.reduce(acc, fn, context);
-    },
-    
-    
-    
     /// Misc ///
-    
     toString : function toString(){
         var pos = (this.layer ? this.position() : {top:NaN, left:NaN});
         return this.className+'['+pos.left+','+pos.top+']( children='+this.children.size()+' )';
     }
 });
 
-
-// Helpers for building the class
-
 function makeDelegate(name, dirties, prop){
     prop = prop || 'layer';
     return function(){
@@ -489,8 +487,4 @@ $(function(){
         .appendTo('head');
 });
 
-
-
-
-
 })(jQuery);
index b774a96..abe1250 100644 (file)
@@ -12,8 +12,8 @@ COS_HALF_PI = Math.cos(HALF_PI);
 math.Line = new Y.Class('Line', math.Vec, {
     
     init : function init(x1,y1, x2,y2, tdist){
-        this.x1 = x1; this.y1 = y1; this.p1 = new math.Vec(x1,y1);
-        this.x2 = x2; this.y2 = y2; this.p2 = new math.Vec(x2,y2);
+        this.x1 = x1; this.y1 = y1;
+        this.x2 = x2; this.y2 = y2;
         
         var xdelta = x2-x1, ydelta = y2-y1
         ,    m = this.slope  =  ydelta/xdelta
@@ -22,9 +22,13 @@ math.Line = new Y.Class('Line', math.Vec, {
         ;
         math.Vec.init.call(this, xdelta, ydelta);
         
+        this.p1 = new math.Vec(x1,y1);
+        this.p2 = new math.Vec(x2,y2);
+        
         this.theta = Math.atan2(ydelta, xdelta);
         this._cos  = Math.cos(this.theta);
         this._sin  = Math.sin(this.theta);
+        
         this.setTScale(tdist);
     },
     
index 99b71fd..bb8a8a1 100644 (file)
@@ -10,7 +10,7 @@ math = {
     reflect : function reflect(v, line){
         var dot   = math.Vec.dot
         ,   basev = math.Vec.difference(v, line.p1);
-        return line.clone()
+        return new math.Vec(line.x, line.y)
             .scale(2 * dot(basev,line) / dot(line,line))
             .subtract(basev)
             .add(line.p1);
index 995f1c1..33cf4f2 100644 (file)
@@ -1,7 +1,7 @@
 /**
  * A 2-dimensional vector.
  */
-math.Vec = new Y.Class('Vec', {
+math.Vec = new Y.Class('Vec', [], {
     
     init : function init(x, y){
         if ( Array.isArray(x) ) {
@@ -9,8 +9,9 @@ math.Vec = new Y.Class('Vec', {
             x = x[0];
         }
         
-        this.x = x;
-        this.y = y;
+        this.length = 2;
+        this.x = this[0] = x;
+        this.y = this[1] = y;
     },
     
     equals : function equals(b){
@@ -62,7 +63,7 @@ math.Vec = new Y.Class('Vec', {
     },
     
     toString : function toString(){
-        return 'Vec('+this.x.toFixed(3)+','+this.y.toFixed(3)+')';
+        return '['+this.x.toFixed(3)+', '+this.y.toFixed(3)+']';
     }
     
 });
index 1f1b109..a31817b 100644 (file)
@@ -1,5 +1,8 @@
 Shape = new Y.Class('Shape', Layer, {
     _cssClasses : 'portal layer shape',
+    fillStyle   : 'rgba(231,48,117, 1)',
+    strokeStyle : 'transparent',
+    lineWidth   : 0,
     
     _calcDimension : function _calcDimension(which, values){
         values.unshift(0);
@@ -52,6 +55,7 @@ Circle = new Y.Class('Circle', Shape, {
         var r  = this.radius;
         ctx.arc(0,0, r, 0, Math.PI*2, false);
         ctx.fill();
+        ctx.stroke();
     }
     
 });
@@ -125,9 +129,10 @@ Line = new Y.Class('Line', Shape, {
     },
     
     fixSize : function fixSize(){
-        var p = this.parent
-        ,   w = this.canvasWidth, h = this.canvasHeight
-        ,   pw = p.canvasWidth,   ph = p.canvasHeight ;
+        var p  = this.parent
+        ,   pw = p.canvasWidth,    ph = p.canvasHeight
+        ,   w  = this.canvasWidth, h  = this.canvasHeight
+        ;
         
         if (w !== pw) {
             this.width(pw);
@@ -144,7 +149,8 @@ Line = new Y.Class('Line', Shape, {
         this.fixSize();
         var x1,y1, x2,y2
         ,   line = this.line, p1 = line.p1, p2 = line.p2
-        ,   w = this.canvasWidth, h = this.canvasHeight;
+        ,   w = this.canvasWidth, h = this.canvasHeight
+        ;
         
         x1 = 0; y1 = line.calcY(x1);
         if (y1 < 0) {
@@ -162,8 +168,8 @@ Line = new Y.Class('Line', Shape, {
         ctx.closePath();
         
         // Show definition points
-        this.point(p1.x,p1.y, '#4596FF');
-        this.point(p2.x,p2.y, '#4596FF');
+        this.point(p1.x,p1.y, 'rgba(69,150,255,0.4)');
+        this.point(p2.x,p2.y, 'rgba(69,150,255,0.4)');
     },
     
     
index d170dc8..659a6d8 100644 (file)
@@ -1,5 +1,5 @@
 // [x,y]
-Loc = new Y.Class('Loc', [], {
+Loc = new Y.Class('Loc', math.Vec, {
     
     init : function init(x, y){
         if ( Array.isArray(x) ) {
@@ -26,10 +26,6 @@ Loc = new Y.Class('Loc', [], {
     },
     attr : Y.attr.methodize(),
     
-    equals : function equals(loc){
-        return (this.x === loc.x) && (this.y === loc.y);
-    },
-    
     clone : function clone(){
         return new Loc(this.x, this.y);
     },
@@ -67,8 +63,8 @@ Loc = new Y.Class('Loc', [], {
     
     toString : function toString(){
         var x = this.x, y = this.y;
-        x = Y.isNumber(x) ? Math.round(x,2) : x;
-        y = Y.isNumber(y) ? Math.round(y,2) : y;
+        x = Y.isNumber(x) ? x.toFixed(2) : x;
+        y = Y.isNumber(y) ? y.toFixed(2) : y;
         return '('+x+','+y+')';
     }
     
@@ -106,23 +102,25 @@ Y(Loc).extend({
 Loc.Rect = new Y.Class('Rect', [], {
     init : function init(x1,y1, x2,y2){
         if (x1 instanceof Loc && y1 instanceof Loc) {
-            var top    = x1,
-                bottom = y1;
-        } else {
-            var top    = new Loc(x1,y1),
-                bottom = new Loc(x2,y2);
+            y2 = y1.y; x2 = y1.x;
+            y1 = x1.y; x1 = x1.x;
         }
-        this.left  = this.top    = top;
-        this.right = this.bottom = bottom;
         
         this.length = 4;
-        x1 = this.x1 = this[0] = this.x = top.x;
-        y1 = this.y1 = this[1] = this.y = top.y;
-        x2 = this.x2 = this[2] = bottom.x;
-        y2 = this.y2 = this[3] = bottom.y;
+        this.x1 = this[0] = this.x = x1;
+        this.y1 = this[1] = this.y = y1;
+        this.x2 = this[2] = x2;
+        this.y2 = this[3] = y2;
         
         this.width  = x2 - x1;
         this.height = y2 - y1;
+        
+        this.sides = {
+            top    : new math.Line(x1,y1, x2,y1),
+            bottom : new math.Line(x1,y2, x2,y2),
+            left   : new math.Line(x1,y1, x1,y2),
+            right  : new math.Line(x2,y1, x2,y2)
+        };
     },
     
     set : function set(k, v, def){
@@ -141,31 +139,6 @@ Loc.Rect = new Y.Class('Rect', [], {
     
     attr : Y.attr.methodize(),
     
-    top : function top(x1,y1){
-        if ( x1 !== undefined && y1 !== undefined )
-            return new Loc(this.x1, this.y1);
-        else
-            return this.attr({ 'x1':x1, 'y1': y1 });
-    },
-    bottom : function bottom(x2,y2){
-        if ( x2 !== undefined && y2 !== undefined )
-            return new Loc(this.x2, this.y2);
-        else
-            return this.attr({ 'x2':x2, 'y2': y2 });
-    },
-    left : function left(x1,y1){
-        if ( x1 !== undefined && y1 !== undefined )
-            return new Loc(this.x1, this.y1);
-        else
-            return this.attr({ 'x1':x1, 'y1': y1 });
-    },
-    right : function right(x2,y2){
-        if ( x2 !== undefined && y2 !== undefined )
-            return new Loc(this.x2, this.y2);
-        else
-            return this.attr({ 'x2':x2, 'y2': y2 });
-    },
-    
     moveTo : function moveTo(x,y){
         return new Loc.Rect(x,y, x+this.width,y+this.height);
     },
diff --git a/src/tanks/game/level.js b/src/tanks/game/level.js
new file mode 100644 (file)
index 0000000..0105e5c
--- /dev/null
@@ -0,0 +1,35 @@
+Wall = new Y.Class('Wall', Rect, {
+    fillStyle : 'rgba(255,255,255, 0.25)',
+    blocking : true,
+    
+    init : function init(x,y, w,h){
+        Rect.init.call(this, w,h);
+        
+        var x1 = x,   y1 = y
+        ,   x2 = x+w, y2 = y+h;
+        this.boundingBox = new Loc.Rect(x1,y1, x2,y2);
+        this.position(x,y);
+    }
+    
+});
+
+Level = new Y.Class('Level', Rect, {
+    
+    init : function init(game, w,h){
+        this.game = game;
+        this.pathmap = game.pathmap;
+        Rect.init.call(this, w,h);
+    },
+    
+    append : function append(children){
+        Y(arguments).forEach(function(child){
+            var bb = child.boundingBox;
+            if (child.blocking && bb)
+                child.region = this.pathmap.set(bb.x1,bb.y1, bb.x2,bb.y2, child);
+        }, this);
+        return Layer.prototype.append.apply(this, arguments);
+    },
+    
+    drawShape : Y.op.nop
+    
+});
\ No newline at end of file
index 3abf13c..a6dc4f7 100644 (file)
@@ -2,24 +2,24 @@
 Y(Game.prototype).extend({
     
     initMap : function initMap(){
-        var self = this;
+        // var self = this;
+        
+        this.byId = {};
+        this.units    = new Y.YArray();
+        this.bullets  = new Y.YArray();
+        this.blockers = new Y.YArray();
         
         this.pathmap = new PathMap(0,0, COLUMNS*REF_SIZE, ROWS*REF_SIZE, CAPACITY);
         
-        var root = this.root = this.grid = 
+        var root = 
+        this.root = 
+        this.grid = 
             new Grid(COLUMNS,ROWS, CELL_SIZE)
                 .appendTo(this.viewport);
         this.level =
-            new Layer()
-                .width(  root.layerWidth  )
-                .height( root.layerHeight )
+            new Level(this, root.layerWidth, root.layerHeight )
                 .appendTo(this.root);
         
-        this.byId = {};
-        this.units    = new Y.YArray();
-        this.bullets  = new Y.YArray();
-        this.blockers = new Y.YArray();
-        
         // Agent.addEventListener('create', function(evt){
         //     self.addAgent(evt.instance);
         // });
@@ -156,5 +156,3 @@ Y(Game.prototype).extend({
     }
     
 });
-
-
index 6cf21de..2ce4ee3 100644 (file)
@@ -3,10 +3,24 @@ jQuery(function($){
 v = $('#viewport');
 LBT = new Game();
 
+var sq = REF_SIZE
+,   wall = new Wall(6*sq,1*sq, 1*sq,4*sq);
+LBT.level.append(wall);
+
+
 T = new Tank(0);
 LBT.addUnit(T, 1,2);
+T.shape.hide();
+
+B = new Bullet(T, 5*REF_SIZE,5*REF_SIZE);
+LBT.addUnit(B);
+B.render( LBT.level );
+
+B = new Bullet(T, 25,25);
+LBT.addUnit(B);
+B.render( LBT.level );
 
-B = new Bullet(T, 3*REF_SIZE,3*REF_SIZE);
+B = new Bullet(T, 1*REF_SIZE,3*REF_SIZE);
 LBT.addUnit(B);
 B.render( LBT.level );
 
index 4855582..af51a27 100644 (file)
@@ -41,29 +41,34 @@ Bullet = new Y.Class('Bullet', Thing, {
     
     move : function move(){
         var p, wall, p2 = this.trajectory.p2
-        ,   level = this.game.grid, walls = level.walls
+        ,   level = this.game.level, walls = level.walls
         ,   w = level.layerWidth, h = level.layerHeight
         ,   trj = this.trajectory
-        ,   to  = this.trajectory.pcalc(this.elapsed);
+        ,   to  = this.trajectory.pcalc(this.elapsed)
+        ,   test = this.game.pathmap.attemptMove(this, trj, to)
+        ;
         
         // Do we need to reflect because we've hit a wall?
-        if (to.x <= 0 || to.x >= w || to.y <= 0 || to.y >= h) {
-            if (to.x <= 0) {
-                wall = walls.left;
-                to = trj.pointX(0);
-            
-            } else if (to.x >= w) {
-                wall = walls.right;
-                to = trj.pointX(w);
-            
-            } else if (to.y <= 0) {
-                wall = walls.top;
-                to = trj.pointY(0);
-            
-            } else if (to.y >= h) {
-                wall = walls.bottom;
-                to = trj.pointY(h);
-            }
+        // if (to.x <= 0 || to.x >= w || to.y <= 0 || to.y >= h) {
+        //     if (to.x <= 0) {
+        //         wall = walls.left;
+        //         to = trj.pointX(0);
+        //     
+        //     } else if (to.x >= w) {
+        //         wall = walls.right;
+        //         to = trj.pointX(w);
+        //     
+        //     } else if (to.y <= 0) {
+        //         wall = walls.top;
+        //         to = trj.pointY(0);
+        //     
+        //     } else if (to.y >= h) {
+        //         wall = walls.bottom;
+        //         to = trj.pointY(h);
+        //     }
+        if (!test.ok) {
+            to = test.to;
+            wall = test.line;
             
             p = math.reflect(p2, wall.tangent(to));
             
@@ -99,12 +104,16 @@ Bullet = new Y.Class('Bullet', Thing, {
         
         var t = this.trajectory;
         this.tline = Line.fromPoints(t.x1,t.y1, t.x2,t.y2)
-            .attr('strokeStyle', 'rgba(255,246,174, 0.5)')
+            .attr('strokeStyle', 'rgba(255,246,174, 0.05)')
             .appendTo( parent );
         
-        this.shape = new Circle(2.5)
+        this.shape = new Circle(3)
             .position(this.loc.x, this.loc.y)
-            .attr('fillStyle', '#FFF6AE')
+            .attr({
+                'fillStyle'   : '#EC5B38',
+                'strokeStyle' : 'transparent',
+                'lineWidth'   : 0
+            })
             .appendTo( parent );
         
         return this;