Adds inventory UI.
authordsc <david.schoonover@gmail.com>
Mon, 17 Jan 2011 08:36:16 +0000 (00:36 -0800)
committerdsc <david.schoonover@gmail.com>
Mon, 17 Jan 2011 08:36:16 +0000 (00:36 -0800)
28 files changed:
data/types/buffs.yaml
data/types/items.yaml
data/types/levels.yaml
data/types/units.yaml
src/Y/modules/y.scaffold.cjs
src/ezl/layer/layer.cjs
src/ezl/widget/cooldown.cjs
src/tanks/game.cjs
src/tanks/globals.js
src/tanks/map/level.cjs
src/tanks/map/pathing/trajectory.cjs
src/tanks/map/rock.cjs
src/tanks/map/wall.cjs
src/tanks/mixins/inventoried.cjs
src/tanks/mixins/quantified.cjs
src/tanks/mixins/speciated.cjs
src/tanks/thing/bullet.cjs
src/tanks/thing/item.cjs
src/tanks/thing/tank.cjs
src/tanks/ui/index.cjs
src/tanks/ui/inventory/backpack.cjs
src/tanks/ui/inventory/index.cjs
src/tanks/ui/main.cjs
www/css/lttl.css
www/css/tipsy.css
www/game.html
www/header.html
www/img/items/green-sq.png [new file with mode: 0644]

index 9a555e6..2280501 100644 (file)
@@ -1,7 +1,7 @@
 name: buffs
 defaults:
     symbol: tanks/effects/buff.Buff
-    timeout: -1 # the Infinity literal is not valid JSON
+    timeout: -1 # the YAML .Inf (Infinity literal) is not valid JSON according to the native decoders
     priority: 0
     stack_limit: 1
 types:
@@ -9,9 +9,9 @@ types:
         name: Speed Up
         desc: Speeds up your tank temporarily.
         tags: [ 'movement' ]
-        timeout: 5.0
+        timeout: 3.0
         stats:
-            move: 2.0
+            move: 0.5
         effects: []
         art:
             icon: ''
index 2c3146b..90e0e87 100644 (file)
@@ -8,9 +8,11 @@ types:
         tags: [ 'movement' ]
         passives: []
         effects: [ 'speedup' ]
+        # effects:
+        #   - include: speedup
         cooldowns:
-            activate: 10
+            activate: 30.0
         art:
             map_icon: ''
-            inv_icon: ''
+            inv_icon: '/img/items/green-sq.png'
     
index 44a9f2a..875e7ba 100644 (file)
@@ -15,6 +15,67 @@ types:
         desc: A test level.
         width: 500
         height: 500
+        bounds:
+          - [-50,-50, 600,50]
+          - [-50,0, 50,500]
+          - [501,0, 50,500]
+          - [-50,501, 600,50]
+        walls:
+          - type: wall
+            args: [300,50, 50,200] # [x,y, w,h]
+          - type: wall
+            args: [300,350, 50,100]
+          - type: wall
+            args: [100,100, 50,50]
+         
+          - type: fence
+            args: [360,210, 30,30]
+          - type: rock
+            args: [400,200, 25,25]
+          - type: rock
+            args: [425,225, 25,25]
+          - type: fence
+            args: [460,210, 30,30]
+         
+          - type: fence
+            args: [10,210, 30,30]
+          - type: fence
+            args: [110,210, 30,30]
+          - type: fence
+            args: [210,210, 30,30]
+         
+          - type: rock
+            args: [50,350, 50,50]
+          - type: rock
+            args: [100,350, 50,50]
+          - type: rock
+            args: [50,400, 50,50]
+          - type: rock
+            args: [100,400, 50,50]
+          - type: rock
+            args: [150,300, 50,50]
+        units:
+          - type: player
+            align: 1
+            loc: [375,475]
+          - type: green
+            align: 2
+            loc: [75,25]
+          - type: green
+            align: 2
+            loc: [175,25]
+          # - type: green
+          #   align: 2
+          #   loc: [425,125]
+        items:
+          - type: nitro
+            loc: [325,475]
+    
+    three_test:
+        name: Three Test
+        desc: A more complex test level.
+        width: 500
+        height: 500
         # bounds: [[-1,-1], [501,-1], [501,351], [351,351], [351,501], [-1,501]]
         # bounds:
         #     top:    [[-50,-50, 600,50]]
