From 0f9eaee0e7a636f5352ee516b71eb0f342946512 Mon Sep 17 00:00:00 2001 From: dsc Date: Sun, 21 Nov 2010 23:02:14 -0800 Subject: [PATCH] UI improvements. --- ai.md | 31 +++++++++++++++++++++++++++++++ css/lttl.css | 22 ++++++++++++---------- src/tanks/main.js | 7 +------ src/tanks/thing/tank.js | 36 ++++++++++++++++++++---------------- 4 files changed, 64 insertions(+), 32 deletions(-) create mode 100644 ai.md diff --git a/ai.md b/ai.md new file mode 100644 index 0000000..0dab8e6 --- /dev/null +++ b/ai.md @@ -0,0 +1,31 @@ +# Tank AI Language + +## Types + +- `Loc`: Object with properties `x` and `y`, representing a position on the map. +- `Rect`: Object with properties `x1`, `y1`, `x2`, `y2`, representing the top-left and bottom-right locations of a region on the map. +- `Agent`: An object that reprensents both your tank and all agents discovered with various lookup methods. See below for properties. + +## Agent Properties + +- `stats`: Agent's stats. + - `hp`: Agent's health. + - `move`: Agent's move speed in squares/sec. + - `speed`: Agent's attack cooldown wait-time in sec. + - `shots`: Maximum projectiles the agent can have in the air at once. +- `loc`: Loc of the top-left point of the agent on the map. +- `boundingBox`: Rect of the agent's absolute map position. +- `midpoint`: Loc of the agent's midpoint position on the map. +- `nShots`: Number of shots the agent currently has in the air. + +## Functions + +- `shoot(x,y)`: Fires a shot at (x,y) if possible. +- `move(x,y)`: Moves directly toward (x,y) if possible. +- `ableToShoot()` -> `Boolean`: Whether your tank is able to fire at the moment. +- `find(x1,y1,x2,y2)` -> `Agent[]` +- `findNearLike(ticks, filter)` -> `Agent[]`: Returns a list of agents within `ticks` movement distance away that match the filter. +- `findClosest(agents)` -> `Agent`: Returns the closest agent to this tank in the supplied list, or null if none are supplied. +- `calculatePath(point)` +- `calculatePath(x,y)`: Calculates a path from your current location to (x,y), taking into account walls, and then queues it for future moves. + diff --git a/css/lttl.css b/css/lttl.css index 4960efe..b293744 100644 --- a/css/lttl.css +++ b/css/lttl.css @@ -23,11 +23,6 @@ table.grid td { /* outline:1px solid rgba(255,255,255,0.1); */ margin:0; padding:0; white-space:nowrap; overflow:hidden; } .gridShowCoords table.grid td:hover { color:rgba(255,255,255,0.1); } -#viewport { position:relative; width:500px; height:500px; margin:1em auto; cursor:crosshair; } - - -#overlay { position:fixed; top:0; left:0; width:100%; height:100%; background-color:#000; opacity:0.5; z-index:100; } - .bigblue { position:fixed; width:100%; top:50%; margin-top:-200px; z-index:101; } .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; } @@ -35,14 +30,21 @@ table.grid td { /* outline:1px solid rgba(255,255,255,0.1); */ .bigblue h2 { font-size:1.1em; letter-spacing:2px; } .bigblue .start { margin:1.5em 0 0.5em; text-align:center; border:0; } - #notes { /* position:fixed; top:4em; right:1em; color:#BFBFBF;*/ } - #notes ul, #notes ol, #notes li { list-style:circle ! important; } - #notes li { margin-left:1em; } - .pinkbutton { width:50%; margin:0 auto; cursor:pointer; - font-size:1.5em; padding:0.5em; background-color:#E73075; color:#fff; text-align:center; text-transform:uppercase; } + 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; } + +#viewport { position:relative; width:500px; height:500px; margin:1em auto; cursor:crosshair; } + +#overlay { position:fixed; top:0; left:0; width:100%; height:100%; background-color:#000; opacity:0.5; z-index:100; } #welcome { cursor:pointer; } +#notes { /* position:fixed; top:4em; right:1em; color:#BFBFBF;*/ } + #notes ul, #notes ol, #notes li { list-style:circle ! important; } + #notes li { margin-left:1em; } + /* #welcome fieldset { border:1px solid #182B53; padding:1em; } diff --git a/src/tanks/main.js b/src/tanks/main.js index b76dbaa..250f47c 100644 --- a/src/tanks/main.js +++ b/src/tanks/main.js @@ -213,18 +213,13 @@ function countdownToStart(n, fn){ , size = bh*sizeRatio , el = $('
') + .addClass('countdown') .width(bh*0.75).height(bh*0.75) .text( values.pop() ) .css({ - 'position' : 'fixed', 'top' : ((bh - size)/2)+'px', 'left' : (bw/2 - bh*0.375)+'px', - 'overflow' : 'hidden', - 'z-index' : 1000, - - 'text-align' : 'center', 'font-size' : size+'px', - 'color' : '#000000', 'background-color' : colors.pop(), }) ; diff --git a/src/tanks/thing/tank.js b/src/tanks/thing/tank.js index 5b8d4b5..28034db 100644 --- a/src/tanks/thing/tank.js +++ b/src/tanks/thing/tank.js @@ -40,7 +40,7 @@ Tank = Thing.subclass('Tank', { }); }, - cannonReady : function cannonReady(){ + ableToShoot : function ableToShoot(){ return this.nShots < this.stats.shots && this.cooldowns.attack.ready; }, @@ -78,10 +78,10 @@ Tank = Thing.subclass('Tank', { // Are we ready to fire? - if ( this.cannonReady() ) { + if ( this.ableToShoot() ) { // Try to shoot down nearby bullets - var bs = this.willCollide( this.nearLike(16, Y.is(Bullet)) ); + var bs = this.willCollide( this.findNearLike(16, Y.is(Bullet)) ); if ( bs.size() ) { var b = this.findClosest(bs); @@ -90,7 +90,8 @@ Tank = Thing.subclass('Tank', { return this; } - var bs = this.willCollide( this.nearLike(50, Y.is(Bullet)), 10 ); + // Dodge incoming bullet + var bs = this.willCollide( this.findNearLike(50, Y.is(Bullet)), 10 ); if ( bs.size() ) { var b = this.findClosest(bs), bs = [b] , mid = this.midpoint @@ -109,7 +110,7 @@ Tank = Thing.subclass('Tank', { } // Try to blow up nearby tanks - var t = this.nearLike(66, 'Y.is(Tank, _) && _.align !== this.align').shift(); + var t = this.findNearLike(66, 'Y.is(Tank, _) && _.align !== this.align').shift(); if (t) { // console.log('I gotcha!', t); this.shoot(t.loc.x, t.loc.y); @@ -125,8 +126,10 @@ Tank = Thing.subclass('Tank', { }, continueMove : function continueMove(){ - if ( !this.currentMove || this.currentMoveLimit <= NOW ) - this.recalculatePath(); + if ( !this.currentMove || this.currentMoveLimit <= NOW ){ + var t = this.findNearLike(10000, 'Y.is(Tank, _) && _.align !== this.align').shift(); + this.calculatePath(t.midpoint); + } var to = this.currentMove; if (!to) return; @@ -139,21 +142,18 @@ Tank = Thing.subclass('Tank', { } }, - recalculatePath : function recalculatePath(){ - var t = this.nearLike(10000, 'Y.is(Tank, _) && _.align !== this.align').shift() - , pm = this.game.pathmap - ; + calculatePath : function calculatePath(end){ + if (!end) return; + + var pm = this.game.pathmap; // this.forceCurrentMove = Y.op.K(true); // this.currentMoveLimit = NOW + 750; this.forceCurrentMove = false; this.currentMoveLimit = -1; - if (!t) return; - // console.log(this, 'moving toward', t); - var end = t.midpoint - , bb = this.boundingBox + var bb = this.boundingBox , mid = this.midpoint , start = mid @@ -184,7 +184,11 @@ Tank = Thing.subclass('Tank', { // console.log('start:', start, 'straddles:', straddles.map(pm.square2Vec.bind(pm)), 'end:', end, 'next:', to); }, - nearLike : function nearLike(ticks, fn){ + find : function find(x1,y1, x2,y2){ + return this.pathmap.get(x1,y1, x2,y2); + }, + + findNearLike : function findNearLike(ticks, fn){ fn = fn.toFunction(); var bMovePerTick = MS_PER_FRAME * Bullet.prototype.stats.move*REF_SIZE/1000 , within = bMovePerTick*ticks -- 1.7.0.4