<h1>The Littlest Battletank</h1>
+<div id="controls">
+ <label for="nbullets">Num Bullets</label> <input id="nbullets" name="nbullets" value="5" type="text">
+</div>
+
<ul id="info" class="rounded">
<li id="state"></li>
<li><div class="fps-sparkline"></div></li>
this.units.push(unit);
}
+
return unit;
},
return agent;
},
- killAgent : function killAgent(agent){
- delete this.byId[agent.id];
- if (agent instanceof Ability)
- this.abilities.remove(agent);
- else
- this.units.remove(agent);
-
- this.pathmap.removeBlocker(agent);
- return agent;
+ killUnit : function killUnit(unit){
+ delete this.byId[unit.id];
+ this.units.remove(unit);
+ this.pathmap.removeBlocker(unit);
+ return unit;
},
moveAgentTo : function moveAgentTo(agent, x,y){
function setupUI(){
spark = LBT.loop.spark = new FpsSparkline(LBT.loop, '.fps-sparkline', 0,0);
- // Draw grid, initial units
LBT.root.draw();
- setInterval(updateInfo, 1000);
- updateInfo();
-
// Start button (click or return key)
$(document).bind('keydown', 'return', toggleGame);
$(document).bind('keydown', 'ctrl+o', toggleOverlay);
+ var bullets = new Y.YArray();
+
+ $('#nbullets').bind('blur', function(){
+ var n = parseInt($('#nbullets').val());
+
+ if ( isNaN(n) || n === bullets.size() ) return;
+
+ while (n < bullets.size()) {
+ var i = rand(0, bullets.size()-1);
+ bullets.remove( bullets.attr(i).remove() );
+ }
+
+ while (n > bullets.size())
+ bullets.push(spawnBullet());
+ });
+
+ $('#nbullets').blur();
+
+ // Draw grid, initial units
+ LBT.root.draw();
+
+ setInterval(updateInfo, 1000);
+ updateInfo();
+
// Fix grid-size on resize
// $(window).bind('resize', resizeGame);
}
+
+function rand(a,b){ return a + Math.random()*(b-a); }
+function randOpenLoc(){
+ do {
+ var x = rand(0,COLUMNS*REF_SIZE)
+ , y = rand(0,ROWS*REF_SIZE);
+ } while ( LBT.pathmap.get(x,y, x+6,y+6).size() );
+ return new math.Vec(x,y);
+}
+
+function spawnBullet(x,y, atX,atY){
+ if (x === undefined && y === undefined) {
+ var loc = randOpenLoc();
+ x = loc.x; y = loc.y;
+ }
+ if (atX === undefined && atY === undefined) do {
+ atX = rand(0,COLUMNS*REF_SIZE);
+ atY = rand(0,ROWS*REF_SIZE);
+ } while ( atX === x && atY === y);
+
+ T.setLocation(x,y);
+ var p = T.fireProjectile(atX,atY);
+ // console.log('spawnBullet(',x,y, atX,atY,') -->', p);
+ return p;
+}
+
+
// Update performance info periodically
function updateInfo(){
var loop = LBT.loop
T = new Tank(0);
LBT.addUnit(T, 1,2);
- T.fireProjectile(5*sq,5*sq);
- T.fireProjectile(1*sq,3*sq);
- T.fireProjectile(6*sq,1.5*sq);
- T.fireProjectile(0.5*sq,0.5*sq);
-
- T.setLocation(3*sq,3*sq);
- T.fireProjectile(1*sq,1*sq);
-
- T.shape.hide();
LBT.pathmap.removeBlocker(T);
+ T.shape.hide();
+
+ // T.fireProjectile(5*sq,5*sq);
+ // T.fireProjectile(1*sq,3*sq);
+ // T.fireProjectile(6*sq,1.5*sq);
+ // T.fireProjectile(0.5*sq,0.5*sq);
+ //
+ // T.setLocation(3*sq,3*sq);
+ // T.fireProjectile(1*sq,1*sq);
P = new Player(LBT, T);
setupUI();
+
+ // T.setLocation(1*sq,2*sq);
}
this.trajectory = new math.Line(loc.x,loc.y, x,y, this.stats.move*REF_SIZE/1000);
this.setLocation(loc.x,loc.y);
},
- blocking : false,
+ blocking : true,
elapsed : 0,
- width : 5,
- height : 5,
+ width : 6,
+ height : 6,
stats : {
move : 2.0, // move speed (squares/sec)
_depth : 0,
move : function move(){
- var trj = this.trajectory
+ var trj = this.trajectory, p2 = trj.p2, goal = p2, _ng
, to = trj.parametric(this.elapsed)
, test = this.game.pathmap.attemptMove(this, trj, to)
;
// Literal corner case :P
if (test.corner) {
- var to = this.loc, ng = trj.p1;
+ var to = this.loc, ng = _ng = trj.p1;
// this.trajectory = new math.Line(loc.x,loc.y, p1.x,p1.y, trj.tdist);
// Normal reflection against one line
} else {
to = test.to;
- var wall = test.wall, p2 = trj.p2
+ var wall = test.wall
, bb = this.boundingBox
, goal = wall.isWithin(p2,bb) ? trj.near(p2.x+2*REF_SIZE, p2.y+2*REF_SIZE) : p2
- , _ng, ng = _ng = math.reflect(goal, wall)
+ , ng = _ng = math.reflect(goal, wall)
, x1 = bb.x1, y1 = bb.y1
, tx = to.x, ty = to.y
, cmp = Y.op.cmp
this.trajectory = new math.Line(to.x,to.y, ng.x,ng.y, trj.tdist);
if (this._depth) {
- console.log('['+this._depth+' '+TICKS+'] '+this+' reflected by', test.what);
+ console.log('['+this._depth+' '+TICKS+'] '+this+' reflected by', (test.corner ? 'corner' : test.what));
console.log(' to='+to+', goal='+goal+(p2.equals(goal) ? '' : ' <~ '+p2));
console.log(' --> new goal='+ng+(ng.equals(_ng) ? '' : ' <~ '+_ng));
console.log(' --> trajectory='+this.trajectory);
}
this.render(this.game.level).draw();
- this.elapsed = ELAPSED;
+ this.elapsed = 0; //ELAPSED;
if (this._depth++ < 5)
- return this.move();
+ return this; // this.move();
console.log('Reflection limit reached!');
this._depth = 0;
Tank = new Y.Class('Tank', Thing, {
projectile : Bullet,
+ blocking: true,
// Bounding box size
width : REF_SIZE*0.7,
loc : null,
boundingBox : null,
+ blocking : true,
// Rotation (rads)
rotation : 0,
destroy : function destroy(){
- if (this.dead) return;
+ if (this.dead) return this;
this.dead = true;
this.fire('destroy', this);
+ return this;
+ },
+
+ remove : function remove(){
+ if (this.shape) this.shape.remove();
+ if (this.game) this.game.killUnit(this);
+ return this;
},
setLocation : function setLocation(x,y){
},
act : function act(){
- var t = this.tank;
- if (t.dead) return this;
-
- var r = TWO_PI * (TICKS % 30)/30;
- // console.log('tank.shape.rotate(', r, ')');
- // t.shape.rotate(r);
- },
-
- act_ : function act_(){
if (this.tank.dead) return this;
var active = this.activeKeys;