From: dsc Date: Tue, 11 Jan 2011 03:25:26 +0000 (-0800) Subject: Checkpoint in pathing refactor. X-Git-Url: http://git.less.ly:3516/?a=commitdiff_plain;h=ad29ced3f39d153d165dde40b3c94f6bed0042b6;p=tanks.git Checkpoint in pathing refactor. --- diff --git a/data/config.yaml b/data/config.yaml index a52c410..9c01445 100644 --- a/data/config.yaml +++ b/data/config.yaml @@ -1,20 +1,21 @@ game: - timeDilation : 1.0 - gameoverDelay : 1000 + timeDilation : 1.0 + # zoom : 1.0 + gameoverDelay : 1000 debug: - showFpsGraph : false + showFpsGraph : false # createGridTable : false # showGridCoords : false map: - refSize : &ref_size 50 - minSplitSize : 12.5 + refSize : &ref_size 50 + minSplitSize : 12.5 pathing: - pathSquare : *ref_size - overlayAiPaths : false - overlayPathmap : false - traceTrajectories : false + pathSquare : *ref_size + overlayAiPaths : false + overlayPathmap : false + traceTrajectories : false ui: - createGridCanvas : true - overlayOnPause : true - showAttackCooldown : false - showCountdown : true + createGridCanvas : true + overlayOnPause : true + showAttackCooldown : false + showCountdown : true diff --git a/data/types/levels.yaml b/data/types/levels.yaml index 3a6b7da..35f3bc3 100644 --- a/data/types/levels.yaml +++ b/data/types/levels.yaml @@ -57,6 +57,12 @@ types: - type: player align: 1 loc: [325,475] + - type: green + align: 2 + loc: [75,25] + - type: blue + align: 1 + loc: [75,475] - type: blue align: 1 loc: [175,475] @@ -65,9 +71,6 @@ types: loc: [25,375] - type: green align: 2 - loc: [75,25] - - type: green - align: 2 loc: [425,75] items: - type: nitro diff --git a/pavement.py b/pavement.py index d0ec9ed..d767048 100755 --- a/pavement.py +++ b/pavement.py @@ -95,7 +95,7 @@ def build_data(): def build_scripts(): "Builds js modules." info('Building scripts...') - sh('rm build/tanks/config.js') + sh('rm -f build/tanks/config.js') tags = sourceTags( commonjs(script_tags=True, capture=True) ) with path('build/deps.html').open('w') as f: f.write(tags) diff --git a/src/ezl/layer/layer.cjs b/src/ezl/layer/layer.cjs index 3cae1c7..55dca75 100644 --- a/src/ezl/layer/layer.cjs +++ b/src/ezl/layer/layer.cjs @@ -29,8 +29,8 @@ Y.subclass('Layer', { animQueue : null, _erased : null, - layerWidth : 0, canvasWidth : 0, - layerHeight : 0, canvasHeight : 0, + layerWidth : 0, canvasWidth : 0, realWidth : 0, + layerHeight : 0, canvasHeight : 0, realHeight : 0, x: 0, y: 0, loc : null, // Position relative to parent @@ -175,16 +175,19 @@ Y.subclass('Layer', { if (w === undefined && h === undefined) return new Vec(this.layerWidth,this.layerHeight); - if (w === null) w = this.layerWidth; - if (h === null) h = this.layerHeight; + if (w === null) w = this.realWidth; + if (h === null) h = this.realHeight; - this.layerWidth = w; - this.layerHeight = h; + this.realWidth = w; + this.realHeight = h; + + // HTMLElement.{width,height} is a long + this.layerWidth = Math.round(w); + this.layerHeight = Math.round(h); var bb = this.bbox.resize(w,h) , nb = this.negBleed, pb = this.posBleed - // HTMLCanvas.{width,height} is a long , cw = this.canvasWidth = Math.ceil(w + nb.x + pb.x) , ch = this.canvasHeight = Math.ceil(h + nb.y + pb.y) ; diff --git a/src/tanks/game.cjs b/src/tanks/game.cjs index 8dfac07..3a50a85 100644 --- a/src/tanks/game.cjs +++ b/src/tanks/game.cjs @@ -7,12 +7,11 @@ var Y = require('Y').Y , Circle = require('ezl/shape').Circle , config = require('tanks/config').config -, map = require('tanks/map') , thing = require('tanks/thing') +, Level = require('tanks/map/level').Level , Grid = require('tanks/ui/grid').Grid , PathMapUI = require('tanks/ui/pathmapui').PathMapUI -, Level = map.Level , Thing = thing.Thing , Tank = thing.Tank , Bullet = thing.Bullet @@ -51,9 +50,9 @@ Y.subclass('Game', { Level.create('test', this, CAPACITY, REF_SIZE) .appendTo(this.root); - this.pathmap = this.level.pathmap; - this.pathmap.ui = new PathMapUI(this, this.pathmap); - this.root.append(this.pathmap.ui); + this.map = this.level.map; + this.map.ui = new PathMapUI(this, this.map); + this.root.append(this.map.ui); // automatically keep track of units Thing.addEventListener('created', this.addThing); @@ -184,7 +183,7 @@ Y.subclass('Game', { unit.render( this.level ); } - this.pathmap.addBlocker(unit); + this.map.addBlocker(unit); return unit; }, @@ -195,7 +194,7 @@ Y.subclass('Game', { delete this.byId[unit.__id__]; this.active.remove(unit); - this.pathmap.removeBlocker(unit); + this.map.removeBlocker(unit); if (unit instanceof Bullet) this.bullets.remove(unit); @@ -206,10 +205,10 @@ Y.subclass('Game', { }, moveThingTo : function moveThingTo(agent, x,y){ - this.pathmap.removeBlocker(agent); + this.map.removeBlocker(agent); if (agent.dead) return agent; agent.position(x,y); - this.pathmap.addBlocker(agent); + this.map.addBlocker(agent); return agent; }, diff --git a/src/tanks/globals.js b/src/tanks/globals.js index b03d4be..24b2520 100644 --- a/src/tanks/globals.js +++ b/src/tanks/globals.js @@ -19,20 +19,6 @@ var undefined , ELAPSED = MS_PER_FRAME // Time (ms) since previous tick , TICKS = 0 // Ticks since start of game -/// Pathing Constants (from tanks/map/map) /// - -/** Does not obstruct other objects. */ -, PASSABLE = 0 - -/** Does not obstruct other objects, but still collides with them. */ -, ZONE = 1 - -/** Obstructs other blockers with its BoundingBox. */ -, BLOCKING = 2 - -/** Potentially obstructs other objects, but requires a special test once a BoundingBox collision has been detected. */ -, IRREGULAR = 3 - /// Common Components of Computation /// diff --git a/src/tanks/map/index.cjs b/src/tanks/map/index.cjs index f357fa0..ba5cba8 100644 --- a/src/tanks/map/index.cjs +++ b/src/tanks/map/index.cjs @@ -2,7 +2,7 @@ require('Y').Y .extend(exports, { 'pathing' : require('tanks/map/pathing'), - 'Map' : require('tanks/map/map').Map, + 'Map' : require('tanks/map/pathing').Map, 'Level' : require('tanks/map/level').Level, 'Wall' : require('tanks/map/wall').Wall, 'Drywall' : require('tanks/map/drywall').Drywall, diff --git a/src/tanks/map/level.cjs b/src/tanks/map/level.cjs index c31d975..393b6eb 100644 --- a/src/tanks/map/level.cjs +++ b/src/tanks/map/level.cjs @@ -5,7 +5,7 @@ var Y = require('Y').Y , Rect = require('ezl/shape').Rect , Buff = require('tanks/effects/buff').Buff -, PathMap = require('tanks/map/pathing/pathmap').PathMap +, Map = require('tanks/map/pathing/map').Map , Thing = require('tanks/thing/thing').Thing , Tank = require('tanks/thing/tank').Tank , Item = require('tanks/thing/item').Item @@ -36,7 +36,7 @@ new evt.Class('Level', { init : function init(game, capacity, buffer_size){ this.game = game; - this.pathmap = new PathMap(0,0, this.width, this.height, capacity, buffer_size); + this.map = new Map(0,0, this.width, this.height, capacity, buffer_size); var shape = this.shape = new Rect(this.width,this.height).fill('transparent'); shape.layer.attr('class', this._cssClasses); diff --git a/src/tanks/map/pathing/index.cjs b/src/tanks/map/pathing/index.cjs index 633d120..c9b122e 100644 --- a/src/tanks/map/pathing/index.cjs +++ b/src/tanks/map/pathing/index.cjs @@ -1,6 +1,13 @@ +// Load in order to ensure class is assembled the right way +require('tanks/map/pathing/map'); +require('tanks/map/pathing/map-blockers'); +require('tanks/map/pathing/map-pathing'); +require('tanks/map/pathing/map-searching'); +// + require('Y').Y .extend(exports, { - 'PathMap' : require('tanks/map/pathing/pathmap').PathMap, + 'Map' : require('tanks/map/pathing/map').Map, 'Traversal' : require('tanks/map/pathing/traversal').Traversal, 'Trajectory' : require('tanks/map/pathing/trajectory').Trajectory }); diff --git a/src/tanks/map/map.cjs b/src/tanks/map/pathing/map-blockers.cjs similarity index 79% rename from src/tanks/map/map.cjs rename to src/tanks/map/pathing/map-blockers.cjs index 92461b4..82bede1 100644 --- a/src/tanks/map/map.cjs +++ b/src/tanks/map/pathing/map-blockers.cjs @@ -1,27 +1,13 @@ // -*- mode: JavaScript; tab-width: 4; indent-tabs-mode: nil; -*- -var Y = require('Y').Y -, QuadTree = require('ezl/util/tree/quadtree').QuadTree - +var Y = require('Y').Y , constants = require('tanks/constants') , BoundsType = constants.BoundsType , DensityType = constants.DensityType -, +, Map = require('tanks/map/pathing/map').Map +; -Map = -exports['Map'] = -QuadTree.subclass('Map', { - allWalls : null, // All walls in this map - innerWalls : null, // Non-boundary walls - denseWalls : null, // Non-boundary non-Fences - - - init : function initMap(x1,y1, x2,y2, capacity){ - this.allWalls = Y([]); - this.innerWalls = Y([]); - this.denseWalls = Y([]); - QuadTree.init.call(this, x1,y1, x2,y2, capacity); - }, +Y.core.extend(Map.fn, { addBlocker : function addBlocker(obj){ this.removeBlocker(obj); diff --git a/src/tanks/map/pathing/pathmap.cjs b/src/tanks/map/pathing/map-pathing.cjs similarity index 87% rename from src/tanks/map/pathing/pathmap.cjs rename to src/tanks/map/pathing/map-pathing.cjs index c81b110..36cdc97 100644 --- a/src/tanks/map/pathing/pathmap.cjs +++ b/src/tanks/map/pathing/map-pathing.cjs @@ -1,5 +1,6 @@ // -*- mode: JavaScript; tab-width: 4; indent-tabs-mode: nil; -*- var Y = require('Y').Y +, op = require('Y/op') , vec = require('ezl/math/vec') , Vec = vec.Vec @@ -11,11 +12,19 @@ var Y = require('Y').Y , constants = require('tanks/constants') , BoundsType = constants.BoundsType , DensityType = constants.DensityType -, Map = require('tanks/map/map').Map - +, Map = require('tanks/map/pathing/map').Map +, Trajectory = require('tanks/map/pathing/trajectory').Trajectory +, Traversal = require('tanks/map/pathing/traversal').Traversal +, Thing = require('tanks/thing/thing').Thing +, Bullet = require('tanks/thing/bullet').Bullet +, _X = 0, _Y = 1 +, BULLET_MOVE_PER_FRAME = MS_PER_FRAME * Bullet.fn.stats.move*REF_SIZE/1000 , SQRT_TWO = Math.sqrt(2) -, + +, kTrue = op.K(true) +, isBullet = Y.is(Bullet) +; /** * A QuadTree which aids in pathing for AI. @@ -24,47 +33,7 @@ var Y = require('Y').Y * - Pathing methods will account for the unit's size when calculating paths, * intersections, blocking, and similar tasks. */ -PathMap = -exports['PathMap'] = -Map.subclass('PathMap', { - // Config - pathSquare : null, - pathSquareMid : null, - - // State - _squares : null, // Cache of Square objects - _pathId : -1, // Instance of A* being run, to track when to reset Square instances - - - - init : function init(x1,y1, x2,y2, capacity, buffer_size) { - this.buffer_size = buffer_size; - x1 -= buffer_size; y1 -= buffer_size; - x2 += buffer_size; y2 += buffer_size; - Map.init.call(this, x1,y1, x2,y2, capacity); - this._squares = {}; - }, - - /** - * Takes normal (not pathSquare-relative) coordinates. - */ - _getSquare : function getSquare(x,y){ - if (x instanceof Array) { y=x[1]; x=x[0]; } - var cache = this._squares - , SIZE = this.pathSquare ; - - x = Math.floor(x / SIZE) * SIZE; - y = Math.floor(y / SIZE) * SIZE; - var key = x+'_'+y - , sq = cache[key] ; - - if (sq) - sq.reset(); - else - sq = cache[key] = new Square(this, x,y); - - return sq; - }, +Y.core.extend(Map.fn, { /** * Finds the shortest path to a destination for the given agent. @@ -168,6 +137,28 @@ Map.subclass('PathMap', { return Y([]); }, + /** + * @private + * Takes normal (not pathSquare-relative) coordinates. + */ + _getSquare : function getSquare(x,y){ + if (x instanceof Array) { y=x[1]; x=x[0]; } + var cache = this._squares + , SIZE = this.pathSquare ; + + x = Math.floor(x / SIZE) * SIZE; + y = Math.floor(y / SIZE) * SIZE; + var key = x+'_'+y + , sq = cache[key] ; + + if (sq) + sq.reset(); + else + sq = cache[key] = new Square(this, x,y); + + return sq; + }, + vec2Square : function vec2Square(x,y){ if (x instanceof Array){ y = x.y; x = x.x; } var floor = Math.floor, SIZE = this.pathSquare; @@ -203,19 +194,19 @@ Y.subclass('Square', new Vec(0,0), { * @param x Left coord of square. * @param y Top coord of square. */ - init : function initSquare(pathmap, x,y){ + init : function initSquare(map, x,y){ Vec.init.call(this, x,y); - this.pathmap = pathmap; + this.map = map; this.reset(); }, reset : function reset(){ - var pathId = this.pathmap._pathId; + var pathId = this.map._pathId; if (this.pathId === pathId) return this; this.pathId = pathId; - this.agent = this.pathmap._agent; + this.agent = this.map._agent; this.blocked = this._blocked(); this.dist = 0; @@ -232,7 +223,7 @@ Y.subclass('Square', new Vec(0,0), { * @private Calculates this.blocked value. Should only be called by reset() to cache the result. */ _blocked : function blocked(){ - var pm = this.pathmap + var pm = this.map // , bb = this.agent.bbox // , origin = bb.relOrigin @@ -266,7 +257,7 @@ Y.subclass('Square', new Vec(0,0), { getNeighbors : function getNeighbors(){ var neighbors = [] , abs = Math.abs - , pm = this.pathmap + , pm = this.map , agent = pm._agent , SIZE = pm.pathSquare @@ -320,24 +311,8 @@ Y.subclass('Square', new Vec(0,0), { ; - -// Wrap QuadTree Methods to accept Rect-like objects -'overlaps get set removeAll leaves collect' - .split(' ') - .forEach(function(name){ - var method = PathMap.fn[name] || QuadTree.fn[name]; - PathMap.fn[name] = function pmHandleRect(o){ - var args = arguments, xy; - if (o.x1 !== undefined){ - xy = [o.x1,o.y1, o.x2,o.y2]; - args = (args.length === 1) ? xy : xy.concat(Y(args,1)); - } - return method.apply(this, args); - }; - }); - // Stay sync'd with config config.updateOnChange( ['pathing.pathSquare', 'pathing.pathSquareMid'], - PathMap.fn); + Map.fn); diff --git a/src/tanks/map/pathing/map-searching.cjs b/src/tanks/map/pathing/map-searching.cjs new file mode 100644 index 0000000..35d54ac --- /dev/null +++ b/src/tanks/map/pathing/map-searching.cjs @@ -0,0 +1,109 @@ +// -*- mode: JavaScript; tab-width: 4; indent-tabs-mode: nil; -*- +var Y = require('Y').Y +, op = require('Y/op') + +, vec = require('ezl/math/vec') +, Vec = vec.Vec +, Line = require('ezl/math/line').Line +, QuadTree = require('ezl/util/tree/quadtree').QuadTree +, BinaryHeap = require('ezl/util/tree/binaryheap').BinaryHeap + +, config = require('tanks/config').config +, constants = require('tanks/constants') +, BoundsType = constants.BoundsType +, DensityType = constants.DensityType +, Map = require('tanks/map/pathing/map').Map +, Trajectory = require('tanks/map/pathing/trajectory').Trajectory +, Traversal = require('tanks/map/pathing/traversal').Traversal +, Thing = require('tanks/thing/thing').Thing +, Bullet = require('tanks/thing/bullet').Bullet + +, _X = 0, _Y = 1 +, BULLET_MOVE_PER_FRAME = MS_PER_FRAME * Bullet.fn.stats.move*REF_SIZE/1000 +, SQRT_TWO = Math.sqrt(2) +; + + +Y.core.extend(Map.fn, { + + // moveAwayFrom : function moveAwayFrom(agent){ + // var mid = this.midpoint + // , trj = agent.trajectory.tangent(mid) + // + // , wall = this.closestOf(this.game.map.allWalls) + // , wmid = wall.midpoint + // + // , lvl = this.game.level.bbox, w = lvl.width, h = lvl.height + // , x = ((mid.x - wmid.x) > 0 ? w : 0) + // , y = ((mid.y - wmid.y) > 0 ? h : 0) + // , to = this.currentMove = trj.near(x,y); + // + // this.forceCurrentMove = this.willCollide.bind(this, [agent], 5); + // this.currentMoveLimit = this.now + 1000; + // + // this.move(to.x, to.y); + // + // // console.log(' --> Dodge', agent, 'away from', wall, 'to', to); + // return to; + // }, + + findNearLike : function findNearLike(me, ticks, fn){ + if (fn) fn = fn.toFunction(); + + var within = BULLET_MOVE_PER_FRAME*ticks + , bb = me.bbox + , x1 = bb.x1 - within, y1 = bb.y1 - within + , x2 = bb.x2 + within, y2 = bb.y2 + within + , dudes = this.get(x1,y1, x2,y2) + ; + if (fn && dudes.length) + return dudes.filter(fn, me); + else + return dudes; + }, + + findNearEnemies : function findNearEnemies(me, ticks){ + return this.findNearLike(me, ticks, this._nearEnemyFilter); + }, + + _nearEnemyFilter : function nearEnemyFilter(agent){ + var me = this; // Runs in the context of the 'me' unit; @see this.findNearLike() + return agent.isCombatant && agent.align !== me.align; + }, + + findNearEnemiesInSight : function findNearEnemiesInSight(me, ticks){ + return this.findNearLike(me, ticks, this._nearEnemyInSightFilter); + }, + + _nearEnemyInSightFilter : function nearEnemyInSightFilter(agent){ + var me = this; // Runs in the context of the 'me' unit; @see this.findNearLike() + return ( agent.align !== me.align && agent.isCombatant && + new Trajectory(me, me.loc, agent.loc).pathBlocked(agent) ); + }, + + closestOf : function closestOf(me, agents){ + if ( !(agents && agents.length) ) + return null; + + return agents.sort(function(a,b){ + return op.cmp( + manhattan(a.midpoint, me.loc), + manhattan(b.midpoint, me.loc) ); + })[0]; + }, + + willCollide : function willCollide(me, bullets, wiggle){ + bullets = ( Y.isArray(bullets) ? bullets : [bullets] ); + wiggle = wiggle || 0; + + var bb = me.bbox + , w = bb.width+wiggle, h = bb.height+wiggle ; + return bullets.filter(function(agent){ + var trj = agent.trajectory; + return ( !agent.dead + && trj.comesWithin(me, w,h) + && !trj.pathBlocked(me) ); + }); + } + +}); diff --git a/src/tanks/map/pathing/map.cjs b/src/tanks/map/pathing/map.cjs new file mode 100644 index 0000000..3d7ce32 --- /dev/null +++ b/src/tanks/map/pathing/map.cjs @@ -0,0 +1,57 @@ +// -*- mode: JavaScript; tab-width: 4; indent-tabs-mode: nil; -*- +var Y = require('Y').Y +, QuadTree = require('ezl/util/tree/quadtree').QuadTree + +, constants = require('tanks/constants') +, BoundsType = constants.BoundsType +, DensityType = constants.DensityType +, + + +Map = +exports['Map'] = +QuadTree.subclass('Map', { + // Config + pathSquare : null, + pathSquareMid : null, + + // State + _squares : null, // Cache of Square objects + _pathId : -1, // Instance of A* being run, to track when to reset Square instances + + allWalls : null, // All walls in this map + innerWalls : null, // Non-boundary walls + denseWalls : null, // Non-boundary non-Fences + + + + init : function initMap(x1,y1, x2,y2, capacity, buffer_size) { + this._squares = {}; + this.allWalls = Y([]); + this.innerWalls = Y([]); + this.denseWalls = Y([]); + + this.buffer_size = buffer_size; + x1 -= buffer_size; y1 -= buffer_size; + x2 += buffer_size; y2 += buffer_size; + + QuadTree.init.call(this, x1,y1, x2,y2, capacity); + } + + +}); + +// Wrap QuadTree Methods to accept Rect-like objects +'overlaps get set removeAll leaves collect' + .split(' ') + .forEach(function(name){ + var method = Map.fn[name] || QuadTree.fn[name]; + Map.fn[name] = function mapHandleRect(o){ + var args = arguments, xy; + if (o.x1 !== undefined){ + xy = [o.x1,o.y1, o.x2,o.y2]; + args = (args.length === 1) ? xy : xy.concat(Y(args,1)); + } + return method.apply(this, args); + }; + }); diff --git a/src/tanks/map/pathing/trajectory.cjs b/src/tanks/map/pathing/trajectory.cjs index 6bd8add..5cc3892 100644 --- a/src/tanks/map/pathing/trajectory.cjs +++ b/src/tanks/map/pathing/trajectory.cjs @@ -22,7 +22,7 @@ Line.subclass('Trajectory', { this.owner = owner; this.game = owner.game; - this.pathmap = this.game.pathmap; + this.map = this.game.map; this.reset(x1,y1, x2,y2, tdist, tCurrent); }, @@ -38,7 +38,7 @@ Line.subclass('Trajectory', { Line.init.call(this, x1,y1, x2,y2, tdist || this.tdist); // Find appropriate edge in direction of line - var pm = this.pathmap + var pm = this.map , ex = (x1 > x2 ? -REF_SIZE : REF_SIZE+pm.width ) , ey = (y1 > y2 ? -REF_SIZE : REF_SIZE+pm.height) , edge = this.near(ex,ey) @@ -155,9 +155,9 @@ Line.subclass('Trajectory', { pathBlocked : function pathBlocked(obj, ignore){ var walls, blockers; if (this.owner.isProjectile) - walls = this.pathmap.denseWalls; + walls = this.map.denseWalls; else - walls = this.pathmap.innerWalls; // FIXME: won't filter out concave intersections with the bounds + walls = this.map.innerWalls; // FIXME: won't filter out concave intersections with the bounds blockers = walls .concat( this.game.units ) diff --git a/src/tanks/map/pathing/traversal.cjs b/src/tanks/map/pathing/traversal.cjs index 6f6beda..bc0ca25 100644 --- a/src/tanks/map/pathing/traversal.cjs +++ b/src/tanks/map/pathing/traversal.cjs @@ -22,7 +22,7 @@ Y.subclass('Traversal', { this.thing = thing; this.game = thing.game; - this.pathmap = thing.game.pathmap; + this.map = thing.game.map; this.bbox = thing.bbox.clone(); this.trajectory = trajectory || thing.trajectory; @@ -61,7 +61,7 @@ Y.subclass('Traversal', { this.bbox.relocate(to); // BoundingBox.relocate() is in-place this.blockers = - this.pathmap.get(this.bbox) + this.map.get(this.bbox) .remove(this.thing) .sort(tr.compare); diff --git a/src/tanks/thing/tank.cjs b/src/tanks/thing/tank.cjs index 4c318d5..2caad1c 100644 --- a/src/tanks/thing/tank.cjs +++ b/src/tanks/thing/tank.cjs @@ -29,6 +29,8 @@ exports['Tank'] = Thing.subclass('Tank', function(Tank){ Y.core.descriptors(this, { + isCombatant : true, + colors : { body : '#83BB32', turret : '#1C625B', @@ -92,9 +94,6 @@ Thing.subclass('Tank', function(Tank){ this.elapsed = elapsed; this.now = now; - // this.continueMove(); - // return; - // Check to see if we should obey our last decision, and not recalc if (this.forceCurrentMove && this.forceCurrentMove() && this.currentMoveLimit > now) { // console.log('forced!', this.currentMove); @@ -174,7 +173,7 @@ Thing.subclass('Tank', function(Tank){ , x1 = tx - pw2 - WIGGLE, y1 = ty - ph2 - WIGGLE , x2 = tx + pw2 + WIGGLE, y2 = ty + ph2 + WIGGLE - , blockers = this.game.pathmap.get(x1,y1, x2,y2).filter(filterShoot, this) + , blockers = this.game.map.get(x1,y1, x2,y2).filter(filterShoot, this) ; if ( blockers.size() ) @@ -254,7 +253,7 @@ Thing.subclass('Tank', function(Tank){ this.forceCurrentMove = false; this.currentMoveLimit = -1; - var pm = this.game.pathmap + var pm = this.game.map , start = this.loc , path = this.currentPath = pm.path(this, end) @@ -264,97 +263,6 @@ Thing.subclass('Tank', function(Tank){ }; - /** - * TODO: Get this.currentMove etc out of the calc methods. - */ - this['moveAwayFrom'] = - function moveAwayFrom(agent){ - var mid = this.midpoint - , trj = agent.trajectory.tangent(mid) - - , wall = this.closestOf(this.game.pathmap.allWalls) - , wmid = wall.midpoint - - , lvl = this.game.level.bbox, w = lvl.width, h = lvl.height - , x = ((mid.x - wmid.x) > 0 ? w : 0) - , y = ((mid.y - wmid.y) > 0 ? h : 0) - , to = this.currentMove = trj.near(x,y); - - this.forceCurrentMove = this.willCollide.bind(this, [agent], 5); - this.currentMoveLimit = this.now + 1000; - - this.move(to.x, to.y); - - // console.log(' --> Dodge', agent, 'away from', wall, 'to', to); - return to; - }; - - this['find'] = - function find(x1,y1, x2,y2){ - return this.pathmap.get(x1,y1, x2,y2); - }; - - - var kTrue = op.K(true); - - this['findNearLike'] = - function findNearLike(ticks, fn){ - fn = (fn || kTrue).toFunction(); - - var within = BULLET_MOVE_PER_FRAME*ticks - , bb = this.bbox - , x1 = bb.x1 - within, y1 = bb.y1 - within - , x2 = bb.x2 + within, y2 = bb.y2 + within - ; - - return this.game.pathmap.get(x1,y1, x2,y2).filter(fn, this); - }; - - this['findNearEnemies'] = - function findNearEnemies(ticks, needLineOfSight){ // TODO: Split off LOS version - return this.findNearLike(ticks, function nearEnemyFilter(agent){ - var aLoc = agent.loc; - return ( agent.align !== this.align - && (agent instanceof Tank) - && !(needLineOfSight - && new Trajectory(this,this.loc,aLoc).pathBlocked(agent)) - ); - }); - }; - - this['closestOf'] = - function closestOf(agents){ - if ( !(agents && agents.size()) ) - return null; - - var cmp = op.cmp - , loc = this.loc ; - - agents.sort(function(a,b){ - return cmp( - manhattan(a.midpoint,loc), - manhattan(b.midpoint,loc) ); - }); - - return agents.attr(0); - }; - - this['willCollide'] = - function willCollide(bullets, wiggle){ - bullets = ( Y.isArray(bullets) ? bullets : [bullets] ); - wiggle = wiggle || 0; - - var tank = this, bb = this.bbox - , w = bb.width+wiggle, h = bb.height+wiggle ; - - return bullets.filter(function(b){ - var trj = b.trajectory; - return ( !b.dead - && trj.comesWithin(tank, w,h) - && !trj.pathBlocked(tank) ); - }); - }; - this['getTurretLoc'] = function getTurretLoc(){ var WIGGLE = 2 diff --git a/src/tanks/thing/thing.cjs b/src/tanks/thing/thing.cjs index 5487ab5..e184dc3 100644 --- a/src/tanks/thing/thing.cjs +++ b/src/tanks/thing/thing.cjs @@ -53,9 +53,11 @@ new evt.Class('Thing', { dead : false, dirty : true, - // Properties + // Unit Flags blocking : BoundsType.BLOCKING, density : DensityType.DENSE, + isWall : false, + isCombatant : false, isProjectile : false, isRenderable : false, // Agent will present itself for rendering when ready // FIXME: stupid hack active : true, // Agent takes actions? diff --git a/src/tanks/ui/pathmapui.cjs b/src/tanks/ui/pathmapui.cjs index cf27951..aca2005 100644 --- a/src/tanks/ui/pathmapui.cjs +++ b/src/tanks/ui/pathmapui.cjs @@ -6,7 +6,7 @@ var Y = require('Y').Y , config = require('tanks/config').config , BoundsType = require('tanks/constants').BoundsType -, PathMap = require('tanks/map/pathing/pathmap').PathMap +, Map = require('tanks/map/pathing/map').Map , @@ -20,7 +20,7 @@ Rect.subclass('PathMapUI', { overlayAiPaths : null, // Shape Config - _cssClasses : 'pathmap rect shape layer ezl', + _cssClasses : 'map rect shape layer ezl', // Blocking objects @@ -36,11 +36,11 @@ Rect.subclass('PathMapUI', { - init : function initPathMapUI(game, pathmap){ + init : function initPathMapUI(game, map){ Y.bindAll(this, 'pathWithUI', 'cleanUpAgent', 'drawPathStep', 'overlayRegion'); var level = game.level - , b = this.buffer = pathmap.buffer_size; + , b = this.buffer = map.buffer_size; Rect.init.call(this, level.width, level.height); // this.posBleed.x = this.posBleed.y = // this.negBleed.x = this.negBleed.y = b; @@ -48,18 +48,18 @@ Rect.subclass('PathMapUI', { this.size(null,null); this.game = game; - this.pathmap = pathmap; + this.map = map; this.highlights = Y([]); // Store ref to original path function - this._path = pathmap.path; - pathmap.path = this.pathWithUI; + this._path = map.path; + map.path = this.pathWithUI; }, render : function render(ctx){ // nb. AI paths are automatically drawn (and cleaned up) as they are created (and destroyed). - // Redraw pathmap + // Redraw map if (this.overlayPathmap) this.overlay(ctx); @@ -69,7 +69,7 @@ Rect.subclass('PathMapUI', { overlay : function overlay(ctx){ // console.group('overlay'); - this.pathmap.reduce(this.overlayRegion, { 'ctx':ctx }); + this.map.reduce(this.overlayRegion, { 'ctx':ctx }); // console.groupEnd(); }, @@ -104,10 +104,10 @@ Rect.subclass('PathMapUI', { }, /** - * Wraps PathMap.path() to draw AI pathes. + * Wraps Map.path() to draw AI pathes. */ pathWithUI : function pathWithUI(agent, x,y){ - var pm = this.pathmap + var pm = this.map , path = this._path.call(pm, agent, x,y) , start = vec.sum(pm._getSquare(agent.loc), pm.pathSquareMid) ; diff --git a/src/tanks/util/utils.cjs b/src/tanks/util/utils.cjs index 86f52a1..6016604 100644 --- a/src/tanks/util/utils.cjs +++ b/src/tanks/util/utils.cjs @@ -6,7 +6,7 @@ Object.dump = function(o){ }; function dumpPathmap(){ - var pm = tanks.game.pathmap; + var pm = tanks.game.map; console.warn(new Date(), pm); pm.collect(pm.x1,pm.y1, pm.x2,pm.y2, function(acc, v, r){ console.log(r+''); diff --git a/www/data b/www/data new file mode 120000 index 0000000..4909e06 --- /dev/null +++ b/www/data @@ -0,0 +1 @@ +../data \ No newline at end of file