var Y = require('Y').Y
-, Emitter = require('Y/modules/y.event').Emitter
+, getNested = require('Y/types/object').getNested
+, Emitter = require('Y/modules/y.event').Emitter
,
Config =
-exports.Config =
-Y.YObject.subclass('Config', function(){
+exports['Config'] =
+Y.YObject.subclass('Config', function(Config){
Y.core.extend(this, {
init : function initConfig(defaults){
- this._defaults = defaults;
- this._o = Y({}, defaults);
+ this._defaults = defaults || {};
+ this._o = Y({}, this._defaults);
this.__emitter__ = new Emitter(this);
},
+ clone : function clone(){
+ var c = new Config();
+ c._defaults = this._defaults;
+ c._o = c._o.clone();
+ return c;
+ },
+
set : function set(key, value, def){
if ( key !== undefined ){
- var meta = this.ensure(key).getNested(key, def, true)
+ var meta = this.ensure(key).getNestedMeta(key, def)
, old = meta.value ;
def = (def === undefined ? old : def);
value = (value === undefined ? def : value);
remove : function remove(key){
if ( key !== undefined ){
var sentinel = {}
- , meta = this.getNested(key, sentinel, true)
+ , meta = this.getNestedMeta(key, sentinel)
, old = (meta.value === sentinel ? undefined : old);
if ( meta.obj ) {
context = context || this;
var ret = Y.reduce(this._o, this._reducer, {
+ 'fn' : fn,
'acc' : acc,
'path' : new Y.YArray(),
'cxt' : context
// Normal value -- invoke iterator
else
- state.acc = fn.call(state.cxt, state.acc, v, chain, this);
+ state.acc = state.fn.call(state.cxt, state.acc, v, chain, this);
state.path.pop();
return state;
+ },
+
+ /**
+ * Iterates over both items and groups of the config object.
+ */
+ parts : function parts(groupFn, itemFn, acc, context){
+ context = context || this;
+
+ var path = new Y.YArray();
+ return Y.reduce(this._o,
+ function _parts(acc, v, k, o){
+ var chain = path.push(k).join('.');
+
+ // Nested object -- recurse
+ if ( Y.isPlainObject(v) ){
+ acc = groupFn.call(context, acc, v, chain, this);
+ acc = Y.reduce(v, _parts, acc, this);
+
+ // Normal value -- invoke iterator
+ } else
+ acc = itemFn.call(context, acc, v, chain, this);
+
+ path.pop();
+ return acc;
+ },
+ acc, this);
+ },
+
+ getDefault : function getDefault(k, def){
+ return getNested(this._defaults, k, def);
}
});
+ this['get'] = this.getNested;
+
});
+
+Y['config'] = exports;
--- /dev/null
+//#ensure "jquery"
+var Y = require('Y').Y
+, Emitter = require('Y/modules/y.event').Emitter
+, op = Y.op
+
+
+, upperPat = /^[A-Z]+$/
+, symbolPat = /^[^a-zA-Z]+$/
+,
+camelToSpaces =
+exports['camelToSpaces'] =
+function camelToSpaces(s){
+ return Y(s).reduce(
+ function(acc, ch, i){
+ return acc + (
+ symbolPat.test(ch) ? '' :
+ (upperPat.test(ch) ? ' '+ch : ch) );
+ }, '');
+}
+,
+
+type2parser = {
+ 'Boolean' : op.parseBool,
+ 'Number' : parseFloat,
+ 'String' : String
+}
+,
+
+type2el = {
+ 'Boolean' : 'checkbox',
+ 'Number' : 'text',
+ 'String' : 'text'
+ // 'Array' : 'select',
+ // 'Date' : 'datepicker',
+ // 'RegExp' : 'text'
+}
+,
+
+
+
+Field =
+exports['Field'] =
+Y.subclass('Field', {
+
+ init : function initField(chain, def, val, options){
+ options = options || {};
+ this.__emitter__ = new Emitter(this);
+
+ this.id = chain;
+ this.def = def;
+ this.val = this.old = val === undefined ? def : val;
+ this.key = chain.split('.').pop();
+ this.label = camelToSpaces(this.key);
+
+ var T = Y(Y.type(val)).getName();
+ this.cast = options.cast || type2parser[T];
+ this.type = options.type || type2el[T];
+
+ if (!this.cast)
+ throw new Error('No parser defined for type "'+T+'"');
+ if (!this.type)
+ throw new Error('No field element defined for type "'+T+'"');
+
+ this.build()
+ .update(this.val);
+
+ this.elField.bind('change', this.onChange.bind(this));
+ },
+
+ build : function build(){
+ var el =
+ this.el =
+ jQuery('<div/>')
+ .addClass('field');
+ this.elLabel =
+ jQuery('<label/>')
+ .attr('for', this.id)
+ .text(this.label)
+ .appendTo(el);
+ this.elField =
+ jQuery('<input/>')
+ .attr({
+ 'id' : this.id,
+ 'type' : this.type,
+ 'name' : this.key
+ })
+ .val(this.val)
+ .appendTo(el);
+ return this;
+ },
+
+ update : function update(val){
+ var el = this.elField;
+ if (val !== this.val) {
+ this.old = this.val;
+ this.val = val;
+ this.fire('change', this, {
+ 'key' : this.id,
+ 'oldval' : this.old,
+ 'newval' : this.val,
+ 'el' : this.elField
+ });
+ el.val(val);
+ }
+ if (this.type === 'checkbox')
+ el.attr('checked', !!this.val);
+ return this;
+ },
+
+ onChange : function onChange(evt){
+ this.update( this.cast(this.elField.val()) );
+ }
+
+})
+,
+
+
+create =
+exports['create'] =
+function create(config, el){
+ config.parts(
+ function createGroup(oldGroup, value, chain){
+ return jQuery('<fieldset/>')
+ .attr('id', chain)
+ .addClass('group')
+ .append( jQuery('<legend/>').text(chain.split('.').pop()) )
+ .appendTo(el);
+ },
+ function createField(group, value, chain){
+ var def = config.getDefault(chain)
+ , field = new Field(chain, def, value);
+
+ group.append(field.el);
+ config.addEventListener('set:'+chain, function onConfigSet(evt){
+ field.update(evt.data.newval);
+ });
+ field.addEventListener('change', function onFieldChange(evt){
+ config.set(evt.data.key, evt.data.newval);
+ });
+
+ return group;
+ },
+ el);
+ return el;
+}
+;
+
+Y.YString.fn['camelToSpaces'] = Y(camelToSpaces).methodize()
+
+
+Y['scaffold'] = exports;
};
},
- end : function end(o){ return ((o && o.__y__) ? o.end() : o); }
+ // misc
+ end : function end(o){ return ((o && o.__y__) ? o.end() : o); },
+ parseBool : function(s){
+ var i = parseInt(s);
+ return isNaN(i) ? (s && s.toLowerCase() !== 'false') : i;
+ }
};
, _Array = globals.Array
, _String = globals.String
, _Number = globals.Number
+, _Boolean = globals.Boolean
, FN = "constructor"
, PT = "prototype"
core.forEach({
- 'ensure' : ensure,
- 'metaGetter' : metaGetter,
- 'getNested' : getNested,
- 'setNested' : setNested
+ 'ensure' : ensure,
+ 'getNestedMeta' : getNestedMeta,
+ 'getNested' : getNested,
+ 'setNested' : setNested
}, function(fn, name){
fn = exports[name] = YFunction(fn);
YObject.fn[name] = fn.methodize();
, NUM_SAMPLES = 33
,
-methods = {
- // framerate : 0, // Target framerate
- // frametime : 0, // 1000 / framerate
- // samples : NUM_SAMPLES, // Number of frames to track for effective fps
- //
- // now : 0, // Last tick time (ms)
- // fps : 0, // Effective framerate
- // ticks : 0, // Number of ticks since start
- //
- // timer : null,
- // running : false,
- // times : null, // Last `samples` frame durations
+
+EventLoop =
+exports['EventLoop'] =
+Emitter.subclass('EventLoop', {
+ samples : NUM_SAMPLES, // Number of frames to track for effective fps
+ dilation : 1.0,
+
+ framerate : 0, // Target framerate
+ frametime : 0, // 1000 / framerate
+
+ now : 0, // Last tick time (ms)
+ fps : 0, // Effective framerate
+ ticks : 0, // Number of ticks since start
+
+ timer : null,
+ running : false,
+ times : null, // Last `samples` frame durations
/**
this.framerate = framerate;
this.targetTime = 1000 / framerate;
- this.samples = samples || NUM_SAMPLES;
- this.dilation = dilation || 1.0;
+
+ if (samples !== undefined)
+ this.samples = samples;
+ if (dilation !== undefined)
+ this.dilation = dilation;
this.reset();
},
return (this.realtimes.reduce(Y.op.add,0) / this.realtimes.length);
}
-},
-
-EventLoop =
-exports['EventLoop'] =
-Emitter.subclass('EventLoop', methods)
+})
;
+
function decorate(delegate){
if (!delegate) return;
- Emitter.prototype.decorate.call(this, delegate);
+ Emitter.fn.decorate.call(this, delegate);
['start', 'stop', 'reset']
.forEach(function(k){
- delegate[k] = methods[k].bind(this);
+ delegate[k] = EventLoop.fn[k].bind(this);
}, this);
return delegate;
}
var Y = require('Y').Y
+, getNested = require('Y/types/object').getNested
, Emitter = require('Y/modules/y.event').Emitter
,
Config =
-exports.Config =
-Y.YObject.subclass('Config', function(){
+exports['Config'] =
+Y.YObject.subclass('Config', function(Config){
Y.core.extend(this, {
init : function initConfig(defaults){
- this._defaults = defaults;
- this._o = Y({}, defaults);
+ this._defaults = defaults || {};
+ this._o = Y({}, this._defaults);
this.__emitter__ = new Emitter(this);
},
+ clone : function clone(){
+ var c = new Config();
+ c._defaults = this._defaults;
+ c._o = c._o.clone();
+ return c;
+ },
+
set : function set(key, value, def){
if ( key !== undefined ){
var meta = this.ensure(key).getNested(key, def, true)
state.path.pop();
return state;
+ },
+
+ getDefault : function getDefault(k, def){
+ return getNested(this._defaults, k, def);
}
});
+ this['get'] = this.getNested;
+
});
// -*- mode: JavaScript; tab-width: 4; indent-tabs-mode: nil; -*-
var Y = require('Y').Y
+, Config = require('y/modules/y.config').Config
+,
-, defaults =
+defaults =
exports['defaults'] = {
game : {
timeDilation : 1.0,
gameoverDelay : 1000
},
ui : {
- createGridCanvas : 1,
- createGridTable : 0,
- showGridCoords : 0,
- showAttackCooldown : 0,
+ createGridCanvas : true,
+ createGridTable : false,
+ showGridCoords : false,
+ showAttackCooldown : true,
showCountdown : (document.location.host.toString() !== 'tanks.woo')
},
pathing : {
- overlayAIPaths : 0,
- overlayPathmap : 0,
- traceTrajectories : 0
+ overlayAiPaths : false,
+ overlayPathmap : false,
+ traceTrajectories : false
}
};
-exports['values'] = Y(defaults).clone().end();
+exports['values'] = new Config(defaults);
Game =
exports['Game'] =
Y.subclass('Game', {
- overlayPathmap : config.pathing.overlayPathmap,
- overlayAIPaths : config.pathing.overlayAIPaths,
- timeDilation : config.game.timeDilation,
- gameoverDelay : config.game.gameoverDelay,
+ overlayPathmap : config.get('pathing.overlayPathmap'),
+ overlayAiPaths : config.get('pathing.overlayAiPaths'),
+ gameoverDelay : config.get('game.gameoverDelay'),
gameover : false,
this.animations = new Y.YArray();
this.viewport = $(viewport || GRID_ELEMENT);
- this.loop = new EventLoop(FRAME_RATE, this, this.timeDilation);
+ this.loop = new EventLoop(FRAME_RATE, this);
this.root =
this.grid =
SECONDTH = ELAPSED / 1000;
SQUARETH = REF_SIZE * SECONDTH
- if (!this.overlayAIPaths)
+ if (!this.overlayAiPaths)
this.pathmap.hidePaths();
this.active.invoke('updateCooldowns', ELAPSED, NOW);
P =
game.player = game.addUnit(new PlayerTank(1), 5,9);
- game.addUnit(new Tank(1).colors('#4596FF', '#182B53', '#F25522'), 3,9);
+ // game.addUnit(new Tank(1).colors('#4596FF', '#182B53', '#F25522'), 3,9);
E =
game.addUnit(new Tank(2), 0,1);
game.addUnit(new Tank(2), 1,0);
- game.addUnit(new Tank(2), 8,1);
+ // game.addUnit(new Tank(2), 8,1);
},
addWall : function addWall(x,y, w,h, isBoundary){
// -*- mode: JavaScript; tab-width: 4; indent-tabs-mode: nil; -*-
var Y = require('Y').Y
, math = require('ezl/math')
-, Vec = math.Vec
-, Line = math.Line
, QuadTree = require('ezl/util/tree/quadtree').QuadTree
-, Bullet = require('tanks/thing/bullet').Bullet
, astar = require('ezl/util/astar')
+, Bullet = require('tanks/thing/bullet').Bullet
+, config = require('tanks/config').values
+, Vec = math.Vec
+, Line = math.Line
,
PathMap =
exports['PathMap'] =
QuadTree.subclass('PathMap', {
+ overlayAiPaths : config.get('pathing.overlayAiPaths'),
+ overlayPathmap : config.get('pathing.overlayPathmap'),
+
gridSquareSize : REF_SIZE,
gridSquareMidPt : new Vec(REF_SIZE/2, REF_SIZE/2),
, path = Y(astar.search(grid, startN, endN))
;
- if (tanks.config.values.pathing.overlayAIPaths)
+ if (this.overlayAiPaths)
this.drawPath(id, startN, path);
return path
, Thing = require('tanks/thing/thing').Thing
, Trajectory = require('tanks/map/trajectory').Trajectory
, Explosion = require('tanks/fx/explosion').Explosion
+, config = require('tanks/config').values
, Line = shape.Line
, Circle = shape.Circle
,
render : function render(parent){
this.remove();
- if (tanks.config.values.pathing.traceTrajectories) {
+ if (config.get('pathing.traceTrajectories')) {
var t = this.trajectory;
this.tline = Line.fromPoints(t.x1,t.y1, t.x2,t.y2)
.attr('drawDefinitionPoints', true)
Thing =
exports['Thing'] =
new evt.Class('Thing', {
- showAttackCooldown : config.ui.showAttackCooldown,
+ showAttackCooldown : config.get('ui.showAttackCooldown'),
// Attributes
stats: {
+++ /dev/null
-//#ensure "jquery"
-
-
-// TODO
-// ====
-// - store at tanks.config.values, but clone at start to t.c.defaults
-// - need Config class to run triggers on changes
-// - button to clear saved config
-//
-// init
-// - For each item in tanks.config (recursive):
-// - Create a UI box based on type, with a name based on its dotted path
-// - Check cookies -- fill it with the value from cookies or default
-//
-// update
-// - For each config element:
-// - Extract value, typecast based on default's type
-// - If different from default, set cookie
-// - Update tanks.config.values
-
-var Y = require('Y').Y
-, config = require('tanks/config')
-, c = config.values
-, p = c.pathing
-;
-
-
-
-
-exports['init'] = function initConfigUi(){
- $('#config [name=pathmap]').attr('checked', p.overlayPathmap);
- $('#config [name=aipaths]').attr('checked', p.overlayAIPaths);
- $('#config [name=trajectories]').attr('checked', p.traceTrajectories);
-
- $('#config [name=gridCoords]').attr('checked', c.ui.showGridCoords);
- $('#viewport .layer.grid')[(c.ui.showGridCoords ? 'add' : 'remove')+'Class']('showGridCoords');
-};
-
-exports['update'] = function updateConfigUi(evt){
- p.overlayPathmap = $('#config [name=pathmap]').attr('checked');
- p.overlayAIPaths = $('#config [name=aipaths]').attr('checked');
- p.traceTrajectories = $('#config [name=trajectories]').attr('checked');
-
- c.ui.showGridCoords = $('#config [name=gridCoords]').attr('checked');
- $('#viewport .layer.grid')[(c.ui.showGridCoords ? 'add' : 'remove')+'Class']('showGridCoords');
-};
-
-// var templates = {
-// 'label' : { html:'<label for="{id}">{label}</label>' },
-// 'input' : { html:'<input id="{id}" type="{type}" name="{key}" value="{value}">' },
-// 'text' : { include:'input', type:'text' },
-// 'checkbox' : { include:'input', type:'checkbox', props:{ 'checked':false } },
-// 'radio' : { include:'input', type:'radio' }
-// // 'select' : '',
-// // 'textarea' : '',
-// // 'hidden' : '',
-// // 'button' : ''
-// };
-//
-// var type2el = {
-// 'Boolean'
-// 'Number' :
-// 'String' : 'text'
-// // 'Array'
-// // 'Date'
-// // 'RegExp'
-// // 'Function'
-// // 'Object'
-// };
-// exports['makeField'] = function makeField(key, value){
-//
-// };
-
-var upperPat = /^[A-Z]+$/
-, symbolPat = /^[^a-zA-Z]+$/
-;
-
-Y.YString.prototype.splitCamel =
- function splitCamel(s){
- return this.reduce(
- function(acc, ch, i){
- return acc + (
- symbolPat.test(ch) ? '' :
- (upperPat.test(ch) ? ' '+ch : ch) );
- }, '')
- .split(' ');
- };
-
--- /dev/null
+//#ensure "jquery"
+var Y = require('Y').Y
+, EventLoop = require('ezl/loop/eventloop').EventLoop
+, scaffold = require('Y/modules/y.scaffold')
+, config = require('tanks/config').values
+, configUI
+;
+
+exports['init'] =
+function initConfigUi(){
+ configUI = scaffold.create(config, jQuery('#config .box'));
+ configUI.append( jQuery('<div class="clearer"></div>') );
+
+ config.addEventListener('set:game.timeDilation', function(evt){
+ EventLoop.fn.dilation = evt.data.newval;
+ });
+};
+
+
+// exports['init'] =
+// function initConfigUi(){
+// $('#config [name=pathmap]').attr('checked', config.get('pathing.overlayPathmap'));
+// $('#config [name=aipaths]').attr('checked', config.get('pathing.overlayAiPaths'));
+// $('#config [name=trajectories]').attr('checked', config.get('pathing.traceTrajectories'));
+//
+// $('#config [name=gridCoords]').attr('checked', config.get('ui.showGridCoords'));
+// $('#viewport .layer.grid')[(config.get('ui.showGridCoords') ? 'add' : 'remove')+'Class']('showGridCoords');
+// };
+//
+// exports['update'] =
+// function updateConfigUi(evt){
+// config.set('pathing.overlayPathmap', $('#config [name=pathmap]').attr('checked'));
+// config.set('pathing.overlayAiPaths', $('#config [name=aipaths]').attr('checked'));
+// config.set('pathing.traceTrajectories', $('#config [name=trajectories]').attr('checked'));
+//
+// config.set('ui.showGridCoords', $('#config [name=gridCoords]').attr('checked'));
+// $('#viewport .layer.grid')[(config.get('ui.showGridCoords') ? 'add' : 'remove')+'Class']('showGridCoords');
+// };
+
+
+
strokeStyle : '#6E6E6E',
lineWidth : 0.5,
- createGridTable : config.ui.createGridTable,
- createGridCanvas : config.ui.createGridCanvas,
+ createGridTable : config.get('ui.createGridTable'),
+ createGridCanvas : config.get('ui.createGridCanvas'),
var Y = require('Y').Y;
-Y.extend(exports, require('tanks/ui/config'));
+Y.extend(exports, require('tanks/ui/configui'));
exports['main'] = require('tanks/ui/main');
require("Y/modules/y.kv");
var Y = require('Y').Y
-, config = require('tanks/config')
-, uiconfig = require('tanks/ui/config')
+, configui = require('tanks/ui/configui')
, Game = require('tanks/game').Game
, Tank = require('tanks/thing').Tank
, FpsSparkline = require('ezl/loop').FpsSparkline
+, config = require('tanks/config').values
, updateTimer = null
;
+function stopProp(evt){ evt.stopPropagation(); }
qkv = Y(window.location.search.slice(1)).fromKV();
$('#ai').toggle();
$('#ai textarea')[0].focus();
}
- if (qkv.debug) $('#debug').toggle();
+ if (qkv.debug) $('#info').toggle();
$('#ai .ready').bind('click', function(evt){
try {
$('#ai').hide();
startGame();
} catch(e) {
- alert('AI Error! '+e);
+ alert('AI Error!\n'+e);
}
});
- // Show debug
- $(document).bind('keydown', 'ctrl+c', function(evt){ $('#debug').toggle(); });
+ // Show debug menus
+ $(document).bind('keydown', 'ctrl+d', function(evt){ $('.debug').toggle(); });
+ $(document).bind('keydown', 'ctrl+i', function(evt){ $('#info').toggle(); });
+ $(document).bind('keydown', 'ctrl+c', function(evt){ $('#config').toggle(); });
// Don't fire on clicks in the debug menu
- $('#debug').bind('mousedown', Y.op.K(false));
+ $('.debug').bind('mousedown', stopProp);
+ $('.debug').bind('click', stopProp);
- // Update config when changed
- $('#debug input').bind('change', uiconfig.update);
+ // Build and bind config
+ configui.init();
// Create #pause box
if (!qkv.ai) $('#welcome').show();
LBT.loop.spark = new FpsSparkline(LBT.loop, '.fps-sparkline', 0,0);
- uiconfig.init();
LBT.root.draw();
// Start button (click or return key)
$('#welcome').hide();
- if ( config.values.ui.showCountdown )
+ if ( config.get('ui.showCountdown') )
countdown(3, readyToStart);
else
readyToStart();
-html { width:100%; height:100%; top:0; left:0; margin:0; padding:0; background-color:#3F3F3F; }
-body { position:absolute; width:100%; top:0; left:0; margin:0; padding:0;
- font-family:Geogrotesque,Helvetica; font-size:12pt; color:#fff; }
+html, body { width:100%; height:100%; top:0; left:0; margin:0; padding:0; background-color:#3F3F3F; }
+body { position:absolute; font-family:Geogrotesque,Helvetica; font-size:12pt; color:#fff; }
h1, h2, h3, h4, h5 { margin:0.75em 0; font-weight:normal; }
ul, ol, li { list-style: none ! important; margin:0; padding:0; }
.clearer { clear:both !important; float:none !important;
margin:0 !important; padding:0 !important; }
.rounded { border-radius:1em; -moz-border-radius:1em; -webkit-border-radius:1em; }
-.box {
- padding:0.5em; background-color:rgba(0,0,0, 0.1); color:#787878;
+.hud {
+ 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; }
#welcome legend { padding:0.5em; text-transform:uppercase; }
*/
+/*
#debug { position:relative; top:1em; right:1em; z-index:500; }
#debug .inner { position:absolute; top:0; right:0; padding:1em; }
#debug .inner > * { float:right; margin-right:1em; }
+*/
-#config { position:relative; width:250px; }
- #config > div { position:relative; line-height:1.5em; }
- #config label { position:relative; width:69%; display:inline-block; }
- #config input { position:absolute; width:30%; top:0; right:0; text-align:center;
- border:0; background-color:rgba(0,0,0, 0.1) ! important; color:#5c5c5c; }
- #config input[type=checkbox] { top:0.33em; }
+.debug { z-index:500; }
+ .debug .inner { top:0; right:0; padding:1em; }
-#info { position:relative; width:250px; }
+#info { position:absolute; top:1em; right:1em; }
+ #info .box { width:250px; }
#info #state { font-weight:bold; }
#info label { display:block; float:left; width:5em; margin-right:0.5em; color:#787878; }
#info input { border:0; background-color:transparent; min-width:5em; width:5em; color:#5c5c5c; }
#info .sep { opacity:0.1; background-color:#999; margin:5px 0; height:1px; }
#info .fps-sparkline { width:100%; height:1.5em; margin-top:0.5em; }
+#config { position:absolute; bottom:1em; left:1em; }
+ #config .box { }
+ #config .group { width:250px; float:left; margin-right:1em; }
+ #config .group:last-of-type { margin-right:0; }
+ #config h3 { font-weight:bold; margin:0; position:absolute; bottom:1em; left:1em; }
+ #config fieldset { border:1px solid #999; padding:0.5em; }
+ #config legend { padding:0.5em; text-transform:uppercase; color:#787878; }
+ #config .field { position:relative; line-height:1.5em; }
+ #config label { position:relative; width:69%; display:inline-block; text-transform:lowercase; }
+ #config input { position:absolute; width:30%; top:0; right:0; text-align:center;
+ border:0; background-color:rgba(0,0,0, 0.1) ! important; color:#5c5c5c; }
+ #config input[type=checkbox] { top:0.33em; }
+
<div id="ai" style="display:none" class="bigblue">
- <div class="box">
+ <div class="box hud">
<h2>Add Tank AI</h2>
<textarea id="customtank"></textarea>
<div class="ready pinkbutton rounded">Ready</div>
</div>
</div>
-<div id="debug" style="display:none"><div class="inner box">
-
- <div id="config">
- <h3>config</h3>
- <!--<div><label for="bullets">bullets</label> <input id="bullets" name="bullets" value="10" type="text"></div>-->
- <div><label for="pathmap">overlay pathmap</label> <input id="pathmap" name="pathmap" value="1" type="checkbox"></div>
- <div><label for="aipaths">overlay ai paths</label> <input id="aipaths" name="aipaths" value="1" type="checkbox"></div>
- <div><label for="trajectories">trace trajectories</label> <input id="trajectories" name="trajectories" value="1" type="checkbox"></div>
- <div><label for="gridCoords">show coords on hover</label> <input id="gridCoords" name="gridCoords" value="1" type="checkbox"></div>
- </div>
-
- <ul id="info">
+<div id="info" class="debug" style="display:none"><div class="inner hud">
+ <ul class="box">
<li id="state"></li>
<li><div class="fps-sparkline"></div></li>
<li><label for="info_fps" >fps</label> <input id="info_fps" name="fps" value="" type="text"></li>
<li><label for="info_bullets">bullets</label> <input id="info_bullets" name="bullets" value="" type="text"></li>
<li><label for="info_anims">animations</label> <input id="info_anims" name="anims" value="" type="text"></li>
</ul>
-
<div class="clearer"></div>
</div></div>
+
+<div id="config" class="debug" style="display:none"><div class="inner hud">
+ <h3>config</h3>
+ <div class="box"></div>
+ <!--
+ <div><label for="pathmap">overlay pathmap</label> <input id="pathmap" name="pathmap" value="1" type="checkbox"></div>
+ <div><label for="aipaths">overlay ai paths</label> <input id="aipaths" name="aipaths" value="1" type="checkbox"></div>
+ <div><label for="trajectories">trace trajectories</label> <input id="trajectories" name="trajectories" value="1" type="checkbox"></div>
+ <div><label for="gridCoords">show coords on hover</label> <input id="gridCoords" name="gridCoords" value="1" type="checkbox"></div>-->
+</div></div>
+
<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/mustache.js" type="text/javascript"></script>
+<script src="build/jquery.mustache.js" type="text/javascript"></script>
<script src="build/ezl/util/binaryheap.js" type="text/javascript"></script>
<script src="build/ezl/util/astar.js" type="text/javascript"></script>
-<script src="build/tanks/config.js" type="text/javascript"></script>
+<script src="build/Y/modules/y.scaffold.js" type="text/javascript"></script>
<script src="build/Y/modules/y.kv.js" type="text/javascript"></script>
<script src="build/ezl/util/tree/quadtree.js" type="text/javascript"></script>
-<script src="build/tanks/ui/config.js" type="text/javascript"></script>
+<script src="build/y/modules/y.config.js" type="text/javascript"></script>
+<script src="build/tanks/config.js" type="text/javascript"></script>
+<script src="build/tanks/ui/configui.js" type="text/javascript"></script>
<script src="build/tanks/thing/thing.js" type="text/javascript"></script>
<script src="build/tanks/map/trajectory.js" type="text/javascript"></script>
<script src="build/tanks/ui/grid.js" type="text/javascript"></script>
-img/favicon-pink.ico
\ No newline at end of file
+img/favicon-pink2.ico
\ No newline at end of file
--- /dev/null
+<div id="panes"></div>
<div id="welcome" class="bigblue">
- <div class="box">
+ <div class="box hud">
<h1>The Littlest Battletank</h1>
<h2>How To Play</h2>