From: dsc Date: Fri, 24 Dec 2010 19:52:34 +0000 (-0800) Subject: Adds properties for reflectivity and inventory; fills in Item collision code. X-Git-Url: http://git.lttlst.com:3516/?a=commitdiff_plain;h=ac6046ec99a710db08608076e13f70898f609d67;p=tanks.git Adds properties for reflectivity and inventory; fills in Item collision code. --- diff --git a/src/ezl/index.cjs b/src/ezl/index.cjs index 0b952af..112295b 100644 --- a/src/ezl/index.cjs +++ b/src/ezl/index.cjs @@ -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') }); diff --git a/src/tanks/abilities/buff.cjs b/src/ezl/layer/html.cjs similarity index 100% copy from src/tanks/abilities/buff.cjs copy to src/ezl/layer/html.cjs diff --git a/src/tanks/abilities/index.cjs b/src/ezl/layer/index.cjs similarity index 100% copy from src/tanks/abilities/index.cjs copy to src/ezl/layer/index.cjs diff --git a/src/ezl/layer.cjs b/src/ezl/layer/layer.cjs similarity index 98% rename from src/ezl/layer.cjs rename to src/ezl/layer/layer.cjs index 21f150f..75d5408 100644 --- a/src/ezl/layer.cjs +++ b/src/ezl/layer/layer.cjs @@ -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 , diff --git a/src/tanks/abilities/buff.cjs b/src/ezl/layer/text.cjs similarity index 100% copy from src/tanks/abilities/buff.cjs copy to src/ezl/layer/text.cjs diff --git a/src/ezl/shape/circle.cjs b/src/ezl/shape/circle.cjs index 733148a..909ee8d 100644 --- a/src/ezl/shape/circle.cjs +++ b/src/ezl/shape/circle.cjs @@ -1,5 +1,4 @@ -var Y = require('Y').Y -, Shape = require('ezl/shape/shape').Shape +var Shape = require('ezl/shape/shape').Shape , Circle = diff --git a/src/ezl/shape/line.cjs b/src/ezl/shape/line.cjs index e007377..d347c7a 100644 --- a/src/ezl/shape/line.cjs +++ b/src/ezl/shape/line.cjs @@ -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 , diff --git a/src/ezl/shape/shape.cjs b/src/ezl/shape/shape.cjs index 9e84fcc..e7ffad7 100644 --- a/src/ezl/shape/shape.cjs +++ b/src/ezl/shape/shape.cjs @@ -1,5 +1,4 @@ -var Y = require('Y').Y -, Layer = require('ezl/layer').Layer +var Layer = require('ezl/layer/layer').Layer , Shape = diff --git a/src/ezl/util/astar.cjs b/src/ezl/util/astar.cjs index 08e9885..1d15f05 100644 --- a/src/ezl/util/astar.cjs +++ b/src/ezl/util/astar.cjs @@ -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) { diff --git a/src/ezl/util/binaryheap.cjs b/src/ezl/util/tree/binaryheap.cjs similarity index 100% rename from src/ezl/util/binaryheap.cjs rename to src/ezl/util/tree/binaryheap.cjs diff --git a/src/ezl/widget/cooldown.cjs b/src/ezl/widget/cooldown.cjs index c7f492a..e94b51b 100644 --- a/src/ezl/widget/cooldown.cjs +++ b/src/ezl/widget/cooldown.cjs @@ -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 index 7e14ba2..0000000 --- a/src/tanks/calc.cjs +++ /dev/null @@ -1,5 +0,0 @@ -Calc = { - - - -}; \ No newline at end of file diff --git a/src/tanks/abilities/buff.cjs b/src/tanks/effects/buff.cjs similarity index 100% rename from src/tanks/abilities/buff.cjs rename to src/tanks/effects/buff.cjs diff --git a/src/tanks/abilities/index.cjs b/src/tanks/effects/index.cjs similarity index 100% rename from src/tanks/abilities/index.cjs rename to src/tanks/effects/index.cjs diff --git a/src/tanks/map/level.cjs b/src/tanks/map/level.cjs index 6736b4f..147a7a1 100644 --- a/src/tanks/map/level.cjs +++ b/src/tanks/map/level.cjs @@ -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){ diff --git a/src/tanks/map/pathmap.cjs b/src/tanks/map/pathmap.cjs index 623cc21..c82075b 100644 --- a/src/tanks/map/pathmap.cjs +++ b/src/tanks/map/pathmap.cjs @@ -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 diff --git a/src/tanks/map/traversal.cjs b/src/tanks/map/traversal.cjs index 4316d32..c51d193 100644 --- a/src/tanks/map/traversal.cjs +++ b/src/tanks/map/traversal.cjs @@ -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){ diff --git a/src/tanks/thing/bullet.cjs b/src/tanks/thing/bullet.cjs index b2a7e9c..22a02cc 100644 --- a/src/tanks/thing/bullet.cjs +++ b/src/tanks/thing/bullet.cjs @@ -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 diff --git a/src/tanks/thing/item.cjs b/src/tanks/thing/item.cjs index 704708a..231baef 100644 --- a/src/tanks/thing/item.cjs +++ b/src/tanks/thing/item.cjs @@ -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+')'; + } }) ; diff --git a/src/tanks/thing/player.cjs b/src/tanks/thing/player.cjs index d59b3ce..67a97cb 100644 --- a/src/tanks/thing/player.cjs +++ b/src/tanks/thing/player.cjs @@ -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){ diff --git a/src/tanks/thing/tank.cjs b/src/tanks/thing/tank.cjs index 939536d..9e69127 100644 --- a/src/tanks/thing/tank.cjs +++ b/src/tanks/thing/tank.cjs @@ -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'] = diff --git a/src/tanks/thing/thing.cjs b/src/tanks/thing/thing.cjs index 3315dc9..53945e3 100644 --- a/src/tanks/thing/thing.cjs +++ b/src/tanks/thing/thing.cjs @@ -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, diff --git a/src/tanks/thing/wall.cjs b/src/tanks/thing/wall.cjs index 781a991..b710e38 100644 --- a/src/tanks/thing/wall.cjs +++ b/src/tanks/thing/wall.cjs @@ -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){ diff --git a/src/tanks/ui/pathmapui.cjs b/src/tanks/ui/pathmapui.cjs index b2af103..13e7928 100644 --- a/src/tanks/ui/pathmapui.cjs +++ b/src/tanks/ui/pathmapui.cjs @@ -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; }, /** diff --git a/www/css/lttl.css b/www/css/lttl.css index 9a6b3f1..beac57f 100644 --- a/www/css/lttl.css +++ b/www/css/lttl.css @@ -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; } diff --git a/www/deps.html b/www/deps.html index b943aaf..0387257 100644 --- a/www/deps.html +++ b/www/deps.html @@ -20,6 +20,7 @@ + @@ -29,25 +30,25 @@ - + + - - + - + - +