Checkpoint on collision refactor to support zones.
authordsc <david.schoonover@gmail.com>
Sat, 18 Dec 2010 17:20:48 +0000 (09:20 -0800)
committerdsc <david.schoonover@gmail.com>
Sat, 18 Dec 2010 17:20:48 +0000 (09:20 -0800)
40 files changed:
src/Y/index.cjs
src/Y/modules/y.config.cjs
src/Y/modules/y.event.cjs
src/Y/modules/y.scaffold.cjs
src/Y/type.cjs
src/Y/types/function.cjs
src/Y/y.cjs
src/evt.cjs
src/ezl/layer.cjs
src/ezl/loc/boundingbox.cjs
src/ezl/loop/eventloop.cjs
src/ezl/math/line.cjs
src/ezl/shape/circle.cjs
src/ezl/shape/line.cjs
src/ezl/shape/polygon.cjs
src/ezl/shape/rect.cjs
src/ezl/util/configuration.cjs [deleted file]
src/ezl/widget/cooldown.cjs
src/tanks/abilities/buff.cjs [new file with mode: 0644]
src/tanks/abilities/index.cjs [new file with mode: 0644]
src/tanks/config.cjs
src/tanks/game.cjs
src/tanks/index.js
src/tanks/map/level.cjs
src/tanks/map/pathmap.cjs
src/tanks/map/trajectory.cjs
src/tanks/map/traversal.cjs [new file with mode: 0644]
src/tanks/map/wall.cjs
src/tanks/thing/bullet.cjs
src/tanks/thing/index.cjs
src/tanks/thing/item.cjs [new file with mode: 0644]
src/tanks/thing/player.cjs
src/tanks/thing/tank.cjs
src/tanks/thing/thing.cjs
src/tanks/ui/configui.cjs
src/tanks/ui/grid.cjs
src/tanks/ui/index.cjs
src/tanks/ui/main.cjs
src/tanks/ui/pathmapui.cjs [new file with mode: 0644]
www/deps.html

index dd9f2b5..cddbcd4 100644 (file)
@@ -50,11 +50,12 @@ addNames('Class subclass instantiate fabricate YBase', require('Y/class'));
 
 
 /// Now start assembling the normal sub-modules ///
-addNames('YCollection',      require('Y/types/collection'));
-addNames('YArray',           require('Y/types/array'));
-addNames('YObject deepcopy', require('Y/types/object'));
-addNames('YString',          require('Y/types/string'));
-addNames('YNumber range',    require('Y/types/number'));
+addNames('YCollection',   require('Y/types/collection'));
+addNames('YArray',        require('Y/types/array'));
+addNames('YObject getNested setNested deepcopy',
+                          require('Y/types/object'));
+addNames('YString',       require('Y/types/string'));
+addNames('YNumber range', require('Y/types/number'));
 
 var utils = require('Y/utils');
 Y['bindAll'] = utils.bindAll;
index 91a694c..f812fde 100644 (file)
@@ -1,5 +1,5 @@
 var Y = require('Y').Y
-,   getNested = require('Y/types/object').getNested
+,   getNested = Y.getNested
 ,   Emitter   = require('Y/modules/y.event').Emitter
 ,
 
