Adds properties for reflectivity and inventory; fills in Item collision code.
authordsc <david.schoonover@gmail.com>
Fri, 24 Dec 2010 19:52:34 +0000 (11:52 -0800)
committerdsc <david.schoonover@gmail.com>
Fri, 24 Dec 2010 19:52:34 +0000 (11:52 -0800)
26 files changed:
src/ezl/index.cjs
src/ezl/layer/html.cjs [copied from src/tanks/abilities/buff.cjs with 100% similarity]
src/ezl/layer/index.cjs [copied from src/tanks/abilities/index.cjs with 100% similarity]
src/ezl/layer/layer.cjs [moved from src/ezl/layer.cjs with 98% similarity]
src/ezl/layer/text.cjs [copied from src/tanks/abilities/buff.cjs with 100% similarity]
src/ezl/shape/circle.cjs
src/ezl/shape/line.cjs
src/ezl/shape/shape.cjs
src/ezl/util/astar.cjs
src/ezl/util/tree/binaryheap.cjs [moved from src/ezl/util/binaryheap.cjs with 100% similarity]
src/ezl/widget/cooldown.cjs
src/tanks/calc.cjs [deleted file]
src/tanks/effects/buff.cjs [moved from src/tanks/abilities/buff.cjs with 100% similarity]
src/tanks/effects/index.cjs [moved from src/tanks/abilities/index.cjs with 100% similarity]
src/tanks/map/level.cjs
src/tanks/map/pathmap.cjs
src/tanks/map/traversal.cjs
src/tanks/thing/bullet.cjs
src/tanks/thing/item.cjs
src/tanks/thing/player.cjs
src/tanks/thing/tank.cjs
src/tanks/thing/thing.cjs
src/tanks/thing/wall.cjs
src/tanks/ui/pathmapui.cjs
www/css/lttl.css
www/deps.html

index 0b952af..112295b 100644 (file)
@@ -6,12 +6,13 @@
 var Y = require('Y').Y;
 
 Y.extend(exports, {
-    'Layer'  : require('ezl/layer').Layer,
-    
+    'math'   : require('ezl/math'),
     'loc'    : require('ezl/loc'),
+    'util'   : require('ezl/util'),
+    
     'loop'   : require('ezl/loop'),
-    'math'   : require('ezl/math'),
+    
+    'layer'  : require('ezl/layer'),
     'shape'  : require('ezl/shape'),
-    'util'   : require('ezl/util'),
     'widget' : require('ezl/widget')
 });
similarity index 98%
rename from src/ezl/layer.cjs
rename to src/ezl/layer/layer.cjs
index 21f150f..75d5408 100644 (file)
@@ -1,16 +1,14 @@
 //#ensure "jquery"
-
-var undefined
-,   Y   = require('Y').Y
-,   Vec = require('ezl/math/vec').Vec
-,   loc = require('ezl/loc')
-,   Loc = loc.Loc
-,   BoundingBox = loc.BoundingBox
-,   Animation = require('ezl/loop/fx').Animation
+var Y           = require('Y').Y
+,   Vec         = require('ezl/math/vec').Vec
+,   Loc         = require('ezl/loc/loc').Loc
+,   BoundingBox = require('ezl/loc/boundingbox').BoundingBox
+,   Animation   = require('ezl/loop/fx').Animation
 , 
+
 CONTEXT_ATTRS  = Y('globalAlpha globalCompositeOperation strokeStyle fillStyle lineWidth lineCap lineJoin miterLimit shadowOffsetX shadowOffsetY shadowBlur shadowColor'.split(' ')),
 FAUX_ACCESSORS = Y('width height position stroke fill origin rotate scale translate title'.split(' '))
-,_X = 0, _Y = 1
+, _X = 0, _Y = 1
 ,
 
 
index 733148a..909ee8d 100644 (file)
@@ -1,5 +1,4 @@
-var Y = require('Y').Y
-,   Shape = require('ezl/shape/shape').Shape
+var Shape = require('ezl/shape/shape').Shape
 ,
 
 Circle =
index e007377..d347c7a 100644 (file)
@@ -2,7 +2,7 @@
 
 var Y     = require('Y').Y
 ,   math  = require('ezl/math')
-,   Layer = require('ezl/layer').Layer
+,   Layer = require('ezl/layer/layer').Layer
 ,   Shape = require('ezl/shape/shape').Shape
 ,
 
