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')
});
//#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
,
-var Y = require('Y').Y
-, Shape = require('ezl/shape/shape').Shape
+var Shape = require('ezl/shape/shape').Shape
,
Circle =
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
,
-var Y = require('Y').Y
-, Layer = require('ezl/layer').Layer
+var Layer = require('ezl/layer/layer').Layer
,
Shape =
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) {
var Y = require('Y').Y
-, Layer = require('ezl/layer').Layer
+, Layer = require('ezl/layer/layer').Layer
, PI = Math.PI
, QUARTER_PI = PI/4
+++ /dev/null
-Calc = {
-
-
-
-};
\ No newline at end of file
// 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){
, 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
},
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){
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
, 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){
.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+')';
+ }
})
;
exports['PlayerTank'] =
Tank.subclass('PlayerTank', {
blocking : map.BLOCKING,
+ hasInventory : true,
bodyColor : '#E73075',
turretColor : '#A72F5B',
shots : 5 // max projectiles in the air at once
},
+ /// Instance ///
+
+ align : null,
+
init : function init(align){
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
},
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'] =
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,
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,
shots : 0
},
+ // Instance
+
isBoundary : false,
this.position(x,y);
},
- // inactive
- createCooldowns : op.nop,
-
- // indestructable
- dealDamage : op.nop,
render : function render(parent){
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
,
// 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;
},
/**
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; }
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; }
#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;*/ }
*/
/*
-#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; }
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; }
<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>