@@ -142,7 +142,7 @@ Y.YObject.subclass('Config', function(Config){
          */
         updateOnChange : function updateOnChange(events, obj){
             if ( !Y.isArray(events) )
-                events = events.split();
+                events = events.split(/\s+/);
             events = events.map(function events(key){
                 obj[key.split('.').pop()] = this.get(key);
                 if ( !Y(key).startsWith('set:') )
index 7421fb8..64859d9 100644 (file)
@@ -37,7 +37,7 @@ Y.YObject.subclass('Event', {
     addEventListener : function addEventListener(evts, fn){
         fn = fn.toFunction();
         if ( !Y.isArray(evts) )
-            evts = evts.split();
+            evts = evts.split(/\s+/);
         evts.forEach(function addEvent(evt){
             this.getQueue(evt).push(fn);
         }, this);
@@ -57,7 +57,11 @@ Y.YObject.subclass('Event', {
         return evt;
     },
     
-    // XXX: does not handle degenerate or recursive event dispatch
+    /**
+     * Dispatches the given event to all listeners in the appropriate queue.
+     * Listeners are invoked with the event, and with context set to the target.
+     * XXX: does not handle degenerate or recursive event dispatch
+     */
     dispatchEvent : function dispatchEvent(evt){
         this.getQueue(evt.type).invoke('call', evt.target, evt);
         if (this.parent) this.parent.fire(evt.type, evt.trigger, evt.data);
index 9a499df..717b7c9 100644 (file)
@@ -37,6 +37,14 @@ type2el = {
 ,
 
 
+// addTypeSupport =
+// exports['addTypeSupport'] =
+// function addTypeSupport(type, parser, builder){
+//     var T = Y.typeName(type);
+//     type2parser[T] = parser;
+// }
+// ,
+
 
 Field =
 exports['Field'] =
@@ -52,7 +60,7 @@ Y.subclass('Field', {
         this.key   = chain.split('.').pop();
         this.label = camelToSpaces(this.key);
         
-        var T = Y(Y.type(val)).getName();
+        var T = Y.typeName(def);
         this.cast = options.cast || type2parser[T];
         this.type = options.type || type2el[T];
         
@@ -133,8 +141,12 @@ function create(config, el){
         },
         function createField(group, value, chain){
             var def = config.getDefault(chain)
-            ,   field = new Field(chain, def, value);
+            ,   T = Y.typeName(def);
+            
+            if (!type2parser[T])
+                return group;
             
+            var field = new Field(chain, def, value);
             fields[chain] = field;
             group.append(field.el);
             config.addEventListener('set:'+chain, function onConfigSet(evt){
index 18c7cb8..bed850b 100644 (file)
@@ -28,46 +28,53 @@ var class2name =
     "Boolean Number String Function Array Date RegExp Object"
         .split(" ")
         .reduce(function(class2name, name) {
-            class2name[ "[object "+name+"]" ] = name.toLowerCase();
+            class2name[ "[object "+name+"]" ] = name;
             return class2name;
         }, {});
 
-function type_of(obj){
-    return obj == null ?
-        String( obj ) :
-        class2name[ toString.call(obj) ] || "object";
+function basicTypeName(o){
+    return o == null ?
+        String(o) :
+        class2name[ toString.call(o) ] || "Object";
+}
+
+function typeName(o){
+    if (o === undefined || o === null)
+        return String(o);
+    var T = type(o);
+    return  T.className || (T !== Function ? T.name : basicTypeName(o));
 }
 
 var arrayLike = isArray.types = [];
-function isArray(obj)    { return type_of(obj) === "array" || (arrayLike.indexOf(type(obj)) !== -1); }
-function isFunction(obj) { return type_of(obj) === "function"; }
-function isString(obj)   { return type_of(obj) === "string"; }
-function isNumber(obj)   { return type_of(obj) === "number"; }
-function isWindow(obj)   { return obj && typeof obj === "object" && "setInterval" in obj; }
+function isArray(o)    { return basicTypeName(o) === "Array" || (arrayLike.indexOf(type(o)) !== -1); }
+function isFunction(o) { return basicTypeName(o) === "Function"; }
+function isString(o)   { return basicTypeName(o) === "String"; }
+function isNumber(o)   { return basicTypeName(o) === "Number"; }
+function isWindow(o)   { return o && typeof o === "object" && "setInterval" in o; }
 
-function isPlainObject( obj ){
+function isPlainObject(o){
     // Must be an Object.
     // Because of IE, we also have to check the presence of the constructor property.
     // Make sure that DOM nodes and window objects don't pass through, as well
-    if ( !obj || type_of(obj) !== "object" || obj.nodeType || isWindow(obj) )
+    if ( !o || basicTypeName(o) !== "Object" || o.nodeType || isWindow(o) )
         return false;
     
     // Not own constructor property must be Object
-    if ( obj[FN] &&
-        !hasOwn.call(obj, FN) &&
-        !hasOwn.call(obj[FN][PT], "isPrototypeOf") )
+    if ( o[FN] &&
+        !hasOwn.call(o, FN) &&
+        !hasOwn.call(o[FN][PT], "isPrototypeOf") )
             return false;
     
     
     // Own properties are enumerated firstly, so to speed up,
     // if last one is own, then all properties are own.
     var key;
-    for ( key in obj ) {}
+    for ( key in o ) {}
     
-    return key === undefined || hasOwn.call( obj, key );
+    return key === undefined || hasOwn.call( o, key );
 }
 
-function type( o ) {
+function type(o) {
     if ( o === null || o === undefined )
         return o;
     
@@ -95,7 +102,7 @@ function type( o ) {
     }
 }
 
-function is( A, B ){
+function is(A, B){
     if ( isArray(B) )
         return B.some( is.bind(this,A) );
     else {
@@ -106,7 +113,8 @@ function is( A, B ){
 
 exports['is']            = is;
 exports['type']          = type;
-exports['type_of']       = type_of;
+exports['basicTypeName'] = basicTypeName;
+exports['typeName']      = typeName;
 
 exports['isArray']       = isArray;
 exports['isFunction']    = isFunction;
@@ -115,5 +123,5 @@ exports['isNumber']      = isNumber;
 exports['isWindow']      = isWindow;
 exports['isPlainObject'] = isPlainObject;
 
-type['KNOWN_CLASSES'] = KNOWN_CLASSES;
+type['KNOWN_CLASSES']    = KNOWN_CLASSES;
 
index b332334..e11e31b 100644 (file)
@@ -284,4 +284,4 @@ function getName( fn ){
 
 // Export these last to avoid methodizing them
 exports['YFunction']  = YF(YF);
-exports._ = _;
+exports['_'] = _;
index 57bb49d..5a22487 100644 (file)
@@ -71,8 +71,7 @@ function Y(o){
     }
     
     // Do we have a type-specific wrapper?
-    var name  = type.type_of(o)
-    ,   yname = 'Y' + name.charAt(0).toUpperCase() + name.slice(1)
+    var yname = 'Y' + type.basicTypeName(o)
     ,   YType = Y[yname]
     ;
     
index 7981385..61462cf 100644 (file)
@@ -39,12 +39,19 @@ var Y       = require('Y').Y
 
 ,   objToString   = _Object[P].toString
 ,   classToString = function toString(){ return this.className+"()"; }
-;
+,
+
 
-// Private delegating constructor -- must be defined for every
-// new class to prevent shared state. All construction is
-// actually done in the init method.
-exports['ConstructorTemplate'] = ConstructorTemplate;
+/**
+ * @private
+ * Private delegating constructor. This function must be redefined for every
+ * new class to prevent shared state. All construction is actually done in
+ * the methods initialise and init.
+ * 
+ * Fires `create` event prior to initialisation if not subclassing.
+ */
+ConstructorTemplate =
+exports['ConstructorTemplate'] =
 function ConstructorTemplate() {
     var cls = arguments.callee
     ,   instance = this;
@@ -64,7 +71,39 @@ function ConstructorTemplate() {
     
     return instance;
 }
+,
 
+/**
+ * Fires `init` event after calling init(). Note that events are fired
+ * for proper instances of the class and instances of subclasses (but
+ * not for the instance created when subclassing).
+ */
+createInitialise =
+exports['createInitialise'] =
+function createInitialise(NewClass){
+    function initialise(){
+        var instance = this
+        ,   init     = NewClass.prototype.init
+        ;
+        
+        instance.__emitter__ = new Emitter(instance, NewClass);
+        
+        if (init) {
+            var result = init.apply(instance, arguments);
+            if (result) instance = result;
+        }
+        
+        instance.fire('init', instance, {
+            'instance' : instance,
+            'cls'      : NewClass,
+            'args'     : Y(arguments)
+        });
+        
+        return instance;
+    }
+    return Y(initialise);
+}
+;
 
 
 
@@ -156,28 +195,7 @@ function Class(className, Parent, members){
     NewClass.__super__    = SuperClass; // don't override NewClass.constructor -- it should be Function
     prototype.constructor = prototype.__class__ = NewClass;
     
-    NewClass.init = // XXX: This means subclasses will fire events.
-    prototype.initialise =
-        Y(function initialise(){
-            var instance = this
-            ,   init     = NewClass.prototype.init
-            ;
-            
-            instance.__emitter__ = new Emitter(instance, NewClass);
-            
-            if (init) {
-                var result = init.apply(instance, arguments);
-                if (result) instance = result;
-            }
-            
-            instance.fire('init', instance, {
-                'instance' : instance,
-                'cls'      : NewClass,
-                'args'     : Y(arguments)
-            });
-            
-            return instance;
-        });
+    NewClass.init = prototype.initialise = createInitialise(NewClass);
     
     // Add class emitter
     var ParentEmitter = (Parent.__emitter__ ? Parent : ClassFactory)
index 6857efb..21f150f 100644 (file)
@@ -21,7 +21,6 @@ Y.subclass('Layer', {
     _cssClasses : 'ezl layer',
     
     canvas     : null,
-    
     parent     : null,
     children   : null,
     
@@ -43,10 +42,14 @@ Y.subclass('Layer', {
     // Transforms
     _origin : null, // rotational origin
     transform : null, // Object
-    useCanvasScaling : false, // default to CSS3 scaling
     
     /// Defaults ///
     
+    useCanvasScaling   : false, // Default to CSS3 scaling
+    alwaysClearDrawing : true,  // Whether to clear the canvas content before redraw
+    alwaysClearAttrs   : false, // Whether to remove all canvas attributes (CONTEXT_ATTRS)
+                                // and transforms (scale, rotate, translate) and reset defaults before redraw
+    
     originX : 0,
     originY : 0,
     
@@ -129,7 +132,7 @@ Y.subclass('Layer', {
      */
     empty : function empty(ctx){
         this.children.invoke('remove');
-        this.clear();
+        this.clear(ctx);
         return this;
     },
     
@@ -469,48 +472,55 @@ Y.subclass('Layer', {
      * @param {Boolean} [force=false] Forces redraw.
      */
     draw : function draw(ctx, force){
+        var _ctx = ctx || this.ctx;
+        
         if ( this.dirty || force ){
-            var _ctx = ctx || this.ctx;
+            this.dirty = false;
             this._openPath(_ctx);
-            this.drawShape(_ctx);
+            this.render(_ctx);
             this._closePath(_ctx);
         }
         
-        this.dirty = false;
         this.children.invoke('draw', ctx, force);
         return this;
     },
     
     _openPath : function _openPath(ctx){
         var self = this
-        ,   alwaysClear = this.alwaysClear
         ,   neg = this.negBleed
         ,   t = this.transform
         ,   w = this.canvasWidth, h = this.canvasHeight ;
         
         ctx.beginPath();
-        ctx.setTransform(1,0,0,1,0,0);
-        ctx.clearRect(-w,-h, 2*w,2*h);
         
+        // TODO: only alwaysClearAttrs should reset transforms?
+        // if (this.alwaysClearAttrs)
+            ctx.setTransform(1,0,0,1,0,0);
+        
+        if (this.alwaysClearDrawing)
+            ctx.clearRect(-w,-h, 2*w,2*h);
+        
+        // if (this.alwaysClearAttrs) {
         if (this.useCanvasScaling && (t.scale.x !== 1 || t.scale.y !== 1))
             ctx.scale(t.scale.x,t.scale.y);
         
         ctx.translate(neg.x, neg.y);
         ctx.translate(t.translate.x, t.translate.y);
+        // }
         
         // Set context attributes
         CONTEXT_ATTRS.forEach(function(name){
-            if (self[name] !== undefined)
-                ctx[name] = self[name];
-            else if (alwaysClear)
+            if (this[name] !== undefined)
+                ctx[name] = this[name];
+            else if (this.alwaysClearAttrs)
                 delete ctx[name];
-        });
+        }, this);
         
         return this;
     },
     
     /** To be implemented by subclasses. */
-    drawShape : function drawShape(ctx){ return this; },
+    render : function render(ctx){ return this; },
     
     _closePath : function _closePath(ctx){
         ctx.closePath();
@@ -518,9 +528,9 @@ Y.subclass('Layer', {
     },
     
     /**
-     * Clears this layer and all children.
+     * Clears this layer and optionally all children.
      */
-    clear : function clear(ctx){
+    clear : function clear(ctx, clearChildren){
         var w = this.canvas.width()
         ,   h = this.canvas.height();
         ctx = ctx || this.ctx;
@@ -528,7 +538,8 @@ Y.subclass('Layer', {
         ctx.setTransform(1,0,0,1,0,0);
         ctx.clearRect(-w,-h, 2*w,2*h);
         ctx.closePath();
-        this.children.invoke('clear');
+        if (clearChildren)
+            this.children.invoke('clear');
         return this;
     },