Checkpoint on positioning mess.
authordsc <david.schoonover@gmail.com>
Sat, 11 Dec 2010 09:39:22 +0000 (01:39 -0800)
committerdsc <david.schoonover@gmail.com>
Sat, 11 Dec 2010 09:39:22 +0000 (01:39 -0800)
15 files changed:
src/Y/class.cjs
src/Y/type.cjs
src/evt.cjs
src/ezl/layer.cjs
src/ezl/loc/boundingbox.cjs
src/ezl/loc/loc.cjs
src/ezl/math/rect.cjs
src/ezl/math/vec.cjs
src/ezl/shape/polygon.cjs
src/tanks/game.cjs
src/tanks/map/pathmap.cjs
src/tanks/map/wall.cjs
src/tanks/thing/bullet.cjs
src/tanks/thing/tank.cjs
src/tanks/thing/thing.cjs

index 2fc6520..73015eb 100644 (file)
@@ -209,4 +209,3 @@ exports['YBase']       = YBase;
 // exports['instantiate'] = instantiate;
 // exports['fabricate']   = fabricate;
 
-
index 9ff3782..1b04091 100644 (file)
@@ -12,6 +12,7 @@ var undefined
 ,   FN = "constructor"
 ,   PT = "prototype"
 ,   OP = _Object[PT]
+,   FP = _Function[PT]
 
 ,   slice    = _Array[PT].slice
 ,   getProto = _Object.getPrototypeOf
