Checkpoint on fixing the positioning mess.
authordsc <david.schoonover@gmail.com>
Thu, 9 Dec 2010 22:09:26 +0000 (14:09 -0800)
committerdsc <david.schoonover@gmail.com>
Thu, 9 Dec 2010 22:09:26 +0000 (14:09 -0800)
29 files changed:
src/Y/class.cjs
src/Y/core.cjs
src/Y/delegate.cjs
src/Y/modules/metaclass.js
src/Y/op.cjs
src/Y/types/array.cjs
src/evt.cjs
src/ezl/layer.cjs
src/ezl/loc/boundingbox.cjs
src/ezl/math/rect.cjs
src/ezl/shape/circle.cjs
src/ezl/shape/line.cjs
src/ezl/shape/polygon.cjs
src/ezl/shape/rect.cjs
src/ezl/shape/shape.cjs
src/tanks/map/pathmap.cjs
src/tanks/map/trajectory.cjs
src/tanks/thing/player.cjs
src/tanks/thing/tank.cjs
www/commonjs.php [new file with mode: 0644]
www/index.php
www/scripts.php [new file with mode: 0644]
www/test [deleted symlink]
www/test/math/index.php [copied from test/math/index.php with 94% similarity]
www/test/math/test-math.js [moved from test/math/math.test.js with 100% similarity]
www/test/shapes/index.php [moved from test/math/index.php with 76% similarity]
www/test/shapes/test-shapes.js [new file with mode: 0644]
www/test/uki/index.php [moved from test/uki/index.php with 100% similarity]
www/test/uki/test-uki.js [moved from test/uki/test-uki.js with 100% similarity]

index 0aa02c8..2fc6520 100644 (file)
@@ -14,8 +14,11 @@ var type       = require('Y/type')
 ,   _String   = globals.String
 ,   _Number   = globals.Number
 
-,   hasOwn   = _Object.prototype.hasOwnProperty
+,   P        = 'prototype'
+,   hasOwn   = _Object[P].hasOwnProperty
 ,   getProto = _Object.getPrototypeOf
+,   getDesc  = _Object.getOwnPropertyDescriptor
+,   setDesc  = _Object.defineProperty
 
 ,   KNOWN_CLASSES = type.type.KNOWN_CLASSES
 ,   classToString = function toString(){ return this.className+"()"; }