index 9e84fcc..e7ffad7 100644 (file)
@@ -1,5 +1,4 @@
-var Y = require('Y').Y
-,   Layer = require('ezl/layer').Layer
+var Layer = require('ezl/layer/layer').Layer
 ,
 
 Shape =
index 08e9885..1d15f05 100644 (file)
@@ -16,7 +16,7 @@
         var end = graph.nodes[1][2];
         astar.search(graph.nodes, start, end);
 */
-var BinaryHeap = require('ezl/util/binaryheap').BinaryHeap;
+var BinaryHeap = require('ezl/util/tree/binaryheap').BinaryHeap;
 
 exports['init'] = init;
 function init(grid) {
index c7f492a..e94b51b 100644 (file)
@@ -1,5 +1,5 @@
 var Y = require('Y').Y
-,   Layer = require('ezl/layer').Layer
+,   Layer = require('ezl/layer/layer').Layer
 
 ,   PI             = Math.PI
 ,   QUARTER_PI     = PI/4
diff --git a/src/tanks/calc.cjs b/src/tanks/calc.cjs
deleted file mode 100644 (file)
index 7e14ba2..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-Calc = {
-    
-    
-    
-};
\ No newline at end of file
index 6736b4f..147a7a1 100644 (file)
@@ -46,7 +46,7 @@ Rect.subclass('Level', {
         // game.addThing(new Tank(2), 1,0);
         // game.addThing(new Tank(2), 8,1);
         
-        // I = game.addThing(new Item(), 8,8);
+        I = game.addThing(new Item(), 8,8);
     },
     
     addWall : function addWall(x,y, w,h, isBoundary){
index 623cc21..c82075b 100644 (file)
@@ -4,7 +4,7 @@ var Y          = require('Y').Y
 ,   math       = require('ezl/math')
 ,   vec        = require('ezl/math/vec')
 ,   QuadTree   = require('ezl/util/tree/quadtree').QuadTree
-,   BinaryHeap = require('ezl/util/binaryheap').BinaryHeap
+,   BinaryHeap = require('ezl/util/tree/binaryheap').BinaryHeap
 ,   Vec        = vec.Vec
 ,   Line       = math.Line
 
index 4316d32..c51d193 100644 (file)
@@ -110,11 +110,10 @@ Y.subclass('Traversal', {
     },
     
     collide : function collide(blocker){
-        var thing = this.thing
-        ,   data  = { 'traversal':this, 'thing':thing, 'blocker':blocker };
+        var thing = this.thing;
         
-        thing.fire('collide', blocker, data);
-        blocker.fire('collide', thing, data);
+        thing.fire('collide', blocker, { 'traversal':this, 'unit':blocker });
+        blocker.fire('collide', thing, { 'traversal':this, 'unit':thing });
     },
     
     rewind : function rewind(blocker){
index b2a7e9c..22a02cc 100644 (file)
@@ -115,11 +115,11 @@ Thing.subclass('Bullet', {
         var traj = this.trajectory
         
         ,   ng, d = evt.data
+        ,   unit = d.unit
         ,   tvsl = d.traversal
         ,   to   = tvsl.to
-        ,   unit = d.blocker
         
-        ,   isReflective = unit instanceof Wall // XXX: unit.reflective
+        ,   isReflective = unit.isReflective
         ;
         
         // Ignore collisions with zones
index 704708a..231baef 100644 (file)
@@ -7,39 +7,84 @@ var Y     = require('Y').Y
 ,   map   = require('tanks/map/map')
 ,   Thing = require('tanks/thing/thing').Thing
 
-,   SIZE = REF_SIZE * 0.5
+,   ITEM_SIZE = REF_SIZE * 0.5
 ,
 
 
 Item =
 exports['Item'] =
 Thing.subclass('Item', {
-    blocking : map.ZONE,
-    active   : false,
+    align : 0, // 0 reserved for neutral units
     
-    width  : SIZE,
-    height : SIZE,
+    blocking : map.ZONE,
+    width    : ITEM_SIZE,
+    height   : ITEM_SIZE,
     
-    stats : { hp:1, move:0, power:0 },
+    // indestructable
+    stats      : { hp:Infinity, move:0, power:0 },
+    dealDamage : op.nop,
     
     // inactive
-    createCooldowns : op.nop,
-    updateCooldowns : op.nop,
-    act : op.nop,
+    active     : false,
+    
+    
+    /// Instance Properties ///
+    type     : 'dummy',     // {String} Item type identifier (unique, for config lookup)
+    name     : 'Dummy',     // {String} Display name
+    icon_inv : '',          // {String} URL to inventory icon file (TODO)
+    icon_map : '',          // {String} URL to map icon file (TODO)
+    buffs    : Y([]),       // {Buff...} Passive effects (triggered on pickup)
+    effects  : Y([]),       // {Function...} Active effects (triggered on activation)
+    owner    : null,        // {Unit} Owner when picked up.
     
-    // indestructable
-    dealDamage : op.nop,
     
     
-    init : function initItem(){
+    // XXX: Setting these per-instance only while testing
+    init : function initItem(name, buffs, effects){
         Thing.init.call(this, 0);
+        if (name) this.name = name;
+        
+        if (buffs)
+            this.buffs = Y(buffs);
+        else
+            this.buffs = this.buffs.clone();
+        
+        if (effects)
+            this.effects = Y(effects);
+        else
+            this.effects = this.effects.clone();
         
         this.addEventListener('collide', this.onCollide.bind(this));
     },
     
+    activate : function activate(){
+        if (!this.owner) return;
+    },
+    
+    acquired : function acquired(unit){
+        this.owner = unit;
+        console.log(unit+' acquired '+this+'!');
+        // TODO: apply buffs
+        unit.fire('acquire', this, { 'unit':unit, 'item':this });
+        // TODO: unit to listen, add to inventory, update UI, inform unit on activation
+    },
+    
+    dropped : function dropped(){
+        if (!this.owner) return;
+        var unit = this.owner;
+        this.owner = null;
+        console.log(unit+' dropped '+this+'!');
+        unit.fire('drop', this, { 'unit':unit, 'item':this });
+        // TODO: game to listen, re-add to level at unit.loc
+    },
+    
     onCollide : function onCollide(evt){
-        console.log('collide!', this);
-        this.destroy();
+        var unit = evt.data.unit;
+        
+        if (unit.hasInventory) {
+            this.destroy();
+            this.acquired(unit);
+        }
     },
     
     render : function render(parent){
@@ -50,12 +95,15 @@ Thing.subclass('Item', {
             .origin('50%', '50%')
             .position(loc.x, loc.y)
             .fill('#83BB32')
-            .stroke('#1C625B', 3.0)
+            .stroke('#1C625B', 5.0)
             .appendTo( parent );
         this.shape.layer.attr('title', ''+loc);
         
         return this;
-    }
+    },
     
+    toString : function(){
+        return this.type+'(id='+this.id+', owner='+this.owner+')';
+    }
 })
 ;
index d59b3ce..67a97cb 100644 (file)
@@ -11,6 +11,7 @@ PlayerTank =
 exports['PlayerTank'] =
 Tank.subclass('PlayerTank', {
     blocking : map.BLOCKING,
+    hasInventory : true,
     
     bodyColor   : '#E73075',
     turretColor : '#A72F5B',
@@ -26,6 +27,10 @@ Tank.subclass('PlayerTank', {
         shots     : 5           // max projectiles in the air at once
     },
     
+    /// Instance ///
+    
+    align : null,
+    
     
     
     init : function init(align){
index 939536d..9e69127 100644 (file)
@@ -27,17 +27,15 @@ exports['Tank'] =
 Thing.subclass('Tank', function(Tank){
     
     Y.core.descriptors(this, {
-        blocking : map.BLOCKING,
-        
         bodyColor   : '#83BB32',
         turretColor : '#1C625B',
         barrelColor : '#D43B24',
         
-        // Bounding box size
+        // Bounding box
+        blocking : map.BLOCKING,
         width  : REF_SIZE*0.55,
         height : REF_SIZE*0.55,
         
-        
         // Attributes
         stats : {
             hp        : 1,          // health
@@ -57,13 +55,19 @@ Thing.subclass('Tank', function(Tank){
         },
         
         projectile : Bullet,
+        
+        /// Instance ///
+        
+        align : null,
         buffs : null,
         
-        nShots : 0,
+        trajectory : null,
+        currentMove : null,
+        currentPath : null,
         forceCurrentMove : false,
         currentMoveLimit : -1,
         
-        trajectory : null
+        nShots : 0
     });
     
     this['init'] =
index 3315dc9..53945e3 100644 (file)
@@ -62,8 +62,12 @@ exports['Thing'] = new evt.Class('Thing', {
     dead    : false,
     dirty   : true,
     
-    blocking : map.BLOCKING, // Pathing type @see {map} for constant definitions
-    active   : true, // Whether the agent takes actions
+    // Properties
+    blocking     : map.BLOCKING,
+    active       : true,        // Agent takes actions?
+    isReflective : false,       // Projectiles bounce off agent rather than explode?
+    hasInventory : false,       // Agent can acquire items?
+    dropOnDeath  : false,       // Agent drops all items in inventory on death?
     
     // Location
     loc : null,
index 781a991..b710e38 100644 (file)
@@ -9,12 +9,21 @@ var Y     = require('Y').Y
 Wall =
 exports['Wall'] =
 Thing.subclass('Wall', {
-    blocking : map.BLOCKING,
-    active   : false,
+    align : 0, // 0 reserved for neutral units
     
     originX : 0,
     originY : 0,
     
+    blocking : map.BLOCKING,
+    isReflective : true,
+    
+    // inactive
+    active : false,
+    createCooldowns : op.nop,
+    
+    // indestructable
+    dealDamage : op.nop,
+    
     stats : {
         hp    : Infinity,
         move  : 0,
@@ -23,6 +32,8 @@ Thing.subclass('Wall', {
         shots : 0
     },
     
+    // Instance 
+    
     isBoundary : false,
     
     
@@ -35,11 +46,6 @@ Thing.subclass('Wall', {
         this.position(x,y);
     },
     
-    // inactive
-    createCooldowns : op.nop,
-    
-    // indestructable
-    dealDamage : op.nop,
     
     
     render : function render(parent){
index b2af103..13e7928 100644 (file)
@@ -1,6 +1,9 @@
 var Y       = require('Y').Y
+
 ,   Rect    = require('ezl/shape').Rect
 ,   vec     = require('ezl/math/vec')
+
+,   map     = require('tanks/map/map')
 ,   PathMap = require('tanks/map/pathmap').PathMap
 ,   config  = require('tanks/config').config
 ,
@@ -17,47 +20,72 @@ Rect.subclass('PathMapUI', {
     // Shape Config
     _cssClasses : 'pathmap rect shape layer ezl',
     
-    fillStyle   : 'rgba(255,255,255,0.1)',
-    strokeStyle : 'rgba(255,255,255,0.2)',
-    lineWidth   : 1,
+    
+    // Blocking objects
+    fillStyle       : 'rgba(255,255,255,0.1)',
+    strokeStyle     : 'rgba(255,255,255,0.75)',
+    lineWidth       : 1,
+    
+    // Zone objects
+    zoneFillStyle   : 'rgba(166,217,255, 0.1)',
+    zoneStrokeStyle : 'rgba(166,217,255, 0.75)',
+    zoneLineWidth   : 1,
+    
     
     
     
     init : function initPathMapUI(game, pathmap){
+        Y.bindAll(this, 'pathWithUI', 'cleanUpAgent', 'drawPathStep', 'overlayRegion');
+        Rect.init.call(this, pathmap.width-2, pathmap.height-2);
+        
         this.game = game;
         this.pathmap = pathmap;
         this.highlights = Y([]);
         
-        Rect.init.call(this, pathmap.width-2, pathmap.height-2);
-        
         // Store ref to original path function
         this._path = pathmap.path;
-        pathmap.path = this.pathWithUI.bind(this);
-        
-        this.cleanUpAgent  = this.cleanUpAgent.bind(this);
-        this.drawPathStep = this.drawPathStep.bind(this);
+        pathmap.path = this.pathWithUI;
     },
     
     render : function render(ctx){
+        // nb. AI paths are automatically drawn (and cleaned up) as they are created (and destroyed).
+        
+        // Redraw pathmap
         if (this.overlayPathmap)
             this.overlay(ctx);
-        // AI Paths automatically show up (and are cleaned up)
-        // as they are created (and destroyed).
+        
+        // Ensure we redraw every step
         this.dirty = true;
     },
     
     overlay : function overlay(ctx){
-        this.pathmap.reduce(function(acc, v, r, tree){
-            if ( acc[r.id] || v.isBoundary )
-                return acc;
-            acc[r.id] = r;
-            ctx.beginPath();
-            ctx.rect(r.x1,r.y1, r.width,r.height);
-            ctx.fill();
-            ctx.stroke();
-            ctx.closePath();
+        this.pathmap.reduce(this.overlayRegion, { 'ctx':ctx });
+    },
+    
+    overlayRegion : function overlayRegion(acc, v, r, tree){
+        var ctx = acc.ctx;
+        
+        if ( acc[r.id] || v.isBoundary )
             return acc;
-        }, {});
+        acc[r.id] = r;
+        
+        if (v.blocking === map.ZONE) {
+            ctx.fillStyle   = this.zoneFillStyle;
+            ctx.strokeStyle = this.zoneStrokeStyle;
+            ctx.lineWidth   = this.zoneLineWidth;
+        } else {
+            ctx.fillStyle   = this.fillStyle;
+            ctx.strokeStyle = this.strokeStyle;
+            ctx.lineWidth   = this.lineWidth;
+        }
+        
+        ctx.beginPath();
+        ctx.rect(r.x1,r.y1, r.width,r.height);
+        ctx.fill();
+        ctx.stroke();
+        ctx.closePath();
+        
+        return acc;
     },
     
     /**
index 9a6b3f1..beac57f 100644 (file)
@@ -10,19 +10,10 @@ ul, ol, li { list-style: none ! important; margin:0; padding:0; }
     padding:0.5em; background-color:rgba(0,0,0, 0.5); color:#787878;
     border-radius:1em; -moz-border-radius:1em; -webkit-border-radius:1em; }
 
-body > h1 { position:fixed; top:0; right:0; margin:0; padding:0; font-size:3em; color:#000; opacity:0.25; z-index:100; }
-
 table { border-spacing:0; }
 td { text-align:center; vertical-align:middle; }
 
-table.grid { position:absolute; top:0; left:0; z-index:10; }
-table.grid,
-table.grid td { /* outline:1px solid rgba(255,255,255,0.1); */ 
-    color:transparent; font: 18pt monospace; 
-    margin:0; padding:0; white-space:nowrap; overflow:hidden; }
-.showGridCoords table.grid td:hover { color:rgba(255,255,255,0.1); }
-
-.bigblue { position:fixed; width:100%; top:50%; margin-top:-200px; z-index:101; }
+.bigblue { position:fixed; width:100%; top:50%; margin-top:-200px; z-index:1001; }
     .bigblue .box { width:400px; margin:0 auto; padding:1em; color:#000; background-color:#2992C5;
         box-shadow:7.5px 7.5px 15px #000; -moz-box-shadow:7.5px 7.5px 15px #000; -webkit-box-shadow:7.5px 7.5px 15px #000; }
     .bigblue h1 { text-align:center; font-size:2em; letter-spacing:2px; }
@@ -33,9 +24,7 @@ table.grid td { /* outline:1px solid rgba(255,255,255,0.1); */
     font-size:1.5em; padding:0.5em; background-color:#E73075; color:#fff; text-align:center; text-transform:uppercase;
     border:5px solid #fff; }
 
-.countdown { position:fixed; overflow:hidden; z-index:1000; text-align:center; border:10px solid #fff; color:#fff; }
-
-#ai { position:absolute; z-index:1002; width:80%; left:10%; }
+#ai { position:absolute; z-index:2002; width:80%; left:10%; }
     #ai h2 { font-size:1.3em; }
     #ai .box { width:100%; }
     #ai .ready { width:5%; float:left; margin-right:1em; }
@@ -44,7 +33,9 @@ table.grid td { /* outline:1px solid rgba(255,255,255,0.1); */
 #viewport { position:relative; width:500px; height:500px; margin:1em auto; cursor:crosshair; }
     #viewport .layer.grid { outline:1px solid rgba(255,255,255,0.1); }
 
-#overlay { position:fixed; top:0; left:0; width:100%; height:100%; background-color:#000; opacity:0.5; z-index:100; }
+#overlay { position:fixed; top:0; left:0; width:100%; height:100%; background-color:#000; opacity:0.5; z-index:1000; }
+
+.countdown { position:fixed; overflow:hidden; z-index:2000; text-align:center; border:10px solid #fff; color:#fff; }
 
 #welcome .box { cursor:pointer; }
 #notes { /* position:fixed; top:4em; right:1em; color:#BFBFBF;*/ }
@@ -58,12 +49,12 @@ table.grid td { /* outline:1px solid rgba(255,255,255,0.1); */
 */
 
 /* 
-#debug { position:relative; top:1em; right:1em; z-index:500; }
+#debug { position:relative; top:1em; right:1em; z-index:5000; }
     #debug .inner { position:absolute; top:0; right:0; padding:1em; }
     #debug .inner > * { float:right; margin-right:1em; }
 */
 
-.debug { z-index:500; }
+.debug { z-index:5000; }
     .debug .inner { top:0; right:0; padding:1em; }
 
 #info { position:absolute; top:1em; right:1em; }
@@ -87,3 +78,12 @@ table.grid td { /* outline:1px solid rgba(255,255,255,0.1); */
         border:0; background-color:rgba(0,0,0, 0.1) ! important; color:#5c5c5c; }
     #config input[type=checkbox] { top:0.33em; }
 
+
+table.grid { position:absolute; top:0; left:0; z-index:10; }
+table.grid,
+table.grid td { /* outline:1px solid rgba(255,255,255,0.1); */ 
+    color:transparent; font: 18pt monospace; 
+    margin:0; padding:0; white-space:nowrap; overflow:hidden; }
+.showGridCoords table.grid td:hover { color:rgba(255,255,255,0.1); }
+
+.ezl.layer.pathmap { z-index:50; }
index b943aaf..0387257 100644 (file)
@@ -20,6 +20,7 @@
 <script src="build/jquery.sparkline.js" type="text/javascript"></script>
 <script src="build/Y/modules/y.event.js" type="text/javascript"></script>
 <script src="build/ezl/util.js" type="text/javascript"></script>
+<script src="build/ezl/layer.js" type="text/javascript"></script>
 <script src="build/ezl/loop/fps.js" type="text/javascript"></script>
 <script src="build/ezl/math/vec.js" type="text/javascript"></script>
 <script src="build/ezl/loop/cooldown.js" type="text/javascript"></script>
 <script src="build/ezl/math/line.js" type="text/javascript"></script>
 <script src="build/ezl/math/rect.js" type="text/javascript"></script>
 <script src="build/ezl/math.js" type="text/javascript"></script>
-<script src="build/ezl/loop/fx.js" type="text/javascript"></script>
 <script src="build/ezl/loc/boundingbox.js" type="text/javascript"></script>
+<script src="build/ezl/loop/fx.js" type="text/javascript"></script>
+<script src="build/ezl/layer/layer.js" type="text/javascript"></script>
 <script src="build/ezl/loop.js" type="text/javascript"></script>
 <script src="build/ezl/loc/square.js" type="text/javascript"></script>
 <script src="build/ezl/loc.js" type="text/javascript"></script>
-<script src="build/ezl/layer.js" type="text/javascript"></script>
-<script src="build/ezl/shape/shape.js" type="text/javascript"></script>
 <script src="build/ezl/widget/cooldown.js" type="text/javascript"></script>
+<script src="build/ezl/shape/shape.js" type="text/javascript"></script>
 <script src="build/ezl/shape/line.js" type="text/javascript"></script>
 <script src="build/ezl/shape/polygon.js" type="text/javascript"></script>
 <script src="build/ezl/widget.js" type="text/javascript"></script>
-<script src="build/ezl/shape/circle.js" type="text/javascript"></script>
 <script src="build/ezl/shape/rect.js" type="text/javascript"></script>
+<script src="build/ezl/shape/circle.js" type="text/javascript"></script>
 <script src="build/ezl/shape.js" type="text/javascript"></script>
 <script src="build/ezl.js" type="text/javascript"></script>
 <script src="build/tanks/globals.js" type="text/javascript"></script>
 <script src="build/jquery.hotkeys.js" type="text/javascript"></script>
 <script src="build/Y/modules/y.kv.js" type="text/javascript"></script>
-<script src="build/ezl/util/binaryheap.js" type="text/javascript"></script>
+<script src="build/ezl/util/tree/binaryheap.js" type="text/javascript"></script>
 <script src="build/ezl/util/tree/quadtree.js" type="text/javascript"></script>
 <script src="build/Y/modules/y.scaffold.js" type="text/javascript"></script>
 <script src="build/Y/modules/y.config.js" type="text/javascript"></script>