, Item = require('tanks/thing/item').Item
, PlayerTank = require('tanks/thing/player').PlayerTank
, PathMap = require('tanks/map/pathmap').PathMap
-, Wall = require('tanks/map/wall').Wall
+, Wall = require('tanks/thing/wall').Wall
,
// game.addThing(new Tank(1).colors('#4596FF', '#182B53', '#F25522'), 3,9);
E =
- game.addThing(new Tank(2), 0,5);
- game.addThing(new Tank(2), 1,0);
- game.addThing(new Tank(2), 8,1);
+ game.addThing(new Tank(2), 0,7);
+ // game.addThing(new Tank(2), 1,0);
+ // game.addThing(new Tank(2), 8,1);
- I = game.addThing(new Item(), 8,8);
+ // I = game.addThing(new Item(), 8,8);
},
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 = require('ezl/math/vec')
, QuadTree = require('ezl/util/tree/quadtree').QuadTree
-, astar = require('ezl/util/astar')
-, config = require('tanks/config').config
-, Bullet = require('tanks/thing/bullet').Bullet
-, Vec = vec.Vec
-, Line = math.Line
+/** Does not obstruct other objects. */
+, PASSABLE = exports['PASSABLE'] = 0
+
+/** Does not obstruct other objects, but still collides with them. */
+, ZONE = exports['ZONE'] = 1
+
+/** Obstructs other blockers with its BoundingBox. */
+, BLOCKING = exports['BLOCKING'] = 2
+
+/** Potentially obstructs other objects, but requires a special test once a BoundingBox collision has been detected. */
+, IRREGULAR = exports['IRREGULAR'] = 3
,
delete obj.region;
}
return obj;
- },
-
- // moveBlocked : function moveBlocked(agent, trj, to, bb){
- // bb = bb || agent.boundingBox;
- // var blockers, blocker, msg
- // , side = null
- // , tobb = bb.relocated(to.x,to.y)
- // , x1 = tobb.x1, y1 = tobb.y1
- // , x2 = tobb.x2, y2 = tobb.y2
- //
- // , ro = bb.relOrigin
- // , bw = bb.width, bh = bb.height
- // , offX = bw - ro.x, offY = bh = ro.y
- //
- // // , x1 = to.x+offX, y1 = to.y+offY
- // // , x2 = x1+bw, y2 = y1+bh
- // ;
- //
- // blockers = this.get(x1,y1, x2,y2).remove(agent).end();
- // blocker = blockers[0];
- //
- // // Not blocked
- // if (!blocker) return false;
- //
- // // Literal corner case :P
- // // XXX: needs better detection of corner
- // if (blockers.length > 1) {
- // msg = 'corner of '+blockers.slice(0);
- // to = trj.p1;
- //
- // // Normal reflection against one line
- // } else {
- // msg = blocker+' on the ';
- //
- // var B = blocker.boundingBox;
- // if (bb.x2 <= B.x1 && x2 >= B.x1) {
- // msg += 'left';
- // side = B.leftSide;
- // to = trj.pointAtX(B.x1-offX-1);
- //
- // } else if (bb.x1 >= B.x2 && x1 <= B.x2) {
- // msg += 'right';
- // side = B.rightSide;
- // to = trj.pointAtX(B.x2+ro.x+1);
- //
- // } else if (bb.y2 <= B.y1 && y2 >= B.y1) {
- // msg += 'top';
- // side = B.topSide;
- // to = trj.pointAtY(B.y1-offY-1);
- //
- // } else if (bb.y1 >= B.y2 && y1 <= B.y2) {
- // msg += 'bottom';
- // side = B.bottomSide;
- // to = trj.pointAtY(B.y2+ro.y+1);
- // }
- //
- // msg += ' side';
- // }
- //
- // return { 'msg':msg, 'blockers':blockers, 'side':side, 'to':to };
- // },
-
+ }
});
, vec = require('ezl/math/vec')
, QuadTree = require('ezl/util/tree/quadtree').QuadTree
, BinaryHeap = require('ezl/util/binaryheap').BinaryHeap
-
-, config = require('tanks/config').config
-, Bullet = require('tanks/thing/bullet').Bullet
-, Map = require('tanks/map/map').Map
, Vec = vec.Vec
, Line = math.Line
+, config = require('tanks/config').config
+, map = require('tanks/map/map')
+, Map = map.Map
-, SQRT_TWO = Math.sqrt(2)
-, PASSABLE = 1 // Does not obstruct other objects
-, BLOCKING = 2 // Obstructs other blockers
-, ZONE = 3 // Does not obstruct other objects, but still collides with them
+, SQRT_TWO = Math.sqrt(2)
,
-
-// Would be nice if I could make this an inner class (for once)
-Square =
-exports['Square'] =
-Y.subclass('Square', new Vec(0,0), {
- pathId : null, // instance of A* being run, to track when to reset
-
- // resetable:
- dist : 0, // estimated distance
- startDist : 0, // distance from start
- endDist : 0, // estimated distance to end
- visited : false,
- closed : false,
- prev : null,
-
-
- /**
- * @param x Left coord of square.
- * @param y Top coord of square.
- */
- init : function initSquare(pathmap, x,y){
- Vec.init.call(this, x,y);
- this.pathmap = pathmap;
- this.reset();
- },
-
- reset : function reset(){
- var pathId = this.pathmap._pathId;
- if (this.pathId === pathId)
- return this;
-
- this.pathId = pathId;
- this.blocked = this._blocked();
-
- this.dist = 0;
- this.startDist = 0;
- this.endDist = 0;
- this.visited = false;
- this.closed = false;
- this.prev = null;
-
- return this;
- },
-
- /**
- * @private Calculates this.blocked value. Should only be called by reset() to cache the result.
- */
- _blocked : function blocked(){
- var pm = this.pathmap
- , agent = pm._agent
- // , bb = agent.boundingBox
-
- // , origin = bb.relOrigin
- // , left = origin.x, right = bb.width - left
- // , top = origin.y, bottom = bb.height - top
-
- , SIZE = pm.gridSquare
- , x = Math.floor(this.x)
- , y = Math.floor(this.y)
- // , x1 = x - left, x2 = x + SIZE + right
- // , y1 = y - top, y2 = y + SIZE + bottom
- , x1 = x, x2 = x + SIZE
- , y1 = y, y2 = y + SIZE
-
- , blockers = pm.get(x1,y1, x2,y2)
- .remove(agent)
- .filter(this._filterBlocked)
- ;
-
- return !!blockers.length;
- },
-
- /**
- * @private
- */
- _filterBlocked : function filterBlocked(v, r){
- return !(v.isBoundary || v instanceof Bullet); // XXX: use PASSABLE
- },
-
- getNeighbors : function getNeighbors(){
- var neighbors = []
- , abs = Math.abs
- , pm = this.pathmap
- , agent = pm._agent
- , SIZE = pm.gridSquare
-
- , x = this.x, y = this.y
- , sq, cost, ix, iy, x1,y1, x2,y2
- ;
-
- for (ix=-1; ix<2; ix++) {
- for (iy=-1; iy<2; iy++) {
- // Skip self
- if (ix === 0 && iy === 0)
- continue;
-
- cost = 1;
- x1 = x + ix*SIZE; y1 = y + iy*SIZE;
- x2 = x1+SIZE; y2 = y1+SIZE;
-
- // filter squares outside bounds
- if ( pm.x1 >= x1 || pm.y1 >= y1 ||
- pm.x2 <= x2 || pm.y2 <= y2 )
- continue;
-
- // Diagonal square
- if ( abs(ix) === 1 && abs(iy) === 1 ) {
- cost = SQRT_TWO;
-
- // Ensure we don't cut a blocked corner
- if ( pm._getSquare(x1,y).blocked || pm._getSquare(x,y1).blocked )
- continue;
- }
-
- sq = pm._getSquare(x1,y1);
- neighbors.push([ sq, cost*SIZE ]);
- }
- }
-
- return neighbors;
- },
-
- toString : function toString(){
- var props = [];
- if (this.blocked) props.push('blocked');
- if (this.visited) props.push('dist='+this.dist);
- if (this.closed) props.push('closed');
- props = props.join(', ');
- if (props) props = '('+props+')';
- return '['+this.x+' '+this.y+']'+props;
- }
-
-})
-
-
-
/**
* A QuadTree which aids in pathing for AI.
* - QuadTree methods which took rect coords (x1,y1, x2,y2) will accept
return new Vec(floor(x)*size, floor(y)*size);
}
-});
+})
+,
+
+
+// Would be nice if I could make this an inner class (for once)
+Square =
+exports['Square'] =
+Y.subclass('Square', new Vec(0,0), {
+ pathId : null, // instance of A* being run, to track when to reset
+
+ // resetable:
+ dist : 0, // estimated distance
+ startDist : 0, // distance from start
+ endDist : 0, // estimated distance to end
+ visited : false,
+ closed : false,
+ prev : null,
+
+
+ /**
+ * @param x Left coord of square.
+ * @param y Top coord of square.
+ */
+ init : function initSquare(pathmap, x,y){
+ Vec.init.call(this, x,y);
+ this.pathmap = pathmap;
+ this.reset();
+ },
+
+ reset : function reset(){
+ var pathId = this.pathmap._pathId;
+ if (this.pathId === pathId)
+ return this;
+
+ this.pathId = pathId;
+ this.blocked = this._blocked();
+
+ this.dist = 0;
+ this.startDist = 0;
+ this.endDist = 0;
+ this.visited = false;
+ this.closed = false;
+ this.prev = null;
+
+ return this;
+ },
+
+ /**
+ * @private Calculates this.blocked value. Should only be called by reset() to cache the result.
+ */
+ _blocked : function blocked(){
+ var pm = this.pathmap
+ , agent = pm._agent
+ // , bb = agent.boundingBox
+
+ // , origin = bb.relOrigin
+ // , left = origin.x, right = bb.width - left
+ // , top = origin.y, bottom = bb.height - top
+
+ , SIZE = pm.gridSquare
+ , x = Math.floor(this.x)
+ , y = Math.floor(this.y)
+ // , x1 = x - left, x2 = x + SIZE + right
+