@@ -56,7 +59,7 @@ function _Class() {
  * @param {Object} [members] Instance members to add to the new class's prototype; a class
  * constructor can be supplied as `init`.
  * 
- * @returns {Class} A new Class.
+ * @return {Class} A new Class.
  */
 function Class(className, Parent, members) {
     var ClassFactory  = arguments.callee
@@ -81,7 +84,7 @@ function Class(className, Parent, members) {
         prototype = Parent;
         
     // Parent is a constructor: check ClassFactory
-    } else if (Parent.prototype instanceof ClassFactory) {
+    } else if (Parent[P] instanceof ClassFactory) {
         SuperClass = Parent;
         prototype  = Parent.fabricate();
         
@@ -90,7 +93,7 @@ function Class(className, Parent, members) {
         return new ClassFactory(className, Parent, members);
     
     } else {
-        parentMembers = Parent.prototype || {};
+        parentMembers = Parent[P] || {};
     }
     
     // Creates a new function with the appropriate name
@@ -109,13 +112,16 @@ function Class(className, Parent, members) {
     
     // Copy parent methods, then add new instance methods
     for (var k in parentMembers)
-        prototype[k] = parentMembers[k];
+        if ( hasOwn.call(parentMembers,k) )
+            setDesc(prototype, k, getDesc(parentMembers,k));
+        else
+            prototype[k] = parentMembers[k];
     
     if ( prototype.toString === toString )
         prototype.toString = classToString;
     
     // Fix Constructors, prototypes
-    NewClass.prototype = NewClass.fn = prototype;
+    NewClass[P] = NewClass.fn = prototype;
     prototype.constructor = prototype.__class__ = NewClass;
     NewClass.__super__ = SuperClass; // don't override NewClass.constructor -- it should be Function
     NewClass.className = prototype.className = className;
@@ -127,7 +133,7 @@ function Class(className, Parent, members) {
     // Or add new instance methods
     } else for (var k in members) {
         if ( hasOwn.call(members, k) )
-            prototype[k] = members[k];
+            setDesc(prototype, k, getDesc(members,k));
     }
     
     if (prototype.init) NewClass.init = YFunction(prototype.init);
@@ -139,7 +145,7 @@ function Class(className, Parent, members) {
 
 // Add metaprogramming data to Class object
 Class.__super__ = Object;
-Class.fn = Class.prototype;
+Class.fn = Class[P];
 Class.fn.__class__ = Class;
 Class.className = Class.fn.className = "Class";
 
index 620723c..ded75cc 100644 (file)
@@ -1,10 +1,19 @@
 // Generic Collection Functions
 
 var undefined
+
 ,   globals   = (function(){ return this; })()
+,   _Object   = globals.Object
 ,   _Function = globals.Function
 ,   _Array    = globals.Array
-,   slice     = _Array.prototype.slice
+
+,   getProto = _Object.getPrototypeOf
+,   getDesc  = _Object.getOwnPropertyDescriptor
+,   setDesc  = _Object.defineProperty
+
+,   P        = 'prototype'
+,   hasOwn   = _Object[P].hasOwnProperty
+,   slice    = _Array[P].slice
 
 ,   type      = require('Y/type')
 ;
@@ -97,14 +106,41 @@ function extend( A, B ){
 function extendall(A, donor){ return reduce(donor, attrvk, A); }
 function attrvk(o, v, k){     return attr(o, k, v, o[k]); }
 
+/**
+ * Fetches the descriptor for each property that is an accessor (getter/setter).
+ * @param {Object} o Object for inspection.
+ * @return {Object} A map of property to descriptor.
+ * nb. An Array is safer, but:
+ *  1) Object.defineProperties takes an Object
+ *  2) That'd be much worse to work with
+ */
+function accessors(o){
+    if ( !(o && typeof o === "object") )
+        return {};
+    return reduce(o, function(acc, v, k, obj){
+        
+        // Ignore inherited properties
+        if ( !hasOwn.call(obj,k) )
+            return acc;
+        
+        // Only yield accessors
+        var desc = getDesc(obj,k);
+        if ( !hasOwn.call(desc,'value') )
+            acc[k] = desc;
+        
+        return acc;
+    }, {});
+}
+
 
-exports['reduce']  = reduce;
-exports['map']     = map;
-exports['forEach'] = forEach;
-exports['filter']  = filter;
+exports['reduce']    = reduce;
+exports['map']       = map;
+exports['forEach']   = forEach;
+exports['filter']    = filter;
 
-exports['set']     = set;
-exports['attr']    = attr;
-exports['extend']  = extend;
+exports['set']       = set;
+exports['attr']      = attr;
+exports['extend']    = extend;
 
-exports['slice']   = slice;
+exports['accessors'] = accessors;
+exports['slice']     = slice;
index 8bc9e64..469a1e0 100644 (file)
@@ -108,6 +108,15 @@ function extend( A, B ){
 function extendall(A, donor){ return reduce(donor, attrvk, A); }
 function attrvk(o, v, k){     return attr(o, k, v, o[k]); }
 
+function accessors(o){
+    if ( !(o && typeof o === "object") )
+        return {};
+    
+    if ( notWrapped(o.accessors) )
+        return o.accessors.apply(o, slice.call(arguments,1));
+    
+    return core.accessors(o);
+}
 
 exports['reduce']  = reduce;
 exports['map']     = map;
@@ -117,3 +126,6 @@ exports['filter']  = filter;
 exports['set']     = set;
 exports['attr']    = attr;
 exports['extend']  = extend;
+
+exports['accessors'] = accessors;
+
index 3aebbbd..d4fdc85 100644 (file)
@@ -112,7 +112,7 @@ function _Class() {
  * @param {Object} [members] Instance members to add to the new class's prototype; a class
  * constructor can be supplied as `init`.
  * 
- * @returns {Class} A new Class.
+ * @return {Class} A new Class.
  */
 function Class(className, Parent, members){
     var ClassFactory  = arguments.callee
index 3b2971c..769cab3 100644 (file)
@@ -65,7 +65,9 @@ var core = require('Y/core')
             else
                 return obj;
         };
-    }
+    },
+    
+    end : function end(o){ return ((o && o.__y__) ? o.end() : o); }
     
 };
 
index c9f11e8..0bd0b4f 100644 (file)
@@ -1,6 +1,7 @@
 var Y           = require('Y/y').Y  // I *think* this is safe
 ,   del         = require('Y/delegate')
 ,   type        = require('Y/type')
+,   op          = require('Y/op')
 ,   mixin       = require('Y/utils').mixin
 ,   YCollection = require('Y/types/collection').YCollection
 
@@ -58,9 +59,6 @@ YCollection.subclass('YArray', function(YArray){
     function concat( donor ){
         var A = this._o;
         return new YArray(A.concat.apply( A, slice.call(arguments,0).map(unwrapY) ));
-        // return new YArray( slice.call(arguments).reduce(function(A, donor ){
-        //     return A.concat(donor instanceof YArray ? donor.end() : donor);
-        // }, this._o) );
     };
     
     this['extend'] =
@@ -90,22 +88,18 @@ YCollection.subclass('YArray', function(YArray){
                     acc.push(v);
                 return acc;
             }, new YArray(), this );
-        
-        // 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);
-        // });
     };
     
-    // this.zip =
-    // function zip(){
-    //     var sequences = new YArray(slice.call(arguments)).map( Y.limit(1) ).unshift(this);
-    //     return this.map(function(_, k){
-    //         return sequences.invoke('attr', k);
-    //     }).invoke('end');
-    // };
+    this['zip'] =
+    function zip(){
+        var sequences = new YArray(slice.call(arguments)).unshift(this._o)
+        ,   kget = op.curried.kget ;
+        return this.map(function(_, k){
+            return sequences.map(function(seq){
+                return del.attr(seq,k);
+            });
+        }); //.invoke('end');
+    };
     
     /**
      * Like map, but produces a YObject:
index 14b0090..345db7a 100644 (file)
@@ -29,9 +29,14 @@ var Y       = require('Y').Y
 
 ,   isFunction      = Y.isFunction
 ,   KNOWN_CLASSES   = Class.KNOWN_CLASSES = exports['KNOWN_CLASSES'] = {}
-,   getProto        = Object.getPrototypeOf
-,   hasOwn          = Object.prototype.hasOwnProperty
-,   objToString     = Object.prototype.toString
+
+,   P        = 'prototype'
+,   _Object  = Object
+,   hasOwn   = _Object[P].hasOwnProperty
+,   getProto = _Object.getPrototypeOf
+,   getDesc  = _Object.getOwnPropertyDescriptor
+,   setDesc  = _Object.defineProperty
+
 ,   classToString   = function toString(){ return this.className+"()"; }
 ;
 
@@ -77,7 +82,7 @@ function ConstructorTemplate() {
  * @param {Object} [members] Instance members to add to the new class's prototype; a class
  * constructor can be supplied as `init`.
  * 
- * @returns {Class} A new Class.
+ * @return {Class} A new Class.
  */
 function Class(className, Parent, members){
     var ClassFactory  = arguments.callee
@@ -133,9 +138,12 @@ function Class(className, Parent, members){
             NewClass[k] = v;
     }
     
-    // Copy parent methods
+    // Copy parent methods, then add new instance methods
     for (var k in parentMembers)
-        prototype[k] = parentMembers[k];
+        if ( hasOwn.call(parentMembers,k) )
+            setDesc(prototype, k, getDesc(parentMembers,k));
+        else
+            prototype[k] = parentMembers[k];
     
     if ( prototype.toString === objToString )
         prototype.toString = classToString;
@@ -149,7 +157,7 @@ function Class(className, Parent, members){
     
     NewClass.init = // XXX: This means subclasses will fire events.
     prototype.initialise =
-        function initialise(){
+        Y(function initialise(){
             var instance = this
             ,   init     = NewClass.prototype.init
             ;
@@ -168,7 +176,7 @@ function Class(className, Parent, members){
             });
             
             return instance;
-        };
+        });
     
     // Add class emitter
     var ParentEmitter = (Parent.__emitter__ ? Parent : ClassFactory)
@@ -182,7 +190,7 @@ function Class(className, Parent, members){
     // Or add new instance methods
     } else for (var k in members) {
         if ( hasOwn.call(members, k) )
-            prototype[k] = members[k];
+            setDesc(prototype, k, getDesc(members,k));
     }
     
     // Record for metaprogramming
@@ -215,8 +223,8 @@ Class.className = Class.fn.className = "Class";
  * Create a new instance and run delegate constructor if it exists.
  * Unlike the keyword `new`, instantiate can be applied.
  */
-function instantiate(){
-    var instance = this.fabricate();
+function instantiate(cls){
+    var instance = cls.fabricate();
     if ( instance.initialise )
         instance.initialise.apply(instance, arguments);
     return instance;
index 53f0f54..1111c0d 100644 (file)
@@ -28,8 +28,9 @@ Y.subclass('Layer', {
     ctx      : null,
     dirty    : true,
     
-    canvasWidth : 0,    layerWidth  : 0,
-    canvasHeight : 0,   layerHeight : 0,
+    
+    layerWidth  : 0,  canvasWidth : 0,
+    layerHeight : 0,  canvasHeight : 0,
     
     x: 0, y: 0, loc : null, // Position relative to parent
     
@@ -38,6 +39,7 @@ Y.subclass('Layer', {
     posBleed : null, // Loc
     
     // Transforms
+    _origin : null, // rotational origin
     transform : null, // Object
     useCanvasScaling : false, // default to CSS3 scaling
     
@@ -53,8 +55,8 @@ Y.subclass('Layer', {
         
         this.boundingBox = new BoundingBox(0,0, 0,0);
         
+        this._origin = new Loc('50%','50%');
         this.transform = {
-            origin    : new Loc('50%','50%'), // rotational origin
             rotate    : 0,
             scale     : new Loc(1.0,1.0),
             translate : new Loc(0,0) // translates canvas
@@ -120,7 +122,7 @@ Y.subclass('Layer', {
     },
     
     /**
-     * @returns The root of the scene graph.
+     * @return The root of the scene graph.
      */
     root : function root(){
         if (this.parent)
@@ -135,17 +137,7 @@ Y.subclass('Layer', {
     
     /// Attributes ///
     
-    
-    attr : function attr(key, value, def){
-        if (!key) return this;
-        
-        if ( Y.isPlainObject(key) ) {
-            for (var k in key)
-                this.attr(k, key[k]);
-            return this;
-        } else
-            return Y.op.attr(this, key, value, def);
-    },
+    attr : Y.attr.methodize(),
     
     /**
      * Changes the layer's width and then updates the canvas.
@@ -155,16 +147,19 @@ Y.subclass('Layer', {
             return this.layerWidth;
         
         this.layerWidth = w;
+        
+        var origin = this._origin
+        ,   nb = this.negBleed
+        ,   v  = 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')
         
-        var nb = this.negBleed.x
-        ,   v  = this.canvasWidth = Math.ceil(w + nb + this.posBleed.x);
-        this.layer.width(w).css('margin-left', (-nb)+'px')
-        this.canvas.width(v);
-        // this.canvas.css({
-        //     'width' : v+'px',
-        //     'margin-left' : (-nb)+'px'
-        // });
+        // this.canvas.width(v);
+        this.canvas.css({
+            'width' : v+'px',
+            'margin-left' : (-nb)+'px'
+        });
         this.canvas[0].width = v;
         
         
@@ -176,10 +171,10 @@ Y.subclass('Layer', {
             return this.layerHeight;
         
         this.layerHeight = h;
-        this.boundingBox = this.boundingBox.resize(this.layerWidth, h);
+        this.boundingBox =  this.boundingBox.resize(this.layerWidth, h);
         
         var nb = this.negBleed.y
-        ,   v  = this.canvasHeight = Math.ceil(h + nb + this.posBleed.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({
@@ -192,35 +187,45 @@ Y.subclass('Layer', {
     },
     
     /**
-     * position() -> object 
+     * position() -> {Loc}
      * Gets position of the layer relative to the parent.
+     * @return {Loc}
      */
     /**
-     * position(top, left) -> this
+     * position(x,y) -> {this}
      * Sets the position of this node, and then returns it.
-     * @param {Number|String|undefined} top If omitted, this method must be invoked with `undefined` as the first argument.
-     * @param {Number|String|undefined} left
+     * @param {Number|String|undefined} x
+     * @param {Number|String|undefined} y If omitted, this method must be invoked with `undefined` as the first argument.
+     * @return {this}
      */
     /**
-     * position(pos) -> this
+     * position(pos) -> {this}
      * Sets the position of this node, and then returns it.
-     * @param {Object} pos An object with "top" and/or "left" properties as in `position(top, left)`.
+     * @param {Object} pos An object with "x" and/or "y" properties as in `position(x,y)`.
+     * @return {this}
      */
-    position : function position(left, top){
-        if (top === undefined && left === undefined)
+    position : function position(x,y){
+        if (x === undefined && y === undefined)
             return this.layer.position();
         
-        if (top && Y.isPlainObject(top))
-            var pos = top;
-        else
-            var pos = { 'top': top, 'left':left };
+        if ( Y.isPlainObject(x) ){
+            y = x.y;
+            x = x.x;
+        }
+        
+        // if (pos.x !== undefined)  pos.x -= this.offsetX;
+        // if (pos.y !== undefined)  pos.y -= this.offsetY;
         
-        // if (pos.left !== undefined)  pos.left -= this.offsetX;
-        // if (pos.top  !== undefined)  pos.top  -= this.offsetY;
+        this.boundingBox = this.boundingBox.relocate(x,y);
+        this.loc = this.boundingBox.midpoint();
         
-        this.boundingBox = this.boundingBox.add(pos.left,pos.top);
-        this.loc = this.boundingBox.p1;
-        this.css(pos);
+        var origin = this.origin();
+        this.css({ 
+            'left'        : x,
+            'top'         : y,
+            'margin-left' : -origin.x,
+            'margin-top'  : -origin.y
+        });
         return this;
     },
     
@@ -259,10 +264,11 @@ Y.subclass('Layer', {
     /// Transformations ///
     
     /**
-     * Gets and sets the transformation origin.
+     * Gets and sets the origin-location for this shape, used for 
+     * position and rotation. Defaults to the midpoint.
      */
     origin : function origin(x,y){
-        var o = this.transform.origin;
+        var o = this._origin;
         if (arguments.length === 0)
             return o.absolute(this.layerWidth, this.layerHeight);
         
@@ -323,15 +329,16 @@ Y.subclass('Layer', {
             tfns.push('scale('+t.scale.x+','+t.scale.y+')');
         
         var trans = (tfns.length ? tfns.join(' ') : 'none')
-        ,   o = t.origin.toUnits()
+        ,   o = this._origin.toUnits('px')
         ,   origin = o.x+' '+o.y ;
-        this.layer.css(
-            ['', '-moz-', '-webkit-'].reduce(
+        this.layer.css(['', '-moz-', '-webkit-']
+            .reduce(
                 function(values, prefix){
                     values[prefix+'transform'] = trans;
                     values[prefix+'transform-origin'] = origin;
                     return values;
-                }, {}) );
+                },
+                {}) );
         return this;
     },
     
@@ -482,8 +489,8 @@ Y.subclass('Layer', {
     
     /// 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()+' )';
+        var pos = (this.layer ? this.position() : {y:NaN, x:NaN});
+        return this.className+'['+pos.x+','+pos.y+']( children='+this.children.size()+' )';
     }
 });
 
index f7ae7d5..7e17ea2 100644 (file)
@@ -8,67 +8,20 @@ var Y = require('Y').Y
 BoundingBox =
 exports['BoundingBox'] =
 Rect.subclass('BoundingBox', {
-    init : function initBoundingBox(x1,y1, x2,y2){
-        Rect.init.call(this, x1,y1, x2,y2);
-        
-        this.sides = {
-            top    : new Line(x1,y1, x2,y1),
-            bottom : new Line(x1,y2, x2,y2),
-            left   : new Line(x1,y1, x1,y2),
-            right  : new Line(x2,y1, x2,y2)
-        };
-    },
-    
-    set : function set(k, v, def){
-        v = (v !== undefined ? v : def);
-        
-        switch (k) {
-            case 'x1': case 0: case 'x':    this.x1 = this[0] = this.x = v;     break;
-            case 'y1': case 1: case 'y':    this.y1 = this[1] = this.y = v;     break;
-            case 'x2': case 2:              this.x2 = this[2] = v;              break;
-            case 'y1': case 3:              this.y2 = this[3] = v;              break;
-            
-            default: this[k] = v;
-        }
-        
-        this.width  = this.x2 - this.x1;
-        this.height = this.y2 - this.y1;
-        
-        return this._updateSides();
-    },
-    
-    _updateSides : function _updateSides(){
-        var s = this.sides
-        ,   x1 = this.x1,           y1 = this.y1
-        ,   x2 = this.x2,           y2 = this.y2
-        ,   dx1 = x1 !== s.top.x1,  dy1 = y1 !== s.top.y1
-        ,   dx2 = x2 !== s.top.x2,  dy2 = y2 !== s.left.y2
-        ;
-        
-        if ( dx1 || dy1 ) this.p1 = new Vec(x1,y1);
-        if ( dx2 || dy2 ) this.p2 = new Vec(x2,y2);
-        
-        if ( dx1 || dy1 || dx2 ) s.top    = new Line(x1,y1, x2,y1);
-        if ( dx1 || dx2 || dy2 ) s.bottom = new Line(x1,y2, x2,y2);
-        if ( dx1 || dy1 || dy2 ) s.left   = new Line(x1,y1, x1,y2);
-        if ( dy1 || dy2 || dx2 ) s.right  = new Line(x2,y1, x2,y2);
-        
-        return this;
-    },
     
     attr : Y.attr.methodize(),
     
-    add : function add(x,y){
+    relocate : function relocate(x,y){
         return new BoundingBox(x,y, x+this.width,y+this.height);
     },
     
     resize : function resize(w,h){
-        var x = this.x, y = this.y;
+        var x = this.x1, y = this.y1;
         return new BoundingBox(x,y, x+w,y+h);
     },
     
     clone : function clone(){
-        return new BoundingBox( this.p1.clone(), this.p2.clone() );
+        return new BoundingBox(this[0],this[1], this[2],this[3]);
     }
     
 });
index c5e8794..8420caa 100644 (file)
@@ -2,44 +2,52 @@ var Y = require('Y').Y
 ,   Vec = require('ezl/math/vec').Vec
 ,
 
+
 Rect =
 exports['Rect'] =
 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];
+    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];
         }
-    // 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];
-    //     }
-    //     var x1 = Math.min(_x1,_x2), x2 = Math.max(_x1,_x2)
-    //     ,   y1 = Math.min(_y1,_y2), y2 = Math.max(_y1,_y2);
+        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.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.p1 = new Vec(x1,y1);
-        this.p2 = new Vec(x2,y2);
+        this[0] = x1; this[1] = y1;
+        this[2] = x2; this[3] = 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; },
+    
+    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  },
+    
+    // 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]; },
+    
+    get midpoint(){
+        return new Vec( this[0] + (this[2]-this[0]) / 2
+                      , this[1] + (this[3]-this[1]) / 2 );
     },
     
     contains : function contains(x,y){
-        return ( x >= this.x1 && x <= this.x2  &&
-                 y >= this.y1 && y <= this.y2  );
+        return ( x >= this[0] && x <= this[2]  &&
+                 y >= this[1] && y <= this[3]  );
     },
     
     intersects : function intersects(line){
-        var x1 = Math.min(this.x1,this.x2), x2 = Math.max(this.x1,this.x2)
-        ,   y1 = Math.min(this.y1,this.y2), y2 = Math.max(this.y1,this.y2)
+        var x1 = this[0], x2 = this[2]
+        ,   y1 = this[1], y2 = this[3]
         ,   cx1,cy1, cx2,cy2 ;
         return (  ( (cx1 = line.calcX(y1)) >= x1 && cx1 <= x2 )
                || ( (cy1 = line.calcY(x1)) >= y1 && cy1 <= y2 )
@@ -47,14 +55,8 @@ Y.subclass('Rect', [], {
                || ( (cy2 = line.calcY(x2)) >= y1 && cy2 <= y2 ) );
     },
     
-    midpoint : function midpoint(){
-        return new Vec( this.x1 + this.width /2
-                      , this.y1 + this.height/2 );
-    },
-    
     clone : function clone(){
-        return new Rect( this.p1.clone()
-                       , this.p2.clone() );
+        return new Rect(this[0],this[1], this[2],this[3]);
     },
     
     toString : function toString(){
index 8e61bf6..00acd8b 100644 (file)
@@ -7,20 +7,24 @@ exports['Circle'] =
 Shape.subclass('Circle', {
     _cssClasses : 'ezl layer shape circle',
     
-    init : function initCircle(radius, centerTL){
+    init : function initCircle(radius){
         Shape.init.call(this);
+        this.radius(radius);
+    },
+    
+    radius : function radius(r){
+        if (r === undefined)
+            return this._radius;
         
-        var d = radius * 2;
-        this.radius = radius;
-        if (!centerTL)
-            this.negBleed.x = this.negBleed.y = radius;
+        var d = r * 2;
+        this.dirty = true;
+        this._radius = r;
         this.width(d).height(d);
-            // .origin(radius,radius);
+        return this;
     },
     
     drawShape : function drawShape(ctx){
-        var r  = this.radius, nb = this.negBleed;
-        ctx.arc(r-nb.x,r-nb.y, r, 0, Math.PI*2, false);
+        ctx.arc(0,0, this._radius, 0, Math.PI*2, false);
         ctx.fill();
         ctx.stroke();
     }
index 9de4298..34bc660 100644 (file)
@@ -1,9 +1,9 @@
 //#ensure "jquery"
 
-var Y = require('Y').Y
+var Y     = require('Y').Y
+,   math  = require('ezl/math')
 ,   Layer = require('ezl/layer').Layer
 ,   Shape = require('ezl/shape/shape').Shape
-,   math = require('ezl/math')
 ,
 
 Line =
@@ -46,7 +46,7 @@ Shape.subclass('Line', {
     },
     
     origin : function origin(x,y){
-        var o = this.transform.origin;
+        var o = this._origin;
         if (arguments.length === 0)
             return o.absolute(this.layerWidth, this.layerHeight);
         
index 80254fb..5b51520 100644 (file)
@@ -1,3 +1,5 @@
+// FIXME: Origin and Bleeds are busted for Polygons that want negative coords
+
 var Y     = require('Y').Y
 ,   Shape = require('ezl/shape/shape').Shape
 ,   Loc   = require('ezl/loc').Loc
@@ -27,6 +29,20 @@ Shape.subclass('Polygon', {
             // .origin(w/2, h/2);
     },
     
+    _calcDimension : function _calcDimension(which, values){
+        values.unshift(0);
+        var self = this
+        ,   neg = -1 * Math.min.apply(Math, values)
+        // ,   pos = Math.min(0, Math.max.apply(Max, values) - max)
+        ;
+        
+        // XXX: Busted
+        self.negBleed.attr(which, neg);
+        // self.posBleed.attr(which, pos);
+        
+        return values.map(function(v, i){ return (self[which+i] = v); });
+    },
+    
     drawShape : function drawShape(ctx){
         this.points.forEach(function(loc, i){
             ctx.lineTo(loc.x, loc.y);
index 6222886..563a441 100644 (file)
@@ -8,8 +8,9 @@ Shape.subclass('Rect', {
     
     init : function initRect(w,h){
         Shape.init.call(this);
-        this.width(w).height(h);
-            // .origin(w/2, h/2);
+        this.origin(0,0)
+            .width(w)
+            .height(h);
     },
     
     drawShape : function drawShape(ctx){
index 1c3aa8c..9e84fcc 100644 (file)
@@ -6,24 +6,10 @@ Shape =
 exports['Shape'] =
 Layer.subclass('Shape', {
     _cssClasses : 'ezl layer shape',
+    
     fillStyle   : 'rgba(231,48,117, 1)',
     strokeStyle : 'transparent',
-    lineWidth   : 0,
-    
-    _calcDimension : function _calcDimension(which, values){
-        values.unshift(0);
-        var self = this
-        ,   neg = -1 * Math.min.apply(Math, values)
-        // ,   pos = Math.min(0, Math.max.apply(Max, values) - max)
-        ;
-        
-        self.negBleed.attr(which, neg);
-        // self.posBleed.attr(which, pos);
-        
-        return values.map(function(v, i){
-                return (self[which+i] = v);
-            });
-    }
+    lineWidth   : 0
     
 });
 
index 90bb5ba..56c90b0 100644 (file)
@@ -101,22 +101,22 @@ QuadTree.subclass('PathMap', {
             var B = blocker.boundingBox;
             if (bb.x2 <= B.x1 && x2 >= B.x1) {
                 msg += 'left';
-                side = B.sides.left;
+                side = new Line(B.x1,B.y1, B.x1,B.y2);
                 to   = trj.pointAtX(B.x1-bw-offX-1);
                 
             } else if (bb.x1 >= B.x2 && x1 <= B.x2) {
                 msg += 'right';
-                side = B.sides.right;
+                side = new Line(B.x2,B.y1, B.x2,B.y2);
                 to   = trj.pointAtX(B.x2-offX+1);
                 
             } else if (bb.y2 <= B.y1 && y2 >= B.y1) {
                 msg += 'top';
-                side = B.sides.top;
+                side = new Line(B.x1,B.y1, B.x2,B.y1);
                 to   = trj.pointAtY(B.y1-bh-offY-1);
                 
             } else if (bb.y1 >= B.y2 && y1 <= B.y2) {
                 msg += 'bottom';
-                side = B.sides.bottom;
+                side = new Line(B.x1,B.y2, B.x2,B.y2);
                 to   = trj.pointAtY(B.y2-offY+1);
             }
             
index fa38fc0..f406acc 100644 (file)
@@ -79,7 +79,7 @@ Line.subclass('Trajectory', {
      * Compares how distant in the future two objects are on this trajectory.
      * Objects that have been passed are always further away than those in the future,
      * but otherwise the comparison is performed by absolute distance.
-     * @returns -1 if a closer b, 1 if a further b, 0 if a same as b
+     * @return -1 if a closer b, 1 if a further b, 0 if a same as b
      */
     compare : function compare(a, b){
         if (a instanceof Thing) a = a.midpoint;
index d330055..64f9125 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.add(x,y)
+        ,   bb = this.boundingBox.reloacte(x,y)
         
         ,   blockers = this.game.pathmap.get(bb.x1,bb.y1, bb.x2,bb.y2).remove(this)
         ;
index c166ff5..2be964d 100644 (file)
@@ -427,8 +427,8 @@ Thing.subclass('Tank', function(Tank){
                 .appendTo( parent ) ;
         
         this.turret =
-            new Circle(r, true)
-                .position(w2-r, h2-r)
+            new Circle(r)
+                .position(w2, h2)
                 .fill(this.turretColor)
                 .appendTo( this.shape ) ;
         
diff --git a/www/commonjs.php b/www/commonjs.php
new file mode 100644 (file)
index 0000000..e9af8be
--- /dev/null
@@ -0,0 +1,25 @@
+<?php
+error_reporting(E_ALL);
+
+$PYTHON_VERSIONS = array( 2.7, 2.6 );
+$PYTHON_SITE_PATHS = array(
+    "~/.python/lib/python",
+    "~/lib/python{ver}/site-packages",
+    "/usr/local/lib/python{ver}/site-packages",
+    "/System/Library/Frameworks/Python.framework/Versions/Current/lib/python{ver}/site-packages",
+    "/usr/lib/python{ver}/site-packages"
+);
+
+function pyVersions($out, $path) {
+    global $PYTHON_VERSIONS;
+    foreach ($PYTHON_VERSIONS as $ver)
+        $out[] = str_replace("{ver}", $ver, $path);
+    return $out;
+}
+
+$PYTHONPATH = implode(':', array_unique(array_reduce($PYTHON_SITE_PATHS, 'pyVersions', array())) );
+
+function commonjs($src, $root="..") {
+    global $PYTHONPATH;
+    return shell_exec("cd $root && PYTHONPATH=$PYTHONPATH commonjs $src 2>&1");
+}
index 1c125f0..7d9be22 100644 (file)
@@ -1,23 +1,7 @@
 <?php
-    include 'header.html';
-    include 'welcome.html';
-    include 'game.html';
-    include 'debug.html';
-?>
-
-<div id="scripts">
-<?php
-    $PYTHONPATH = "PYTHONPATH='/Users/dsc/.python/lib/python:/usr/local/lib/python2.7/site-packages:/usr/local/lib/python2.6/site-packages'";
-    
-    error_reporting(E_ALL);
-    echo "<!--\n";
-    echo shell_exec("cd .. && $PYTHONPATH commonjs src/{Y,ezl,tanks} 2>&1");
-    echo "\n-->\n";
-    
-    include "deps.html";
-?>
-</div>
-
-<?php
-    include 'footer.html';
-?>
+require 'header.html';
+require 'welcome.html';
+require 'game.html';
+require 'debug.html';
+require 'scripts.php';
+require 'footer.html';
diff --git a/www/scripts.php b/www/scripts.php
new file mode 100644 (file)
index 0000000..a7e0016
--- /dev/null
@@ -0,0 +1,12 @@
+<div id="scripts">
+<?php
+require "commonjs.php";
+
+$errors = commonjs('src/{Y,ezl,tanks}');
+if ($errors) echo "<pre>$errors</pre>";
+
+// Precompiled dependency list
+require "deps.html";
+
+?>
+</div>
\ No newline at end of file
diff --git a/www/test b/www/test
deleted file mode 120000 (symlink)
index 419df4f..0000000
--- a/www/test
+++ /dev/null
@@ -1 +0,0 @@
-../test
\ No newline at end of file
similarity index 94%
copy from test/math/index.php
copy to www/test/math/index.php
index 830a32c..14a3dda 100644 (file)
@@ -62,16 +62,10 @@ h1 { position:fixed; top:0; right:0; margin:0; padding:0; font-size:3em; color:#
 
 <div id="scripts">
 <?php
-
-require "../../tanks.php";
-Tanks::writeTags(null, "../../");
-
-$scripts = array(
-    "math.test.js"
-);
-foreach ($scripts as $s) js($s);
-
+    require "../../commonjs.php";
+    echo commonjs('www/test/math/test-math --script-tags /build', "../../..");
 ?>
 </div>
+
 </body>
 </html>
\ No newline at end of file
similarity index 76%
rename from test/math/index.php
rename to www/test/shapes/index.php
index 830a32c..f77f097 100644 (file)
@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html>
 <head>
-<title>math</title>
+<title>shapes</title>
 <link rel="stylesheet" href="../../css/reset.css" type="text/css" media="screen">
 <style type="text/css" media="screen">
 
@@ -39,17 +39,6 @@ h1 { position:fixed; top:0; right:0; margin:0; padding:0; font-size:3em; color:#
 <div id="content">
     <div id="plot"></div>
     
-    <div id="info" class="rounded">
-        <form id="line" action="#" method="get">
-        <!--<fieldset id="line"><legend>Line</legend>-->
-            <label for="line_coords">Line:</label>
-            ( <input id="line_coords" name="x1" value="" type="text">, <input name="y1" value="" type="text"> )
-            ( <input name="x2" value="" type="text">, <input name="y2" value="" type="text"> )
-        <!--</fieldset>-->
-        </form>
-        <pre id="inter"></pre>
-    </div>
-    
     <div id="howto" class="rounded">
         <h3>Trigonometry and Reflection Test</h3>
         <ul>
@@ -62,16 +51,10 @@ h1 { position:fixed; top:0; right:0; margin:0; padding:0; font-size:3em; color:#
 
 <div id="scripts">
 <?php
-
-require "../../tanks.php";
-Tanks::writeTags(null, "../../");
-
-$scripts = array(
-    "math.test.js"
-);
-foreach ($scripts as $s) js($s);
-
+    require "../../commonjs.php";
+    echo commonjs('www/test/shapes/test-shapes --script-tags /build', "../../..");
 ?>
 </div>
+
 </body>
 </html>
\ No newline at end of file
diff --git a/www/test/shapes/test-shapes.js b/www/test/shapes/test-shapes.js
new file mode 100644 (file)
index 0000000..0fa526b
--- /dev/null
@@ -0,0 +1,40 @@
+REF_SIZE = 50;
+
+Y     = require('Y').Y;
+ezl   = require('ezl');
+shape = require('ezl/shape');
+Grid  = require('tanks/ui/grid').Grid;
+
+
+
+$(function(){
+    el = $('#plot');
+    
+    w = el.width();  w2 = w/2;
+    h = el.height(); h2 = h/2;
+    COLS = w/REF_SIZE; COLS2 = COLS/2;
+    ROWS = h/REF_SIZE; ROWS2 = ROWS/2;
+    
+    grid = new Grid( COLS, ROWS, REF_SIZE ).appendTo(el);
+    grid.createTableGrid = false;
+    grid.lineWidth = 1.0;
+    grid.strokeStyle = '#E0E0E0'; //'#EEEEEE'; //
+    grid.draw();
+    
+    // Draw axes
+    shape.Line // X Axis
+        .fromPoints(-w,-h2, w,-h2)
+        .stroke('#CCCCCC', 2.0)
+        .appendTo(grid);
+    shape.Line // Y Axis
+        .fromPoints(w2,-h, w2,h)
+        .stroke('#CCCCCC', 2.0)
+        .appendTo(grid);
+    
+    plot = new ezl.Layer()
+        .width(w).height(h)
+        .appendTo(grid);
+    
+    
+    
+});
similarity index 100%
rename from test/uki/index.php
rename to www/test/uki/index.php