# Buff definitions
name: buff
+lookup: .tanks.data.buffs
defaults:
symbol: tanks/effects/buff.Buff
timeout: -1 # the Infinity literal is not valid JSON
# Item definitions
name: item
+lookup: .tanks.data.items
defaults:
symbol: tanks/thing/item.Item
types:
+# Level definitions
+name: level
+lookup: .tanks.data.levels
+defaults:
+ symbol: tanks/map/level.Level
+types:
+ test:
+ name: Da Test
+ desc: A 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]]
+ # left: [[-50,0, 50,500]]
+ # right: [[501,0, 551,351], [351,351, 401,501]]
+ # bottom: [[-50,501, 401,551]]
+ bounds:
+ - [-50,-50, 600,50]
+ - [-50,0, 50,500]
+ - [501,0, 50,500]
+ - [-50,501, 600,50]
+ # - [351,351, 200,200]
+ walls:
+ - [300,50, 50,200] # [x,y, w,h]
+ - [300,350, 50,100]
+ - [50,350, 100,100]
+ - [150,300, 50,50]
+ - [100,100, 50,50]
+ units:
+ - type: player
+ align: 1
+ loc: [275,475]
+ - type: blue
+ align: 1
+ loc: [175,475]
+ - type: green
+ align: 2
+ loc: [25,375]
+ - type: green
+ align: 2
+ loc: [75,25]
+ - type: green
+ align: 2
+ loc: [425,75]
+ items: []
+ events: []
+ art:
+ bg: ''
+ doodads: []
# Unit definitions
name: unit
+lookup: .tanks.data.units
defaults:
symbol: tanks/thing/thing.Thing
level: 1
name: Player
desc: "Don't hate the Player, hate the--Wait. No, that's fine."
tags: [ 'tank' ]
- symbol: tanks/thing/player.PlayerTank
+ symbol: tanks/thing/player.Player
stats:
hp : 1
move : 0.90
if v is not True: kwargs.append(str(v))
return sh('commonjs %s' % ' '.join( SRC_DIRS + kwargs + list(args)), capture=capture)
+
@task
def data():
"Convert all yaml files to json."
, del = require('Y/delegate')
, type = require('Y/type')
, op = require('Y/op')
-, mixInto = require('Y/utils').mixInto
+, proxy = require('Y/utils').proxy
, YCollection = require('Y/types/collection').YCollection
, _Array = Array
var newYArray = YArray.instantiate.bind(YArray);
- mixInto({ target:YArray, donor:_Array, context:'_o',
+ proxy({ target:YArray, donor:_Array, context:'_o',
names:'indexOf lastIndexOf shift join'.split(' ') });
- mixInto({ target:YArray, donor:_Array, context:'_o', chain:true,
+ proxy({ target:YArray, donor:_Array, context:'_o', chain:true,
names:'push unshift sort splice reverse'.split(' ') });
- mixInto({ target:YArray, donor:_Array, context:'_o', fnFirst:true, wrap:newYArray,
+ proxy({ target:YArray, donor:_Array, context:'_o', fnFirst:true, wrap:newYArray,
names:'map forEach filter'.split(' ') });
- mixInto({ target:YArray, donor:_Array, context:'_o', fnFirst:true,
+ proxy({ target:YArray, donor:_Array, context:'_o', fnFirst:true,
names:['reduce', 'some', 'every'] });
- mixInto({ target:YArray, donor:_Array, context:'_o', wrap:newYArray,
+ proxy({ target:YArray, donor:_Array, context:'_o', wrap:newYArray,
names:['slice'] });
var YCollection = require('Y/types/collection').YCollection
-, mixInto = require('Y/utils').mixInto
+, proxy = require('Y/utils').proxy
, op = require('Y/op')
, core = require('Y/core')
, del = require('Y/delegate')
YCollection.subclass('YString', function(YString){
var newYString = YString.instantiate.bind(YString);
- mixInto({ target:YString, donor:String, context:'_o', wrap:newYString,
+ proxy({ target:YString, donor:String, context:'_o', wrap:newYString,
names:'slice substr substring concat replace toLowerCase toUpperCase'.split(' ') });
- mixInto({ target:YString, donor:String, context:'_o',
+ proxy({ target:YString, donor:String, context:'_o',
names:'split indexOf lastIndexOf charAt charCodeAt'.split(' ') });
function trim(val){
var
-This = mixInto['This'] = {},
-Target = mixInto['Target'] = {},
+This = proxy['This'] = {},
+Target = proxy['Target'] = {},
defaults = {
/**
* {Object|Function} target Required. Target object onto which methods will be added. If this a Function, it's prototype will be used.
'names' : null,
/**
- * {mixInto.This|mixInto.Target|String} [context=mixInto.This]
+ * {proxy.This|proxy.Target|String} [context=proxy.This]
* Sets the call context for the function.
- * - {mixInto.This}: (Default) Use runtime `this` as context.
- * - {mixInto.Target}: Use `target` as context.
+ * - {proxy.This}: (Default) Use runtime `this` as context.
+ * - {proxy.Target}: Use `target` as context.
* - {String}: Names a property on `this` to use. If specified and property is false-y, `this` is used.
*/
'context' : This,
*/
'fnFirst' : false
};
-function mixInto(options){
+function proxy(options){
var o = core.extend({}, defaults, options)
, target = o.target
, donor = o.donor
}
exports['bindAll'] = bindAll;
-exports['mixInto'] = mixInto;
+exports['proxy'] = proxy;
var initialise = instance.__initialise__;
if ( isFunction(initialise) )
- return initialise.apply(instance, args);
+ initialise.apply(instance, args);
+
+ cls.fire('created', instance, {
+ 'instance' : instance,
+ 'cls' : cls,
+ 'args' : Y(args)
+ });
}
return instance;
eval(constructor);
- // Copy Class statics
- // for (var i=0, L=classStatics.length; i<L; ++i) {
- // var k = classStatics[i];
- // NewClass[k] = ClassFactory[k];
- // }
-
// Copy parent methods, then add new instance methods
for (var k in parentMembers)
if ( hasOwn.call(parentMembers,k) )
setDesc(prototype, k, getDesc(members,k));
}
+ NewClass.instantiate = instantiate.partial(NewClass);
// prototype.__bind__ = Y([]).concat(prototype.__bind__||[], SuperClass.fn.__bind__||[]).unique();
// Notify mixins to let them finish up any customization
this.remove();
this.dirty = true;
+ if ( !(parent instanceof Layer) && (parent.shape instanceof Layer) )
+ parent = parent.shape;
+
// Layer? Add self as new child, fix DOM
if ( parent instanceof Layer ) {
this.parent = parent;
this.parent.children.remove(this);
this.parent = null;
this.layer.remove();
+ return this;
},
/**
if (w === undefined && h === undefined)
return new Vec(this.layerWidth,this.layerHeight);
+ if (w === null) w = this.layerWidth;
+ if (h === null) h = this.layerHeight;
+
this.layerWidth = w;
this.layerHeight = h;
});
this.canvas.css({
'width' : cw, 'height' : ch,
- 'margin-left' : -nb.x, 'top' : -nb.y
+ 'margin-left' : -nb.x, 'margin-top' : -nb.y
});
var el = this.canvas[0];
el.width = cw;
resolve : function resolve(spec){
var nameParts = spec.split('.')
, modName = nameParts.shift()
- ;
- if (!(modName && modName.length && nameParts.length))
- this.die('Cannot resolve symbol: '+spec);
+ , module ;
- var module = require(modName)
- , symbol = getNested(module, nameParts)
- ;
+ if (!modName)
+ module = window;
+ else
+ module = require(modName);
+
+ if (!nameParts.length)
+ this.die('Cannot resolve symbol: '+spec);
+ var symbol = getNested(module, nameParts)
if (!symbol)
this.die('Unable to locate class specified by symbol (symbol="'+spec+'", module='+module+' --> '+symbol+')!');
- if (!Y.isFunction(symbol.speciate))
- this.die('Cannot create types from data (symbol-class '+symbol+' from "'+spec+'" is not Speciated)!');
return symbol;
},
// console.group('DataFile: processing '+this.path);
var types = Y(data.types)
- , defaults = data.defaults || {};
+ , defaults = data.defaults || {}
+ , lookup = this.resolve(data.lookup)
+ ;
if (!(types && Y.isFunction(types.forEach)))
this.die('Specified types are not iterable! '+data.types);
this.die('No symbol defined for type "'+id+'" at '+this.path+'!');
delete props.symbol;
- var base = this.resolve(symbol)
- , type = base.speciate(id, props);
+ var base = this.resolve(symbol);
+
+ if (!Y.isFunction(base.speciate))
+ this.die('Cannot create types from data (symbol-class '+base+' from "'+symbol+'" is not Speciated)!');
+
+ var type = base.speciate(id, props);
+ lookup[id] = type;
+
// console.log('Added type '+id+':', type);
}, this);
this.clear();
},
+ resize : function resize(x1,y1, x2,y2){
+ Rect.call(this, x1,y1, x2,y2);
+ return this;
+ },
/**
* Determines if the given Rect overlaps with this tree,
ui : {
createGridCanvas : true,
createGridTable : false,
+ overlayOnPause : true,
showGridCoords : false,
showAttackCooldown : false,
showCountdown : (document.location.host.toString() !== 'tanks.woo')
/// Load Data Files ///
var files =
- 'types/buffs types/items types/units' // types/level levels game
+ 'types/buffs types/items types/units types/levels' // levels game
.split(' ')
.map(function(type){
return new DataFile('build/data/'+type+'.json');
, PathMapUI = require('tanks/ui/pathmapui').PathMapUI
, Level = map.Level
-, Thing = thing.Thing, Tank = thing.Tank, Bullet = thing.Bullet
+, Thing = thing.Thing
+, Tank = thing.Tank
+, Bullet = thing.Bullet
+, Player = thing.Player
,
this.viewport = $(viewport || GRID_ELEMENT);
this.loop = new EventLoop(FRAME_RATE, this);
- this.root =
- this.grid =
+ this.root =
+ this.grid =
new Grid(COLUMNS,ROWS, REF_SIZE)
.appendTo(this.viewport);
this.level =
- new Level(this, COLUMNS*REF_SIZE, ROWS*REF_SIZE)
+ Level.create('test', this, CAPACITY, REF_SIZE)
.appendTo(this.root);
- var pathmap = this.pathmap = this.level.pathmap;
- pathmap.ui = new PathMapUI(this, pathmap);
- this.level.append(pathmap.ui);
+ this.pathmap = this.level.pathmap;
+ this.pathmap.ui = new PathMapUI(this, this.pathmap);
+ this.root.append(this.pathmap.ui);
- Thing.addEventListener('init', this.addThing);
+ // automatically keep track of units
+ Thing.addEventListener('created', this.addThing);
Thing.addEventListener('destroy', this.killThing);
-
this.addEventListener('tick', this.tick);
+ this.level.setup();
this.fire('ready', this);
},
destroy : function destroy(){
- Thing.removeEventListener('init', this.addThing);
+ Thing.removeEventListener('created', this.addThing);
Thing.removeEventListener('destroy', this.killThing);
this.stop();
this.resetGlobals();
SQUARETH = REF_SIZE * SECONDTH;
},
+ // get width(){ return this.level.width; },
+ // get height(){ return this.level.height; },
+
draw : function draw(){
this.root.draw();
},
return animation;
},
- addThing : function addThing(unit, col,row){
+ addThing : function addThing(unit, x,y){
if (unit instanceof Event)
unit = unit.trigger;
unit.game = this;
- if (col !== undefined) {
- // Center unit in square
- var sqX = (col || 0) * REF_SIZE
- , sqY = (row || 0) * REF_SIZE
- , x = sqX + REF_SIZE/2
- , y = sqY + REF_SIZE/2 ;
-
+ if (x !== undefined) {
unit.position(x,y);
unit.render( this.level );
+ } else if ( unit.isRenderable ) {
+ unit.render( this.level );
}
this.pathmap.addBlocker(unit);
this.units.push(unit);
}
+ if (unit instanceof Player) {
+ if ( this.player && unit !== this.player )
+ throw new Error('wtf errant player created!');
+ this.player = unit;
+ }
+
return unit;
},
'ui' : require('tanks/ui'),
'Game' : require('tanks/game').Game,
- 'game' : null
+ 'game' : null,
+ 'data' : { 'buffs':{}, 'items':{}, 'units':{}, 'levels':{}, 'bullets':{} }
};
var Y = require('Y').Y
, op = require('Y/op')
-
+, proxy = require('Y/utils').proxy
+, evt = require('evt')
, Rect = require('ezl/shape').Rect
, Buff = require('tanks/effects/buff').Buff
+, PathMap = require('tanks/map/pathmap').PathMap
, Thing = require('tanks/thing/thing').Thing
, Tank = require('tanks/thing/tank').Tank
, Item = require('tanks/thing/item').Item
-, PlayerTank = require('tanks/thing/player').PlayerTank
-, PathMap = require('tanks/map/pathmap').PathMap
+, Player = require('tanks/thing/player').Player
, Wall = require('tanks/thing/wall').Wall
+, Speciated = require('tanks/mixins/speciated').Speciated
+
+, min = Y(Math.min).limit(2)
+, max = Y(Math.max).limit(2)
,
Level =
exports['Level'] =
-Rect.subclass('Level', {
+new evt.Class('Level', {
+ __mixins__ : [ Speciated ],
_cssClasses : 'ezl layer level',
- init : function init(game, w,h){
- Rect.init.call(this, w,h);
- this.canvas.remove();
-
- this.game = game;
- this.walls = Y([]);
- this.allWalls = Y([]);
- this.pathmap = new PathMap(this, 0,0, w, h, CAPACITY);
+ // bounds : [],
+ // walls : [
+ // [300,50, 50,200],
+ // [300,350, 50,100],
+ // [50,350, 100,100],
+ // [150,300, 50,50],
+ // [100,100, 50,50]
+ // ],
+
+
+ init : function init(game, capacity, buffer_size){
+ this.game = game;
+ this.pathmap = new PathMap(0,0, this.width, this.height, capacity, buffer_size);
- game.addEventListener('ready', this.setup.bind(this));
+ var shape = this.shape = new Rect(this.width,this.height).fill('transparent');
+ shape.layer.attr('class', this._cssClasses);
+ this.bbox = shape.bbox;
},
setup : function setup(){
var game = this.game;
- Y.map([ [6,1, 1,4],
- [6,7, 1,2],
- [1,7, 2,2],
- [3,6, 1,1],
- [2,2, 1,1] ],
- "this.addWall.apply(this, Y.map(_, '*REF_SIZE'))",
- this );
+ this.bounds =
+ Y(this.bounds).map(function(wall){
+ return Wall.instantiate.apply(Wall, wall.concat([true]));
+ });
- P =
- game.player = game.addThing(PlayerTank.create('player', 1), 5,9);
- game.addThing(Tank.create('blue', 1), 3,9);
+ this.walls =
+ Y(this.walls).map(function(wall){
+ return Wall.instantiate.apply(Wall, wall);
+ });
- E =
- game.addThing(Tank.create('green', 2), 0,7);
- game.addThing(Tank.create('green', 2), 1,0);
- game.addThing(Tank.create('green', 2), 8,1);
+ var unitdata = tanks.data.units;
+ this.units.map(function(u){
+ var unit = unitdata[u.type].instantiate(u.align);
+ return game.addThing(unit, u.loc[