@@ -104,10 +165,10 @@ types:
          
           - type: fence
             args: [360,210, 30,30]
-          - type: rock
-            args: [400,200, 25,25]
-          - type: rock
-            args: [425,225, 25,25]
+          # - type: rock
+          #   args: [400,200, 25,25]
+          # - type: rock
+          #   args: [425,225, 25,25]
           - type: fence
             args: [460,210, 30,30]
          
@@ -131,7 +192,7 @@ types:
         units:
           - type: blue
             align: 1
-            loc: [425,425]
+            loc: [475,425]
           - type: blue
             align: 1
             loc: [125,475]
@@ -171,3 +232,4 @@ types:
           - type: green
             align: 2
             loc: [225,325]
+
index 85f4ebb..e461135 100644 (file)
@@ -50,8 +50,8 @@ types:
             speed : 0.5
             shots : 3
         ai:
-            path          : 1.0
-            dodge         : 1.0
+            path          : 1.00
+            dodge         : 0.75
             shootIncoming : 0.25
             shootEnemy    : 0.75
         colors:
index 4fdbfe7..ea0f200 100644 (file)
@@ -141,7 +141,7 @@ function create(config, el){
             var g = 
             groups[chain] = 
                     jQuery('<fieldset/>')
-                        .attr('id', chain)
+                        .attr('id', 'group-'+chain)
                         .addClass('group')
                         .append( jQuery('<legend/>').text(chain.split('.').pop()) )
                         .appendTo(el);
index 7af06de..48b71b6 100644 (file)
@@ -57,7 +57,10 @@ Y.subclass('Layer', {
     
     /// Setup ///
     
-    init : function init(){
+    init : function init(props, attrs, html){
+        if (props)
+            Y.core.extend(this, props);
+        
         this.children   = new Y.YArray();
         this.animActive = new Y.YArray();
         this.animQueue  = new Y.YArray();
@@ -76,10 +79,11 @@ Y.subclass('Layer', {
             translate : new Loc(0,0) // translates canvas
         };
         
-        this.layer = jQuery('<div/>')
+        this.layer = jQuery(html || '<div/>')
             .addClass(this._cssClasses)
             .data('layer', this);
         this.layer[0].layer = this;
+        if (attrs) this.layer.attr(attrs);
         
         if (this.hasCanvas) {
             this.canvas = jQuery('<canvas />')
index e94b51b..d7429a4 100644 (file)
@@ -46,9 +46,9 @@ Layer.subclass('CooldownGauge', function setupCooldownGauge(CooldownGauge){
         var p = cool.ratio()
         ,   w = this.layerWidth, h = this.layerHeight
         ,   x = w*0.5, y = h*0.5
-        ,   amt = HALF_PI + (1 - p)*PI_AND_HALF;
+        ,   amt = -HALF_PI + (1 - p)*TWO_PI;
         
-        ctx.arc(x,y, w, HALF_PI, amt, false);
+        ctx.arc(x,y, w, -HALF_PI, amt, false);
         ctx.lineTo(x,y);
         ctx.lineTo(x,0);
         ctx.fill();
index 582ed8e..08c7d0a 100644 (file)
@@ -14,6 +14,7 @@ var Y         = require('Y').Y
 ,   Level     = require('tanks/map/level').Level
 ,   Grid      = require('tanks/ui/grid').Grid
 ,   PathMapUI = require('tanks/ui/pathmapui').PathMapUI
+,   Backpack  = require('tanks/ui/inventory/backpack').Backpack
 
 ,   Thing  = thing.Thing
 ,   Tank   = thing.Tank
@@ -41,37 +42,50 @@ Y.subclass('Game', {
         if (levelId) this.levelId = levelId;
         
         this.byId = {};
+        this.toTick     = new Y.YArray();
         this.active     = new Y.YArray();
         this.units      = new Y.YArray();
         this.bullets    = new Y.YArray();
         this.animations = new Y.YArray();
         
-        this.viewport = $(GRID_ELEMENT);
+        // this.el = $(GAME_ELEMENT);
         this.loop = new EventLoop(FRAME_RATE, this);
         
         this.root =
-            new Layer()
-                .appendTo(this.viewport);
+            new Layer({ hasCanvas:false }, { 'id':'game' })
+                .prependTo( $('body') );
+        // this.root.shape.remove();
+        // this.root.layer.attr('id', 'viewport');
+        
+        this.viewport = 
+            new Layer({ hasCanvas:false }, { 'id':'viewport' })
+                .appendTo( this.root );
+        
         this.level =
             Level.create(this.levelId, this, CAPACITY, REF_SIZE)
-                .appendTo(this.root);
+                .appendTo( this.viewport );
         this.grid =
             new Grid(this.level, REF_SIZE)
-                .prependTo(this.root);
+                .prependTo( this.viewport );
         this.viewport
             .width(this.level.width)
             .height(this.level.height);
         
         this.map = this.level.map;
         this.map.ui = new PathMapUI(this, this.map);
-        this.root.append(this.map.ui);
+        this.viewport.append(this.map.ui);
         
         // automatically keep track of units
-        Thing.addEventListener('created', this.addThing);
-        Thing.addEventListener('destroy', this.killThing);
+        Thing.addEventListener('created', this.addUnit);
+        Thing.addEventListener('destroy', this.killUnit);
         this.addEventListener('tick', this.tick);
         
         this.level.setup();
+        if (this.player) {
+            this.backpack = new Backpack(this.player)
+                    .appendTo( this.root )
+                    .refresh();
+        }
         
         if (replayFile) {
             this.isReplay = true;
@@ -81,8 +95,10 @@ Y.subclass('Game', {
     },
     
     destroy : function destroy(){
-        Thing.removeEventListener('created', this.addThing);
-        Thing.removeEventListener('destroy', this.killThing);
+        Thing.removeEventListener('created', this.addUnit);
+        Thing.removeEventListener('destroy', this.killUnit);
+        this.root.remove();
+        // this.backpack && this.backpack.remove();
         this.stop();
         this.resetGlobals();
     },
@@ -100,6 +116,7 @@ Y.subclass('Game', {
     
     draw : function draw(){
         this.root.draw();
+        // this.backpack.draw();
     },
     
     /**
@@ -116,8 +133,8 @@ Y.subclass('Game', {
         SECONDTH = this.SECONDTH = ELAPSED / 1000;
         SQUARETH = this.SQUARETH = REF_SIZE * SECONDTH;
         
-        this.active.invoke('updateCooldowns', ELAPSED, NOW);
-        this.active.invoke('act', ELAPSED, NOW);
+        this.toTick.invoke('tick', ELAPSED, NOW, TICKS);
+        this.active.invoke('act',  ELAPSED, NOW, TICKS);
         this.animations = this.animations.filter(this.tickAnimations, this);
         
         this.draw();
@@ -154,7 +171,7 @@ Y.subclass('Game', {
     },
     
     tickAnimations : function tickAnimations(animation){
-        var running = animation.tick(ELAPSED, NOW);
+        var running = animation.tick(ELAPSED, NOW, TICKS);
         if (!running)
             animation.remove();
         return running;
@@ -170,18 +187,21 @@ Y.subclass('Game', {
         return animation;
     },
     
-    noteThing : function noteThing(unit){
+    noteUnit : function noteUnit(unit){
         unit.game = this;
         if (unit.dead) return unit;
         
-        if ( unit.active && !this.byId[unit.__id__] ) {
+        if ( !this.byId[unit.__id__] ) {
             this.byId[unit.__id__] = unit;
-            this.active.push(unit);
             
+            if (unit.active)
+                this.active.push(unit);
             if (unit.isProjectile)
                 this.bullets.push(unit);
             if (unit.isCombatant)
                 this.units.push(unit);
+            if (unit.tick)
+                this.toTick.push(unit);
         }
         
         if (unit instanceof Player) {
@@ -194,13 +214,13 @@ Y.subclass('Game', {
         return unit;
     },
     
-    addThing : function addThing(unit, x,y){
+    addUnit : function addUnit(unit, x,y){
         if (unit instanceof Event)
             unit = unit.trigger;
         
         if (unit.dead) return unit;
         
-        this.noteThing(unit);
+        this.noteUnit(unit);
         
         if (x !== undefined) {
             unit.position(x,y);
@@ -214,22 +234,31 @@ Y.subclass('Game', {
         return unit;
     },
     
-    killThing : function killThing(unit){
+    killUnit : function killUnit(unit){
         if (unit instanceof Event)
             unit = unit.data.unit;
         
         delete this.byId[unit.__id__];
-        this.active.remove(unit);
         this.map.removeBlocker(unit);
         
-        if (unit instanceof Bullet)
+        if (unit.active)
+            this.active.remove(unit);
+        if (unit.tick)
+            this.toTick.remove(unit);
+        if (unit.isProjectile)
             this.bullets.remove(unit);
-        else
+        if (unit.isCombatant)
             this.units.remove(unit);
         
         return unit;
     },
     
+    removeUnitFromMap : function removeUnitFromMap(unit){
+        unit.remove();
+        this.map.removeBlocker(unit);
+        return unit;
+    },
+    
     moveThingTo : function moveThingTo(agent, x,y){
         this.map.removeBlocker(agent);
         if (agent.dead) return agent;
index 24b2520..9475af0 100644 (file)
@@ -1,7 +1,7 @@
 
 var undefined
 ,   Y = require('Y').Y
-,   GRID_ELEMENT  = '#viewport'
+,   GAME_ELEMENT  = '#game'
 
 ,   REF_SIZE      = 50
 ,   CELL_SIZE     = REF_SIZE
index 50fa1ab..21944c9 100644 (file)
@@ -51,17 +51,17 @@ new evt.Class('Level', {
             // if (isReplay && x.type === 'player')
             //     return null;
             var obj = data[x.type].instantiate(x.align);
-            return game.addThing(obj, x.loc[0], x.loc[1]);
+            return game.addUnit(obj, x.loc[0], x.loc[1]);
         });
         
         var data = tanks.data.items;
         this.items.map(function(x){
             var obj = data[x.type].instantiate();
-            return game.addThing(obj, x.loc[0], x.loc[1]);
+            return game.addUnit(obj, x.loc[0], x.loc[1]);
         });
         
         // I =
-        // game.addThing(Item.create('nitro'), 8,8);
+        // game.addUnit(Item.create('nitro'), 8,8);
         
         return this;
     }
index deafe60..fc3f14f 100644 (file)
@@ -70,21 +70,6 @@ Line.subclass('Trajectory', {
     },
     
     
-    canSee : function canSee(obj, ignore){
-        ignore = [this.owner].concat(ignore || []);
-        // var blockers = this.map.denseWalls
-        //         .apply('remove', ignore)
-        //         .filter(this.intersects)
-        //         .sort( this.compare )
-        var blockers = this.map.denseWalls
-        ,   blockers = blockers.apply('remove', ignore).concat([ obj ])
-        ,   blockers = blockers.filter(this.intersects)
-        ,   blockers = blockers.sort(this.compare)
-        ,   blocker = blockers.first()
-        ;
-        return !!(blocker === obj);
-    },
-    
     intersects : function intersects(x,y){
         var o = x;
         if (o.bbox)
@@ -199,6 +184,21 @@ Line.subclass('Trajectory', {
         return ( t <= ft && (dw <= w || dh <= h) );
     },
     
+    canSee : function canSee(obj, ignore){
+        ignore = [this.owner].concat(ignore || []);
+        // var blockers = this.map.denseWalls
+        //         .apply('remove', ignore)
+        //         .filter(this.intersects)
+        //         .sort( this.compare )
+        var blockers = this.map.denseWalls
+                .apply('remove', ignore).concat([ obj ])
+                .filter(this.intersects)
+                .sort(this.compare)
+        ,   blocker = blockers.first()
+        ;
+        return !!(blocker === obj);
+    },
+    
     pathBlocked : function pathBlocked(obj, ignore){
         // var walls, blockers
         // if (this.owner.isProjectile)
@@ -218,6 +218,28 @@ Line.subclass('Trajectory', {
         return (blocker === obj ? false : blocker);
     },
     
+    calcIntersectTraj : function calcIntersectTraj(fireLoc, speed){
+        // targetVelocityVector = math.Vector3(0, 0, 0) * aTargetSpeed
+        // interceptVelocityVector = math.Vector3(0, 0, 0) * aBulletSpeed
+        //    
+        // tDelta = aTargetPosition - aFiringPosition
+        //    
+        // Vr = targetVelocityVector - interceptVelocityVector
+        // a = Vr.Dot( Vr ) - aBulletSpeed * aBulletSpeed
+        // b = 2 * Vr.Dot( tDelta )
+        // c = tDelta.Dot ( tDelta )
+        //    
+        // deter = b * b - 4 * ( a * c )
+        //    
+        // if deter < 0:
+        //   return -1
+        // else:
+        //   ETN = 2 * ( c / pdmath.sqrt(deter) - b )
+        //   return ETN
+        
+    },
+    
+    
     toString : function(){
         return 'T['+this.p1+', '+this.p2+', slope='+this.slope.toFixed(3)+']';
     }
index 6ee11dc..4cac56d 100644 (file)
@@ -61,7 +61,7 @@ Wall.subclass('Rock', {
                 if ( gapOk && (x <= gapX && gapX <= nextX) && (y <= gapY && gapY <= nextY) ) {
                     rock.dead = true; // Don't recursively fire destroy event
                     rock.divide(gap).remove();
-                    this.game.killThing(rock);
+                    this.game.killUnit(rock);
                 }
             }
         }
index 19a7306..5c5e37a 100644 (file)
@@ -38,6 +38,7 @@ Thing.subclass('Wall', {
     // inactive
     active : false,
     createCooldowns : op.nop,
+    tick : op.nop,
     
     stats : {
         hp    : Infinity,
index 8579128..9b33bbe 100644 (file)
@@ -20,7 +20,7 @@ Mixin.subclass('Inventoried', {
             'item1' : 'consumable',
             'item2' : 'consumable'
         },
-        max       : 10,     // Backpack capacity
+        max       : 12,     // Backpack capacity
         size      : 0,      // Number of items
         items     : null,   // item id -> Item { backpack:backpack[i], slot:slotName }
         backpack  : null,   // Array of positions of items in backpack: backpack idx -> item id
@@ -153,8 +153,8 @@ Mixin.subclass('Inventoried', {
     },
     
     
-    _fireItemChange : function _fireItemChange(evt, item){
-        var data = { 'unit':this, 'item':item };
+    _fireItemChange : function _fireItemChange(evt, item, data){
+        data = Y.extend({ 'unit':this, 'item':item }, data || {});
         this.fire(evt, item, data);
         item.fire(evt, this, data);
         return this;