From: dsc Date: Tue, 11 Jan 2011 07:41:19 +0000 (-0800) Subject: Pathing refactor complete. X-Git-Url: http://git.less.ly:3516/?a=commitdiff_plain;h=90bf21cd575892e1506caffd057995fc9e55abf0;p=tanks.git Pathing refactor complete. --- diff --git a/data/types/levels.yaml b/data/types/levels.yaml index 35f3bc3..43fc167 100644 --- a/data/types/levels.yaml +++ b/data/types/levels.yaml @@ -57,15 +57,15 @@ 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] + # - type: blue + # align: 1 + # loc: [175,475] + - type: green + align: 2 + loc: [75,25] - type: green align: 2 loc: [25,375] diff --git a/src/tanks/map/pathing/map-pathing.cjs b/src/tanks/map/pathing/map-pathing.cjs index 36cdc97..6d189ba 100644 --- a/src/tanks/map/pathing/map-pathing.cjs +++ b/src/tanks/map/pathing/map-pathing.cjs @@ -5,7 +5,6 @@ var Y = require('Y').Y , 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 @@ -13,26 +12,11 @@ var Y = require('Y').Y , 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) - -, kTrue = op.K(true) -, isBullet = Y.is(Bullet) ; -/** - * A QuadTree which aids in pathing for AI. - * - QuadTree methods which took rect coords (x1,y1, x2,y2) will accept - * anything Rect-like (having properties x1,y1, x2,y2). - * - Pathing methods will account for the unit's size when calculating paths, - * intersections, blocking, and similar tasks. - */ Y.core.extend(Map.fn, { /** diff --git a/src/tanks/map/pathing/map-searching.cjs b/src/tanks/map/pathing/map-searching.cjs index 35d54ac..f96a082 100644 --- a/src/tanks/map/pathing/map-searching.cjs +++ b/src/tanks/map/pathing/map-searching.cjs @@ -4,49 +4,20 @@ var Y = require('Y').Y , 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 +, manhattan = vec.manhattan -, 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 +, BULLET_MOVE_PER_FRAME = MS_PER_FRAME * Bullet.fn.stats.move*REF_SIZE/1000 // FIXME: different projectile types move at different rates! , 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(); @@ -62,10 +33,16 @@ Y.core.extend(Map.fn, { return dudes; }, + findNearBullets : function findNearBullets(me, ticks){ + return this.findNearLike(me, ticks, this._nearBulletFilter); + }, + _nearBulletFilter : function nearBulletFilter(agent){ + return agent.isProjectile; + }, + 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; @@ -74,11 +51,10 @@ Y.core.extend(Map.fn, { 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) ); + new Trajectory(me, me.loc, agent.loc).canSee(agent) ); }, closestOf : function closestOf(me, agents){ @@ -92,6 +68,10 @@ Y.core.extend(Map.fn, { })[0]; }, + closestWall : function closestWall(me){ + return this.closestOf(me, this.allWalls); + }, + willCollide : function willCollide(me, bullets, wiggle){ bullets = ( Y.isArray(bullets) ? bullets : [bullets] ); wiggle = wiggle || 0; diff --git a/src/tanks/map/pathing/map.cjs b/src/tanks/map/pathing/map.cjs index 3d7ce32..8b6b7d2 100644 --- a/src/tanks/map/pathing/map.cjs +++ b/src/tanks/map/pathing/map.cjs @@ -8,6 +8,13 @@ var Y = require('Y').Y , +/** + * A QuadTree which aids in pathing for AI. + * - QuadTree methods which took rect coords (x1,y1, x2,y2) will accept + * anything Rect-like (having properties x1,y1, x2,y2). + * - Pathing methods will account for the unit's size when calculating paths, + * intersections, blocking, and similar tasks. + */ Map = exports['Map'] = QuadTree.subclass('Map', { diff --git a/src/tanks/map/pathing/trajectory.cjs b/src/tanks/map/pathing/trajectory.cjs index 5cc3892..f3072f4 100644 --- a/src/tanks/map/pathing/trajectory.cjs +++ b/src/tanks/map/pathing/trajectory.cjs @@ -152,14 +152,23 @@ Line.subclass('Trajectory', { return ( t <= ft && (dw <= w || dh <= h) ); }, + canSee : function canSee(obj, ignore){ + var blockers = + this.map.denseWalls + .apply('remove', [this.owner, obj].concat(ignore || []) ) + .filter( this.intersects ) + .sort( this.compare ); + return !!blockers.length; + }, + pathBlocked : function pathBlocked(obj, ignore){ - var walls, blockers; - if (this.owner.isProjectile) - walls = this.map.denseWalls; - else - walls = this.map.innerWalls; // FIXME: won't filter out concave intersections with the bounds + // var walls, blockers + // if (this.owner.isProjectile) + // walls = this.map.denseWalls; + // else + // walls = this.map.innerWalls; // FIXME: won't filter out concave intersections with the bounds - blockers = walls + var blockers = this.map.innerWalls .concat( this.game.units ) .apply('remove', [this.owner].concat(ignore || []) ) .filter( this.intersects ) diff --git a/src/tanks/thing/tank.cjs b/src/tanks/thing/tank.cjs index 2caad1c..dfbcbed 100644 --- a/src/tanks/thing/tank.cjs +++ b/src/tanks/thing/tank.cjs @@ -2,11 +2,10 @@ var Y = require('Y').Y , op = require('Y/op') , vec = require('ezl/math/vec') -, shape = require('ezl/shape') +, Vec = vec.Vec , Cooldown = require('ezl/loop').Cooldown , CooldownGauge = require('ezl/widget').CooldownGauge -, Vec = vec.Vec -, manhattan = vec.manhattan +, shape = require('ezl/shape') , Rect = shape.Rect , Circle = shape.Circle @@ -18,8 +17,6 @@ var Y = require('Y').Y , Thing = require('tanks/thing/thing').Thing , Bullet = require('tanks/thing/bullet').Bullet -, isBullet = Y.is(Bullet) -, BULLET_MOVE_PER_FRAME = MS_PER_FRAME * Bullet.fn.stats.move*REF_SIZE/1000 , _X = 0, _Y = 1 , @@ -90,7 +87,7 @@ Thing.subclass('Tank', function(Tank){ this['act'] = function act(elapsed, now){ - var ai = this.ai; + var ai = this.ai, map = this.game.map; this.elapsed = elapsed; this.now = now; @@ -105,11 +102,11 @@ Thing.subclass('Tank', function(Tank){ // Try to shoot down nearby bullets if (ai.shootIncoming.ready && this.ableToShoot()) { - var bs = this.willCollide( this.findNearLike(25, isBullet) ); + var bs = map.willCollide(this, map.findNearBullets(this, 25) ); // console.log('['+TICKS+':'+this.id, this, '] Shoot down bullets?', bs.size() && bs); if ( bs.size() ) { ai.shootIncoming.activate(now); - var b = this.closestOf(bs); + var b = map.closestOf(this, bs); // console.log(' --> Incoming! Shoot it down!', b); this.shoot(b.loc.x, b.loc.y); return this; @@ -118,11 +115,11 @@ Thing.subclass('Tank', function(Tank){ // Dodge incoming bullet if (ai.dodge.ready) { - var bs = this.willCollide(this.findNearLike(71, isBullet), 5); + var bs = map.willCollide(this, map.findNearBullets(this, 71), 5); // console.log('['+TICKS+':'+this.id, this, '] Dodge bullets?', bs.size() && bs); if (bs.size()) { ai.dodge.activate(now); - var bullet = this.closestOf(bs); + var bullet = map.closestOf(this, bs); this.moveAwayFrom(bullet); return this; } @@ -130,7 +127,7 @@ Thing.subclass('Tank', function(Tank){ // Try to blow up nearby tanks if (ai.shootEnemy.ready && (this.stats.shots.val - this.nShots > 1)) { - var t = this.findNearEnemies(71, true).shift(); + var t = map.findNearEnemiesInSight(this, 71).shift(); // console.log('['+TICKS+':'+this.id, this, '] Shoot at enemies?', t); if (t) { ai.shootEnemy.activate(now); @@ -226,7 +223,7 @@ Thing.subclass('Tank', function(Tank){ this['continueMove'] = function continueMove(){ if ( !this.currentMove || this.ai.path.ready ){ - var target = this.findNearEnemies(10000).shift(); + var target = this.game.map.findNearEnemies(this, 10000).shift(); if (target) this.calculatePath(target.loc); else @@ -263,6 +260,30 @@ Thing.subclass('Tank', function(Tank){ }; + this['moveAwayFrom'] = + function moveAwayFrom(agent){ + var map = this.game.map + , mid = this.midpoint + , trj = agent.trajectory.tangent(mid) + + , wall = map.closestWall(this) + , 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 = map.willCollide.bind(map, 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['getTurretLoc'] = function getTurretLoc(){ var WIGGLE = 2