Position refactor complete, I think.
authordsc <david.schoonover@gmail.com>
Sun, 12 Dec 2010 07:27:57 +0000 (23:27 -0800)
committerdsc <david.schoonover@gmail.com>
Sun, 12 Dec 2010 07:27:57 +0000 (23:27 -0800)
15 files changed:
src/ezl/layer.cjs
src/ezl/loc/boundingbox.cjs
src/ezl/math/vec.cjs
src/ezl/shape/circle.cjs
src/ezl/shape/rect.cjs
src/tanks/config.cjs
src/tanks/game.cjs
src/tanks/map/pathmap.cjs
src/tanks/map/trajectory.cjs
src/tanks/thing/player.cjs
src/tanks/thing/tank.cjs
src/tanks/thing/thing.cjs
src/tanks/ui/grid.cjs
src/tanks/ui/main.cjs
www/test/shapes/test-shapes.js

index dfc5aad..19d5396 100644 (file)
@@ -43,6 +43,12 @@ Y.subclass('Layer', {
     transform : null, // Object
     useCanvasScaling : false, // default to CSS3 scaling
     
+    /// Defaults ///
+    
+    originX : 0,
+    originY : 0,
+    
+    
     
     /// Setup ///
     
@@ -53,7 +59,7 @@ Y.subclass('Layer', {
         this.negBleed = new Loc(0,0);
         this.posBleed = new Loc(0,0);
         
-        this.boundingBox = new BoundingBox(0,0, 0,0);
+        this.boundingBox = new BoundingBox(0,0, 0,0, this.originX,this.originY);
         this._origin = this.boundingBox.origin;
         
         this.transform = {
@@ -139,6 +145,36 @@ Y.subclass('Layer', {
     
     attr : Y.attr.methodize(),
     
+    size : function size(w,h){
+        if (w === undefined && h === undefined)
+            return new Vec(this.layerWidth,this.layerHeight);
+        
+        this.layerWidth  = w;
+        this.layerHeight = h;
+        
+        var bb = this.boundingBox.resize(w,h)
+        ,   nb = this.negBleed, pb = this.posBleed
+        
+        // HTMLCanvas.{width,height} is a long
+        ,   cw = this.canvasWidth  = Math.ceil(w + nb.x + pb.x)
+        ,   ch = this.canvasHeight = Math.ceil(h + nb.y + pb.y)
+        ;
+        
+        this.layer.css({
+            'width' : w,            'height' : h,
+            'left'  : bb.x1,        'top' : bb.y1
+        });
+        this.canvas.css({
+            'width' : cw,           'height' : ch,
+            'margin-left' : -nb.x,  'top' : -nb.y
+        });
+        var el = this.canvas[0];
+        el.width  = cw;
+        el.height = ch;
+        
+        return this;
+    },
+    
     /**
      * Changes the layer's width and then updates the canvas.
      */
@@ -149,14 +185,14 @@ Y.subclass('Layer', {
         this.layerWidth = w;
         
         var bb = this.boundingBox.resize(w, this.layerHeight)
-        ,   ro = bb.relOrigin
+        // ,   ro = bb.relOrigin
         ,   nb = this.negBleed
         ,   cw = this.canvasWidth = Math.ceil(w + nb.x + this.posBleed.x); // HTMLCanvas.width is a long
         
         this.layer.css({
             'width'       : w,
             'left'        : bb.x1,
-            'margin-left' : -ro.x
+            // 'margin-left' : -ro.x
         });
         
         this.canvas.css({
@@ -175,14 +211,14 @@ Y.subclass('Layer', {
         this.layerHeight = h;
         
         var bb = this.boundingBox.resize(this.layerWidth, h)
-        ,   ro = bb.relOrigin
+        // ,   ro = bb.relOrigin
         ,   nb = this.negBleed
         ,   ch = this.canvasHeight = Math.ceil(h + nb.y + this.posBleed.y); // HTMLCanvas.height is a long
         
         this.layer.css({
             'height'     : h,
             'top'        : bb.y1,
-            'margin-top' : -ro.y
+            // 'margin-top' : -ro.y
         });
         
         this.canvas.css({
@@ -256,7 +292,7 @@ Y.subclass('Layer', {
     css : makeDelegate('css'),
     
     /** Position relative to document. */
-    // offset : makeDelegate('offset'),
+    offset : makeDelegate('offset'),
     
     
     
@@ -464,6 +500,12 @@ Y.subclass('Layer', {
         return this;
     },
     
+    animate : function animate(props, options) {
+        
+    },
+    
+    /// Debuggging ///
+    
     // for debugging
     point : function point(x,y, color){
         var ctx = this.ctx;
@@ -480,16 +522,20 @@ Y.subclass('Layer', {
         return this;
     },
     
-    animate : function animate(props, options) {
+    title : function title(val){
+        if (val === undefined)
+            return this.layer.attr('title');
         
+        this.layer.attr('title', val);
+        return this;
     },
     
     
     
     /// Misc ///
     toString : function toString(){
-        var pos = (this.layer ? this.position() : {y:NaN, x:NaN});
-        return this.className+'['+pos.x+','+pos.y+']( children='+this.children.size()+' )';
+        var pos = (this.layer ? this.position() : {top:NaN, left:NaN});
+        return this.className+'['+pos.left+','+pos.top+']( children='+this.children.size()+' )';
     }
 });
 
index 3145a81..5de767d 100644 (file)
@@ -27,15 +27,15 @@ Rect.subclass('BoundingBox', {
      * Use relocate() to change the position by moving the origin.
      */
     set originX(v){ this._origin.x = v; return v; },
-    get originX(){ return this._origin.absolute(this.width,this.height, this.x1,this.x2).x; },
+    get originX(){ return this._origin.absolute(this.width,this.height, this.x1,this.y1).x; },
     
     set originY(v){ this._origin.y = v; return v; },
-    get originY(){ return this._origin.absolute(this.width,this.height, this.x1,this.x2).y; },
+    get originY(){ return this._origin.absolute(this.width,this.height, this.x1,this.y1).y; },
     
     /**
      * Accessor for the realized numeric origin.
      */
-    get absOrigin() { return this._origin.absolute(this.width,this.height, this.x1,this.x2); },
+    get absOrigin() { return this._origin.absolute(this.width,this.height, this.x1,this.y1); },
     get relOrigin() { return this._origin.absolute(this.width,this.height); },
     
     get origin(){ return this._origin; },
@@ -44,7 +44,7 @@ Rect.subclass('BoundingBox', {
         var _x1 = this[X1], _y1 = this[Y1]
         ,   _x2 = this[X2], _y2 = this[Y2]
         
-        ,   abs = this._origin.absolute(_x1-_x1, _y2-_y1, _x1,_y1)
+        ,   abs = this._origin.absolute(_x2-_x1, _y2-_y1, _x1,_y1)
         ,   dx1 = _x1 - abs.x, dy1 = _y1 - abs.y
         ,   dx2 = _x2 - abs.x, dy2 = _y2 - abs.y
         
@@ -54,6 +54,11 @@ Rect.subclass('BoundingBox', {
         return this.set4(x1,y1, x2,y2);
     },
     
+    relocated : function relocated(x,y){
+        var bb = this.clone();
+        return bb.relocate(x,y);
+    },
+    
     resize : function resize(w,h){
         var x1 = this[X1], y1 = this[Y1]
         ,   x2 = this[X2], y2 = this[Y2]
@@ -63,24 +68,29 @@ Rect.subclass('BoundingBox', {
         ,   xp = o.xPercentage, yp = o.yPercentage
         ;
         if ( xp !== null ) {
-            diff = w - wOld;
+            // diff = w - wOld;
             abs = x1 + xp*wOld;
-            x1 = abs - xp*diff;
-            x2 = abs + (1-xp)*diff;
+            x1 = abs - xp*w;
+            x2 = abs + (1-xp)*w;
         } else
             x2 = x1 + w;
         
         if ( yp !== null ) {
-            diff = h - hOld;
+            // diff = h - hOld;
             abs = y1 + yp*hOld;
-            y1 = abs - yp*diff;
-            y2 = abs + (1-yp)*diff;
+            y1 = abs - yp*h;
+            y2 = abs + (1-yp)*h;
         } else
             y2 = y1 + h;
         
         return this.set4(x1,y1, x2,y2);
     },
     
+    resized : function resized(w,h){
+        var bb = this.clone();
+        return bb.resize(w,h);
+    },
+    
     clone : function clone(){
         var o = this._origin;
         return new BoundingBox(this[X1],this[Y1], this[X2],this[Y2], o[X1], o[Y1]);
index 19cf627..1bc3c08 100644 (file)
@@ -91,6 +91,10 @@ new Y.Class('Vec', [], {
         return this.setXY(x*cos - y*sin, x*sin + y*cos);
     },
     
+    clone : function clone(){
+        return new this.__class__(this[_X],this[_Y]);
+    },
+    
     toString : function toString(){
         var p = 2, x = this[_X], y = this[_Y];
         x = ((x % 1 !== 0) ? x.toFixed(p) : x);
index 00acd8b..e02eab7 100644 (file)
@@ -6,6 +6,8 @@ Circle =
 exports['Circle'] =
 Shape.subclass('Circle', {
     _cssClasses : 'ezl layer shape circle',
+    originX : '50%',
+    originY : '50%',
     
     init : function initCircle(radius){
         Shape.init.call(this);
@@ -19,12 +21,13 @@ Shape.subclass('Circle', {
         var d = r * 2;
         this.dirty = true;
         this._radius = r;
-        this.width(d).height(d);
+        this.size(d,d);
         return this;
     },
     
     drawShape : function drawShape(ctx){
-        ctx.arc(0,0, this._radius, 0, Math.PI*2, false);
+        var r = this._radius;
+        ctx.arc(r,r, r, 0, Math.PI*2, false);
         ctx.fill();
         ctx.stroke();
     }
index 563a441..845688d 100644 (file)
@@ -5,12 +5,12 @@ Rect =
 exports['Rect'] =
 Shape.subclass('Rect', {
     _cssClasses : 'ezl layer shape rect',
+    originX : 0,
+    originY : 0,
     
     init : function initRect(w,h){
         Shape.init.call(this);
-        this.origin(0,0)
-            .width(w)
-            .height(h);
+        this.size(w,h);
     },
     
     drawShape : function drawShape(ctx){
index dc05997..9178463 100644 (file)
@@ -5,7 +5,7 @@ var Y = require('Y').Y
 exports['defaults'] = {
     ui : {
         showGridCoords : false,
-        showCountdown  : true
+        showCountdown  : false
     },
     pathing : { 
         overlayAIPaths    : false,
index b4a260f..d21ef32 100644 (file)
@@ -119,8 +119,8 @@ Y.subclass('Game', {
             // Center unit in square
             var sqX = (col || 0) * REF_SIZE
             ,   sqY = (row || 0) * REF_SIZE
-            ,   x = sqX + (REF_SIZE-unit.width) /2
-            ,   y = sqY + (REF_SIZE-unit.height)/2 ;
+            ,   x = sqX + REF_SIZE/2
+            ,   y = sqY + REF_SIZE/2 ;
             
             unit.position(x,y);
             unit.render( this.level );
index f80bda9..c107629 100644 (file)
@@ -1,6 +1,8 @@
 //  -*- mode: JavaScript; tab-width: 4; indent-tabs-mode: nil; -*-
 var Y        = require('Y').Y
-,   Vec      = require('ezl/math/vec').Vec
+,   math     = require('ezl/math')
+,   Vec      = math.Vec
+,   Line     = math.Line
 ,   QuadTree = require('ezl/util/tree/quadtree').QuadTree
 ,   Bullet   = require('tanks/thing/bullet').Bullet
 ,   astar    = require('ezl/util/astar')
@@ -74,14 +76,16 @@ QuadTree.subclass('PathMap', {
         bb = bb || agent.boundingBox;
         var blockers, blocker, msg
         ,   side = null
-        
-        ,   bw = bb.width,          bh = bb.height
+        ,   tobb = bb.relocated(to.x,to.y)
+        ,   x1 = tobb.x1, y1 = tobb.y1
+        ,   x2 = tobb.x2, y2 = tobb.y2
         
         ,   ro = bb.relOrigin
-        ,   offX = ro.x,            offY = ro.y
+        ,   bw = bb.width,          bh = bb.height
+        ,   offX = bw - ro.x,       offY = bh = ro.y
         
-        ,   x1 = to.x+offX,         y1 = to.y+offY
-        ,   x2 = x1+bw,             y2 = y1+bh
+        // ,   x1 = to.x+offX,         y1 = to.y+offY
+        // ,   x2 = x1+bw,             y2 = y1+bh
         ;
         
         blockers = this.get(x1,y1, x2,y2).remove(agent).end();
@@ -104,22 +108,22 @@ QuadTree.subclass('PathMap', {
             if (bb.x2 <= B.x1 && x2 >= B.x1) {
                 msg += 'left';
                 side = new Line(B.x1,B.y1, B.x1,B.y2);
-                to   = trj.pointAtX(B.x1-bw-offX-1);
+                to   = trj.pointAtX(B.x1-offX-1);
                 
             } else if (bb.x1 >= B.x2 && x1 <= B.x2) {
                 msg += 'right';
                 side = new Line(B.x2,B.y1, B.x2,B.y2);
-                to   = trj.pointAtX(B.x2-offX+1);
+                to   = trj.pointAtX(B.x2+ro.x+1);
                 
             } else if (bb.y2 <= B.y1 && y2 >= B.y1) {
                 msg += 'top';
                 side = new Line(B.x1,B.y1, B.x2,B.y1);
-                to   = trj.pointAtY(B.y1-bh-offY-1);
+                to   = trj.pointAtY(B.y1-offY-1);
                 
             } else if (bb.y1 >= B.y2 && y1 <= B.y2) {
                 msg += 'bottom';
                 side = new Line(B.x1,B.y2, B.x2,B.y2);
-                to   = trj.pointAtY(B.y2-offY+1);
+                to   = trj.pointAtY(B.y2+ro.y+1);
             }
             
             msg += ' side';
index f406acc..edace1b 100644 (file)
@@ -3,6 +3,7 @@ var Y     = require('Y').Y
 ,   Vec   = math.Vec
 ,   Line  = math.Line
 ,   Rect  = math.Rect
+,   BoundingBox = require('ezl/loc').BoundingBox
 ,   Thing = require('tanks/thing/thing').Thing
 ,
 
@@ -172,8 +173,7 @@ Line.subclass('Trajectory', {
             to = this.stepTo(t, bb);
             if (this.halt) break;
             
-            // FIXME: bb.add?
-            bb = new Rect(to.x,to.y, to.x+bw,to.y+bh);
+            bb = new BoundingBox(to.x,to.y, to.x+bw,to.y+bh);
             
         } while (dt > 0);
         
index 64f9125..ab5215a 100644 (file)
@@ -90,7 +90,7 @@ Tank.subclass('PlayerTank', {
         var toLoc = this.loc.moveByDir(dir, (this.stats.move * SQUARETH))
         
         ,   x = toLoc.x, y = toLoc.y
-        ,   bb = this.boundingBox.reloacte(x,y)
+        ,   bb = this.boundingBox.relocate(x,y)
         
         ,   blockers = this.game.pathmap.get(bb.x1,bb.y1, bb.x2,bb.y2).remove(this)
         ;
index 4c142f1..1d81dbe 100644 (file)
@@ -25,7 +25,6 @@ Thing.subclass('Tank', function(Tank){
         turretColor : '#1C625B',
         barrelColor : '#D43B24',
         
-        
         // Bounding box size
         width  : REF_SIZE*0.55,
         height : REF_SIZE*0.55,
@@ -297,7 +296,7 @@ Thing.subclass('Tank', function(Tank){
     function moveByAngle(theta, targetX,targetY){
         var abs = Math.abs
         ,   bb  = this.boundingBox, w2 = bb.width/2, h2 = bb.height/2
-        ,   loc = this.loc, mid = bb.midpoint()
+        ,   loc = this.loc, mid = bb.midpoint
         ,   to  = loc.moveByAngle(theta, this.stats.move * SQUARETH)
         ;
         
@@ -308,7 +307,7 @@ Thing.subclass('Tank', function(Tank){
         if ( targetY !== undefined && abs(loc.y-to.y) > abs(loc.y-targetY) )
             to.setXY(to.x, targetY);
         
-        var nbb = bb.add(to.x,to.y)
+        var nbb = bb.relocated(to.x,to.y)
         ,   blockers = this.game.pathmap.get(nbb.x1,nbb.y1, nbb.x2,nbb.y2).remove(this)
         ;
         
@@ -353,29 +352,6 @@ Thing.subclass('Tank', function(Tank){
         ,   path  = this.lastPath    = pm.path(start, end, this.id)
         ,   to    = this.currentMove = path.shift()
         ;
-        
-        // VVV We only really need this code if we're going to recalculate before we reach the currentMove
-        
-        // we may need to move closer to start if we occupy multiple grid-squares
-        // var tosq = pm.vec2Square(to), manhattan = Vec.manhattan
-        // ,   bb = this.boundingBox
-        // ,   tl = pm.vec2Square(bb.x1,bb.y1), tr = pm.vec2Square(bb.x2,bb.y1)
-        // ,   bl = pm.vec2Square(bb.x1,bb.y2), br = pm.vec2Square(bb.x2,bb.y2)
-        // ,   straddles = [tl, tr, bl, br]
-        // ;
-        // 
-        // 
-        // if ( !tl.equals(br) ) {
-        //     tl.to = pm.vec2Square(bb.x1,bb.y1); tr.to = pm.vec2Square(mid.x,bb.y1);
-        //     bl.to = pm.vec2Square(bb.x1,mid.y); br.to = pm.vec2Square(mid.x,mid.y);
-        //     straddles.sort(function(a,b){
-        //         return Y.op.cmp(manhattan(a,tosq), manhattan(b,tosq));
-        //     });
-        //     to = pm.square2Vec(straddles[0].to).add(pm.gridSquareMidPt);
-        //     path.unshift(to);
-        // }
-        
-        // console.log('start:', start, 'straddles:', straddles.map(pm.square2Vec.bind(pm)), 'end:', end, 'next:', to);
     };
     
     
@@ -386,17 +362,18 @@ Thing.subclass('Tank', function(Tank){
     
     this['getTurretLoc'] =
     function getTurretLoc(){
-        var loc    = this.loc, mid = this.midpoint
+        var WIGGLE = 8
+        ,   loc    = this.loc, mid = this.midpoint
         ,   barrel = this.barrel
         
         ,   theta  = barrel.transform.rotate
         ,   sin = Math.sin(theta),  cos = Math.cos(theta)
-        ,   len = barrel.boundingBox.width
+        ,   len = barrel.boundingBox.width + WIGGLE
         
         ,   x = mid.x + len*cos
         ,   y = mid.y + len*sin
         ;
-        // console.log('getTurretLoc()', 'loc:', loc, 'bbb.(x2,y2):', [bbb.x2,bbb.y2], '(x,y):', [x,y]);
+        // console.log('getTurretLoc()', 'loc:', loc, '(x,y):', [x,y]);
         return new Vec(x,y);
     };
     
@@ -423,6 +400,7 @@ Thing.subclass('Tank', function(Tank){
         
         this.shape = 
             new Rect(w,h)
+                .origin(this.originX,this.originY)
                 .position(this.loc.x, this.loc.y)
                 .fill(this.bodyColor)
                 .appendTo( parent ) ;
index 4c5eeb5..8c29cf9 100644 (file)
@@ -13,15 +13,6 @@ Thing =
 exports['Thing'] =
 new evt.Class('Thing', {
     
-    init : function init(align){
-        this.id    = Thing.THING_ID++;
-        this.align = align || 0;
-        this.boundingBox = new BoundingBox(0,0, this.width,this.height, this.originX,this.originY);
-        
-        this.fillStats();
-        this.createCooldowns();
-    },
-    
     // Attributes
     stats: {
         hp        : 1,          // health
@@ -59,24 +50,28 @@ new evt.Class('Thing', {
     width  : REF_SIZE,
     height : REF_SIZE,
     
-    set  : Y.op.set.methodize(),
-    attr : Y.op.attr.methodize(),
-    
     
-    dealDamage : function dealDamage(d, source){
-        this.stats.hp -= d;
-        
-        if (this.stats.hp <= 0)
-            this.destroy();
+    init : function init(align){
+        this.id    = Thing.THING_ID++;
+        this.align = align || 0;
+        this.boundingBox = new BoundingBox(0,0, this.width,this.height, this.originX,this.originY);
         
-        return this;
+        this.fillStats();
+        this.createCooldowns();
     },
     
+    set  : Y.op.set.methodize(),
+    attr : Y.op.attr.methodize(),
+    
+    
     position : function position(x,y){
-        var bb        = this.boundingBox.relocate(x,y);
-        this.loc      = bb.absOrigin;
+        if (x === undefined && y === undefined)
+            return this.loc;
+        
+        var bb  = this.boundingBox.relocate(x,y)
+        ,   loc = this.loc = bb.absOrigin;
         this.midpoint = bb.midpoint;
-        if (this.shape) this.shape.position(x,y);
+        if (this.shape) this.shape.position(loc.x,loc.y);
         return this;
     },
     
@@ -114,6 +109,16 @@ new evt.Class('Thing', {
         return this;
     },
     
+    dealDamage : function dealDamage(d, source){
+        this.stats.hp -= d;
+        
+        if (this.stats.hp <= 0)
+            this.destroy();
+        
+        return this;
+    },
+    
+    
     /**
      * Calculates the location of the bullet-spawning point on this Thing.
      */
index 5183abf..f3fb59c 100644 (file)
@@ -13,11 +13,11 @@ Rect.subclass('Grid', {
     createCanvasGrid : true,
     
     
-    init : function init(cols,rows, size){
+    init : function init(cols,rows, side){
         this.cols = cols;
         this.rows = rows;
-        this.size = size;
-        Rect.init.call(this, cols*size, rows*size);
+        this.side = side;
+        Rect.init.call(this, cols*side, rows*side);
     },
     
     drawShape : function drawShape(ctx){
@@ -25,7 +25,7 @@ Rect.subclass('Grid', {
         // if (this.canvas) this.canvas.remove();
         
         var cols = this.cols, rows = this.rows
-        ,   size = this.size
+        ,   side = this.side
         ,   w    =  this.canvasWidth
         ,   h    =  this.canvasHeight
         ;
@@ -36,7 +36,7 @@ Rect.subclass('Grid', {
                 var row = $('<tr class="row row'+y+'" />').appendTo(tbody);
                 Y(0, cols).forEach(function(x){
                     $('<td class="cell cell'+x+'_'+y+' col'+x+'">'+x+','+y+'</td>')
-                        .width(size).height(size)
+                        .width(side).height(side)
                         .appendTo(row);
                 }, this);
             }, this);
@@ -55,12 +55,12 @@ Rect.subclass('Grid', {
             ctx.lineWidth   = this.lineWidth;
             ctx.strokeStyle = this.strokeStyle;
             
-            for (var row=0, y=0; row<=rows; y = (++row) * size){
+            for (var row=0, y=0; row<=rows; y = (++row) * side){
                 ctx.moveTo(0, y);
                 ctx.lineTo(w, y);
             }
             
-            for (var col=0, x=0; col<=cols; x = (++col) * size){
+            for (var col=0, x=0; col<=cols; x = (++col) * side){
                 ctx.moveTo(x, 0);
                 ctx.lineTo(x, h);
             }
index 134e339..1e6f086 100644 (file)
@@ -73,6 +73,9 @@ function main(){
     
     setupGame();
     setupUI();
+    
+    // $('#welcome').hide();
+    // $('#overlay').hide();
 }
 
 function gameExists(){ return !!tanks.currentGame; }
index 0fa526b..261302e 100644 (file)
@@ -2,7 +2,10 @@ REF_SIZE = 50;
 
 Y     = require('Y').Y;
 ezl   = require('ezl');
+math  = require('ezl/math');
+loc   = require('ezl/loc');
 shape = require('ezl/shape');
+
 Grid  = require('tanks/ui/grid').Grid;
 
 
@@ -19,7 +22,6 @@ $(function(){
     grid.createTableGrid = false;
     grid.lineWidth = 1.0;
     grid.strokeStyle = '#E0E0E0'; //'#EEEEEE'; //
-    grid.draw();
     
     // Draw axes
     shape.Line // X Axis
@@ -35,6 +37,17 @@ $(function(){
         .width(w).height(h)
         .appendTo(grid);
     
+    R = shape.Rect
+        .fromPoints(100,100, 150,150)
+        .fill('#E73075')
+        .appendTo(plot);
+    R.title(R.boundingBox+'');
     
+    C = new shape.Circle(25)
+        .position(150,150)
+        .fill('#2E62C9')
+        .appendTo(plot);
+    C.title(C.boundingBox+'');
     
+    grid.draw();
 });