@@ -66,8 +67,14 @@ function isPlainObject( obj ){
 }
 
 function type( o ) {
+    if ( o === null || o === undefined )
+        return o;
+    
+    // If this is a Y.Class or similar, it will help us out
+    if (o.__class__)
+        return o.__class__;
+    
     switch ( typeof(o) ) {
-        case "undefined" : return undefined;
         case "string"    : return _String;
         case "number"    : return _Number; // Note: NaN and Infinity are Number literals
         case "boolean"   : return _Boolean;
@@ -75,19 +82,15 @@ function type( o ) {
         case "function" :
             // If the function has a user-specified prototype, we can probably assume
             // it's meant to be a class constructor (and therefore, a type)
-            if ( o[PT] && o[PT] !== _Function[PT] )
+            var oP = o[PT];
+            if ( oP && !(oP === FP || oP === _Function[PT]) )
                 return o;
             else
                 return _Function;
         
         case "object" :
         default :
-            // Null is an object, obv
-            if ( o === null )
-                return null;
-            
-            return KNOWN_CLASSES[o.className] || o.__class__
-                || (o[FN] && o[FN] !== _Object) ? o[FN] : _Object;
+            return (o[FN] && o[FN] !== _Object) ? o[FN] : _Object;
     }
 }
 
index 345db7a..010fc87 100644 (file)
@@ -37,7 +37,8 @@ var Y       = require('Y').Y
 ,   getDesc  = _Object.getOwnPropertyDescriptor
 ,   setDesc  = _Object.defineProperty
 
-,   classToString   = function toString(){ return this.className+"()"; }
+,   objToString   = _Object[P].toString
+,   classToString = function toString(){ return this.className+"()"; }
 ;
 
 // Private delegating constructor -- must be defined for every
index 1111c0d..dfc5aad 100644 (file)
@@ -54,8 +54,8 @@ Y.subclass('Layer', {
         this.posBleed = new Loc(0,0);
         
         this.boundingBox = new BoundingBox(0,0, 0,0);
+        this._origin = this.boundingBox.origin;
         
-        this._origin = new Loc('50%','50%');
         this.transform = {
             rotate    : 0,
             scale     : new Loc(1.0,1.0),
@@ -148,20 +148,22 @@ Y.subclass('Layer', {
         
         this.layerWidth = w;
         
-        var origin = this._origin
+        var bb = this.boundingBox.resize(w, this.layerHeight)
+        ,   ro = bb.relOrigin
         ,   nb = this.negBleed
-        ,   v  = this.canvasWidth = Math.ceil(w + nb.x + this.posBleed.x); // HTMLCanvas.width is a long
+        ,   cw = this.canvasWidth = Math.ceil(w + nb.x + this.posBleed.x); // HTMLCanvas.width is a long
         
-        this.boundingBox = this.boundingBox.resize(w, this.layerHeight);
-        this.layer.width(w).css('margin-left', (-nb.x)+'px')
+        this.layer.css({
+            'width'       : w,
+            'left'        : bb.x1,
+            'margin-left' : -ro.x
+        });
         
-        // this.canvas.width(v);
         this.canvas.css({
-            'width' : v+'px',
-            'margin-left' : (-nb)+'px'
+            'width'       : cw,
+            'margin-left' : -nb.x
         });
-        this.canvas[0].width = v;
-        
+        this.canvas[0].width = cw;
         
         return this;
     },
@@ -171,17 +173,23 @@ Y.subclass('Layer', {
             return this.layerHeight;
         
         this.layerHeight = h;
-        this.boundingBox =  this.boundingBox.resize(this.layerWidth, h);
-        
-        var nb = this.negBleed.y
-        ,   v  = this.canvasHeight = Math.ceil(h + nb + this.posBleed.y); // HTMLCanvas.height is a long
-        this.layer.height(h).css('margin-top', (-nb)+'px')
-        this.canvas.height(v);
-        // this.canvas.css({
-        //     'height' : v+'px',
-        //     'margin-top' : (-nb)+'px'
-        // });
-        this.canvas[0].height = v;
+        
+        var bb = this.boundingBox.resize(this.layerWidth, h)
+        ,   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
+        });
+        
+        this.canvas.css({
+            'height'     : ch,
+            'margin-top' : -nb.y
+        });
+        this.canvas[0].height = ch;
         
         return this;
     },
@@ -209,22 +217,13 @@ Y.subclass('Layer', {
             return this.layer.position();
         
         if ( Y.isPlainObject(x) ){
-            y = x.y;
-            x = x.x;
+            y = x.y; x = x.x;
         }
         
-        // if (pos.x !== undefined)  pos.x -= this.offsetX;
-        // if (pos.y !== undefined)  pos.y -= this.offsetY;
-        
-        this.boundingBox = this.boundingBox.relocate(x,y);
-        this.loc = this.boundingBox.midpoint();
-        
-        var origin = this.origin();
-        this.css({ 
-            'left'        : x,
-            'top'         : y,
-            'margin-left' : -origin.x,
-            'margin-top'  : -origin.y
+        var bbox = this.boundingBox.relocate(x,y);
+        this.css({
+            'left' : bbox.x1,
+            'top'  : bbox.y1
         });
         return this;
     },
@@ -257,7 +256,7 @@ Y.subclass('Layer', {
     css : makeDelegate('css'),
     
     /** Position relative to document. */
-    offset : makeDelegate('offset'),
+    // offset : makeDelegate('offset'),
     
     
     
@@ -294,12 +293,12 @@ Y.subclass('Layer', {
      * to all sublayers (preserving knowledge of their individual scaling).
      */
     scale : function scale(sx,sy){
-        var o = this.transform.scale;
+        var ts = this.transform.scale;
         if (arguments.length === 0)
-            return o.absolute(this.layerWidth, this.layerHeight);
+            return ts;
         
-        o.x = sx;
-        o.y = sy;
+        ts.x = sx;
+        ts.y = sy;
         this.dirty = true;
         return this._applyTransforms();
     },
@@ -308,13 +307,13 @@ Y.subclass('Layer', {
      * Translates draw calls by (x,y) within this layer only. This allows you to
      * functionally move the coordinate system of the layer.
      */
-    translate : function translate(x,y){
-        var o = this.transform.translate;
+    translate : function translate(tx,ty){
+        var tt = this.transform.translate;
         if (arguments.length === 0)
-            return o.absolute(this.layerWidth, this.layerHeight);
+            return tt;
         
-        o.x = x;
-        o.y = y;
+        tt.x = tx;
+        tt.y = ty;
         this.dirty = true;
         return this;
     },
index 7e17ea2..3145a81 100644 (file)
@@ -1,27 +1,89 @@
 var Y = require('Y').Y
+,   Loc  = require('ezl/loc/loc').Loc
 ,   math = require('ezl/math')
 ,   Vec  = math.Vec
 ,   Line = math.Line
 ,   Rect = math.Rect
+
+,   X1 = 0, Y1 = 1
+,   X2 = 2, Y2 = 3
 ,
 
+
 BoundingBox =
 exports['BoundingBox'] =
 Rect.subclass('BoundingBox', {
     
-    attr : Y.attr.methodize(),
+    init : function initRect(_x1,_y1, _x2,_y2, originX, originY){
+        Rect.init.call(this, _x1,_y1, _x2,_y2);
+        
+        if (originX === undefined) originX = '50%';
+        if (originY === undefined) originY = '50%';
+        this._origin = new Loc(originX,originY);
+    },
+    
+    /**
+     * Changes origin definition without moving the bounds.
+     * 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; },
+    
+    set originY(v){ this._origin.y = v; return v; },
+    get originY(){ return this._origin.absolute(this.width,this.height, this.x1,this.x2).y; },
+    
+    /**
+     * Accessor for the realized numeric origin.
+     */
+    get absOrigin() { return this._origin.absolute(this.width,this.height, this.x1,this.x2); },
+    get relOrigin() { return this._origin.absolute(this.width,this.height); },
+    
+    get origin(){ return this._origin; },
     
     relocate : function relocate(x,y){
-        return new BoundingBox(x,y, x+this.width,y+this.height);
+        var _x1 = this[X1], _y1 = this[Y1]
+        ,   _x2 = this[X2], _y2 = this[Y2]
+        
+        ,   abs = this._origin.absolute(_x1-_x1, _y2-_y1, _x1,_y1)
+        ,   dx1 = _x1 - abs.x, dy1 = _y1 - abs.y
+        ,   dx2 = _x2 - abs.x, dy2 = _y2 - abs.y
+        
+        ,   x1 = x + dx1, y1 = y + dy1
+        ,   x2 = x + dx2, y2 = y + dy2
+        ;
+        return this.set4(x1,y1, x2,y2);
     },
     
     resize : function resize(w,h){
-        var x = this.x1, y = this.y1;
-        return new BoundingBox(x,y, x+w,y+h);
+        var x1 = this[X1], y1 = this[Y1]
+        ,   x2 = this[X2], y2 = this[Y2]
+        ,   wOld = x2-x1, hOld = y2-y1
+        
+        ,   p, abs, diff, o = this._origin
+        ,   xp = o.xPercentage, yp = o.yPercentage
+        ;
+        if ( xp !== null ) {
+            diff = w - wOld;
+            abs = x1 + xp*wOld;
+            x1 = abs - xp*diff;
+            x2 = abs + (1-xp)*diff;
+        } else
+            x2 = x1 + w;
+        
+        if ( yp !== null ) {
+            diff = h - hOld;
+            abs = y1 + yp*hOld;
+            y1 = abs - yp*diff;
+            y2 = abs + (1-yp)*diff;
+        } else
+            y2 = y1 + h;
+        
+        return this.set4(x1,y1, x2,y2);
     },
     
     clone : function clone(){
-        return new BoundingBox(this[0],this[1], this[2],this[3]);
+        var o = this._origin;
+        return new BoundingBox(this[X1],this[Y1], this[X2],this[Y2], o[X1], o[Y1]);
     }
     
 });
index edd623c..67471d0 100644 (file)
@@ -17,24 +17,6 @@ Y.subclass('Loc', new Vec(0,0), {
     //     Vec.init.call(this, x,y);
     // },
     
-    set : function set(k, v, def){
-        v = (v !== undefined ? v : def);
-        switch (k) {
-            case 'x': case 0:
-                this.x = this[0] = v; break;
-            case 'y': case 1:
-                this.y = this[1] = v; break;
-            default:
-                this[k] = v;
-        }
-        return this;
-    },
-    attr : Y.attr.methodize(),
-    
-    clone : function clone(){
-        return new Loc(this.x, this.y);
-    },
-    
     moveBy : function moveBy(x,y){
         return new Loc(this.x+x, this.y+y);
     },
@@ -53,13 +35,19 @@ Y.subclass('Loc', new Vec(0,0), {
         return Loc.Square.fromLoc(this.x, this.y);
     },
     
+    get xIsPercentage(){ return Y.isString(this.x); },
+    get yIsPercentage(){ return Y.isString(this.x); },
+    
+    get xPercentage(){ var x = this.x; return Y.isString(x) ? parseFloat(x.slice(0,-1))/100 : null; },
+    get yPercentage(){ var y = this.y; return Y.isString(y) ? parseFloat(y.slice(0,-1))/100 : null; },
+    
     /**
      * Converts relative locations like ('50%','50%') to a numeric location.
      */
-    absolute : function absolute(w,h){
-        var x = this.x, y = this.y
-        return new Loc( Y.isString(x) ? parseFloat(x.slice(0,-1))/100 * w : x
-                      , Y.isString(y) ? parseFloat(y.slice(0,-1))/100 * h : y );
+    absolute : function absolute(w,h, x1,y1){
+        var x = this.x, y = this.y;
+        return new Loc( (x1 || 0) + (Y.isString(x) ? parseFloat(x.slice(0,-1))/100 * w : x)
+                      , (y1 || 0) + (Y.isString(y) ? parseFloat(y.slice(0,-1))/100 * h : y) );
     },
     
     toUnits : function toUnits(units){
index 8420caa..d1b8e85 100644 (file)
@@ -1,5 +1,7 @@
 var Y = require('Y').Y
 ,   Vec = require('ezl/math/vec').Vec
+,   X1 = 0, Y1 = 1
+,   X2 = 2, Y2 = 3
 ,
 
 
@@ -9,45 +11,53 @@ Y.subclass('Rect', [], {
     
     init : function initRect(_x1,_y1, _x2,_y2){
         if (_x1 instanceof Array && _y1 instanceof Array) {
-            _y2 = _y1[1]; _x2 = _y1[0];
-            _y1 = _x1[1]; _x1 = _x1[0];
+            _y2 = _y1[Y1]; _x2 = _y1[X1];
+            _y1 = _x1[Y1]; _x1 = _x1[X1];
         }
         var x1 = Math.min(_x1,_x2), x2 = Math.max(_x1,_x2)
         ,   y1 = Math.min(_y1,_y2), y2 = Math.max(_y1,_y2);
         
         this.length = 4;
-        this[0] = x1; this[1] = y1;
-        this[2] = x2; this[3] = y2;
+        this.set4(x1,y1, x2,y2);
     },
     
-    get x1(){ return this[0]; }, set x1(v){ this[0] = v; },
-    get y1(){ return this[1]; }, set y1(v){ this[1] = v; },
-    get x2(){ return this[2]; }, set x2(v){ this[2] = v; },
-    get y2(){ return this[3]; }, set y2(v){ this[3] = v; },
+    /**
+     * @protected
+     */
+    set4 : function set4(x1,y1, x2,y2){
+        this[X1] = x1; this[Y1] = y1;
+        this[X2] = x2; this[Y2] = y2;
+        return this;
+    },
+    
+    get x1(){ return this[X1]; }, set x1(v){ this[X1] = v; return v; },
+    get y1(){ return this[Y1]; }, set y1(v){ this[Y1] = v; return v; },
+    get x2(){ return this[X2]; }, set x2(v){ this[X2] = v; return v; },
+    get y2(){ return this[Y2]; }, set y2(v){ this[Y2] = v; return v; },
+    
+    get p1(){  return new Vec(this[X1],this[Y1]); },
+    set p1(v){ this[X1] = v.x; this[Y1] = this.y; return v; },
+    get p2(){  return new Vec(this[X2],this[Y2]); },
+    set p2(v){ this[X2] = v.x; this[Y2] = this.y; return v; },
     
-    get p1(){  return new Vec(this[0],this[1]); },
-    set p1(v){ this[0] = v.x; this[1] = this.y  },
-    get p2(){  return new Vec(this[2],this[3]); },
-    set p2(v){ this[2] = v.x; this[3] = this.y  },
+    get width(){  return this[X2] - this[X1]; },
+    get height(){ return this[Y2] - this[Y1]; },
     
-    // TODO: .origin
-    // TODO: Scale w/h proportionally if .origin is percentage
-    get width(){  return this[2] - this[0]; },
-    get height(){ return this[3] - this[1]; },
+    attr : Y.attr.methodize(),
     
     get midpoint(){
-        return new Vec( this[0] + (this[2]-this[0]) / 2
-                      , this[1] + (this[3]-this[1]) / 2 );
+        return new Vec( this[X1] + (this[X2]-this[X1]) / 2
+                      , this[Y1] + (this[Y2]-this[Y1]) / 2 );
     },
     
     contains : function contains(x,y){
-        return ( x >= this[0] && x <= this[2]  &&
-                 y >= this[1] && y <= this[3]  );
+        return ( x >= this[X1] && x <= this[X2]  &&
+                 y >= this[Y1] && y <= this[Y2]  );
     },
     
     intersects : function intersects(line){
-        var x1 = this[0], x2 = this[2]
-        ,   y1 = this[1], y2 = this[3]
+        var x1 = this[X1], x2 = this[X2]
+        ,   y1 = this[Y1], y2 = this[Y2]
         ,   cx1,cy1, cx2,cy2 ;
         return (  ( (cx1 = line.calcX(y1)) >= x1 && cx1 <= x2 )
                || ( (cy1 = line.calcY(x1)) >= y1 && cy1 <= y2 )
@@ -56,7 +66,7 @@ Y.subclass('Rect', [], {
     },
     
     clone : function clone(){
-        return new Rect(this[0],this[1], this[2],this[3]);
+        return new this.__class__(this[X1],this[Y1], this[X2],this[Y2]);
     },
     
     toString : function toString(){
index a3cb5ac..19cf627 100644 (file)
@@ -1,4 +1,5 @@
 var Y = require('Y').Y
+,   _X = 0, _Y = 1
 ,
 
 /**
@@ -9,48 +10,51 @@ exports['Vec'] =
 new Y.Class('Vec', [], {
     
     init : function init(x, y){
-        this.length = 2;
-        
         if ( x instanceof Array ) {
-            y = x[1]; x = x[0];
+            y = x[_Y]; x = x[_X];
         }
+        this.length = 2;
         this.setXY(x,y);
     },
     
-    equals : function equals(b){
-        return (this.x === b.x) && (this.y === b.y);
-    },
-    
-    clone : function clone(){
-        return new Vec(this.x, this.y);
-    },
+