From 596c9a0dbed2681efc396ab576fe36de41d7723f Mon Sep 17 00:00:00 2001 From: dsc Date: Thu, 31 Mar 2011 03:31:08 -0700 Subject: [PATCH] Adds Unit base class --- src/tanks/game.cjs | 8 +- src/tanks/map/pathing/index.cjs | 2 +- src/tanks/map/pathing/linear-trajectory.cjs | 246 --------------------------- src/tanks/map/pathing/lineartrajectory.cjs | 246 +++++++++++++++++++++++++++ src/tanks/map/pathing/map-searching.cjs | 6 +- src/tanks/thing/bullet.cjs | 6 +- src/tanks/thing/index.cjs | 4 +- src/tanks/thing/shield.cjs | 1 + src/tanks/thing/tank.cjs | 54 +++--- src/tanks/thing/thing.cjs | 3 +- src/tanks/thing/tower.cjs | 17 +- src/tanks/thing/unit.cjs | 38 ++++ 12 files changed, 335 insertions(+), 296 deletions(-) delete mode 100644 src/tanks/map/pathing/linear-trajectory.cjs create mode 100644 src/tanks/map/pathing/lineartrajectory.cjs diff --git a/src/tanks/game.cjs b/src/tanks/game.cjs index a213ba9..fabbc25 100644 --- a/src/tanks/game.cjs +++ b/src/tanks/game.cjs @@ -201,11 +201,11 @@ evt.subclass('Game', { if ( !this.byId[unit.__id__] ) { this.byId[unit.__id__] = unit; - if (unit.active) + if (unit.isActive) this.active.push(unit); if (unit.isProjectile) this.bullets.push(unit); - if (unit.isCombatant) + if (unit.isUnit) this.units.push(unit); if (unit.tick) this.toTick.push(unit); @@ -250,13 +250,13 @@ evt.subclass('Game', { delete this.byId[unit.__id__]; this.map.removeBlocker(unit); - if (unit.active) + if (unit.isActive) this.active.remove(unit); if (unit.tick) this.toTick.remove(unit); if (unit.isProjectile) this.bullets.remove(unit); - if (unit.isCombatant) + if (unit.isUnit) this.units.remove(unit); return unit; diff --git a/src/tanks/map/pathing/index.cjs b/src/tanks/map/pathing/index.cjs index 4eb559e..ea3502a 100644 --- a/src/tanks/map/pathing/index.cjs +++ b/src/tanks/map/pathing/index.cjs @@ -9,6 +9,6 @@ require('Y').Y .extend(exports, { 'Map' : require('tanks/map/pathing/map').Map, 'Traversal' : require('tanks/map/pathing/traversal').Traversal, - 'LinearTrajectory' : require('tanks/map/pathing/linear-trajectory').LinearTrajectory, + 'LinearTrajectory' : require('tanks/map/pathing/lineartrajectory').LinearTrajectory, 'CircularTrajectory' : require('tanks/map/pathing/circular-trajectory').CircularTrajectory }); diff --git a/src/tanks/map/pathing/linear-trajectory.cjs b/src/tanks/map/pathing/linear-trajectory.cjs deleted file mode 100644 index 4e439b0..0000000 --- a/src/tanks/map/pathing/linear-trajectory.cjs +++ /dev/null @@ -1,246 +0,0 @@ -var Y = require('Y').Y -, op = require('Y/op') -, Vec = require('ezl/math/vec').Vec -, Line = require('ezl/math/line').Line -, Rect = require('ezl/math/rect').Rect -, BoundingBox = require('ezl/loc').BoundingBox - -, Thing = require('tanks/thing/thing').Thing - -, BOUND_SIZE_RATIO = 0.75 -, - - -LinearTrajectory = -exports['LinearTrajectory'] = -Line.subclass('LinearTrajectory', { - tCurrent : 0, - - - init : function initLinearTrajectory(owner, x1,y1, x2,y2, tdist, tCurrent){ - Y.bindAll(this, 'compare', 'closer', 'intersects'); - - this.owner = owner; - this.game = owner.game; - this.map = this.game.map; - - this.reset(x1,y1, x2,y2, tdist, tCurrent); - }, - - reset : function reset(x1,y1, x2,y2, tdist, tCurrent){ - if (x1 instanceof Array && y1 instanceof Array) { - tdist = x2; - y2 = y1[1]; x2 = y1[0]; - y1 = x1[1]; x1 = x1[0]; - } - - // init with raw numbers to do calculations - Line.init.call(this, x1,y1, x2,y2, tdist || this.tdist); - - // Find appropriate edge in direction of line - 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) - ; - - // Move goal point beyond far wall to avoid rotations post-reflection - x2 = this.x2 = edge.x; - y2 = this.y2 = edge.y; - this.p2 = new Vec(x2,y2); - Vec.init.call(this, x2-x1, y2-y1); - - this.tCurrent = tCurrent || 0; - this.resetBound(); - return this; - }, - - // Determine how much time can pass before we risk teleporting - // We'll need to reset this whenever the bounding box changes size - resetBound : function resetBound(){ - this.tBound = - BOUND_SIZE_RATIO * Math.min( - Math.abs(this.owner.width / this.pa), - Math.abs(this.owner.height / this.pb) ); - return this; - }, - - clone : function clone(){ - return new LinearTrajectory(this.owner, this.x1,this.y1, this.x2,this.y2, this.tdist, this.tCurrent); - }, - - - intersects : function intersects(x,y){ - var o = x; - if (o.bbox) - o = o.bbox; - if (o.isRect || o instanceof Rect) - return o.intersects(this); - return Line.fn.intersects.call(this, x,y); - }, - - intersection : function intersection(line){ - if (!line) return null; - - // Line, Vec - if (line instanceof Line || line instanceof Vec) - return Line.fn.intersection.call(this, line); - - // Rect - var o = line; - if (o.bbox) o = o.bbox; - - var hits = [], hit - , sides = o.sides; - for (var n=0, L=sides.length, side=sides[n]; n 1 ) - hits.sort(this.compare); - return hits[0]; - }, - - /** - * Compares how distant in the future two objects are on this trajectory. - * Objects that have been passed are always further away than those in the future, - * but otherwise the comparison is performed by absolute distance. - * @return -1 if a closer b, 1 if a further b, 0 if a same as b - */ - compare : function compare(a, b){ - var _a = a, _b = b; - - if ( !(a instanceof Array) ) a = this.intersection(a); - if ( !(b instanceof Array) ) b = this.intersection(b); - - // if (a.bbox || a.intersection || a instanceof Rect) a = this.intersection(a); - // if (b.bbox || b.intersection || b instanceof Rect) b = this.intersection(b); - - if ( !(a || b) ) return 0; - if ( !a ) return 1; - if ( !b ) return -1; - - var abs = Math.abs - , t = this.tCurrent - - , xa = this.calcX(a.y), ya = this.calcY(a.x) - , ta = this.iparametric(xa,ya) - t - - , xb = this.calcX(b.y), yb = this.calcY(b.x) - , tb = this.iparametric(xb,yb) - t - ; - - // If one has passed, return the other - if ( isNaN(ta) || !isFinite(ta) || (ta < 0 && tb >= 0) ) - return 1; - if ( isNaN(tb) || !isFinite(tb) || (tb < 0 && ta >= 0) ) - return -1; - - return op.cmp(abs(ta), abs(tb)); - }, - - closer : function closer(o1, o2){ - return this.compare(o1,o2) === 1 ? o2 : o1; - }, - - sortClosest : function sortClosest(o1, o2){ - var things; - if (o1 instanceof Y.YArray) - things = o1; - else if (o1 instanceof Array) - things = Y(o1); - else - things = new Y(arguments); - - return things.sort( this.compare ); - }, - - closest : function closest(o1, o2){ - return this.sortClosest.apply(this, arguments).shift(); - }, - - comesWithin : function comesWithin(pt, w,h){ - if ( !this.owner.loc ) - return false; - - if (pt instanceof Thing) pt = pt.loc; - - if ( w === undefined ){ - w = 0; h = 0; - } else if ( Y.isNumber(w.width) ){ - h = w.height; w = w.width; - } - - var cur = this.owner.loc - , fx = this.calcX(pt.y), fy = this.calcY(pt.x) - , t = this.iparametric(cur.x, cur.y) - , ft = this.iparametric(fx,fy) - , dw = Math.abs(fx - pt.x), dh = Math.abs(fy - pt.y) - ; - return ( t <= ft && (dw <= w || dh <= h) ); - }, - - canSee : function canSee(obj, ignore){ - ignore = [this.owner].concat(ignore || []); - // var blockers = this.map.denseWalls - // .apply('remove', ignore) - // .filter(this.intersects) - // .sort( this.compare ) - var blockers = this.map.denseWalls - .apply('remove', ignore).concat([ obj ]) - .filter(this.intersects) - .sort(this.compare) - , blocker = blockers.first() - ; - return !!(blocker === obj); - }, - - 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 blockers = this.map.innerWalls - .concat( this.game.units ) - .apply('remove', [this.owner].concat(ignore || []) ) - .filter( this.intersects ) - .sort( this.compare ) - - , blocker = blockers.first() - ; - - return (blocker === obj ? false : blocker); - }, - - calcIntersectTraj : function calcIntersectTraj(fireLoc, speed){ - // targetVelocityVector = math.Vector3(0, 0, 0) * aTargetSpeed - // interceptVelocityVector = math.Vector3(0, 0, 0) * aBulletSpeed - // - // tDelta = aTargetPosition - aFiringPosition - // - // Vr = targetVelocityVector - interceptVelocityVector - // a = Vr.Dot( Vr ) - aBulletSpeed * aBulletSpeed - // b = 2 * Vr.Dot( tDelta ) - // c = tDelta.Dot ( tDelta ) - // - // deter = b * b - 4 * ( a * c ) - // - // if deter < 0: - // return -1 - // else: - // ETN = 2 * ( c / pdmath.sqrt(deter) - b ) - // return ETN - - }, - - - toString : function(){ - return 'T['+this.p1+', '+this.p2+', slope='+this.slope.toFixed(3)+']'; - } -}); diff --git a/src/tanks/map/pathing/lineartrajectory.cjs b/src/tanks/map/pathing/lineartrajectory.cjs new file mode 100644 index 0000000..4e439b0 --- /dev/null +++ b/src/tanks/map/pathing/lineartrajectory.cjs @@ -0,0 +1,246 @@ +var Y = require('Y').Y +, op = require('Y/op') +, Vec = require('ezl/math/vec').Vec +, Line = require('ezl/math/line').Line +, Rect = require('ezl/math/rect').Rect +, BoundingBox = require('ezl/loc').BoundingBox + +, Thing = require('tanks/thing/thing').Thing + +, BOUND_SIZE_RATIO = 0.75 +, + + +LinearTrajectory = +exports['LinearTrajectory'] = +Line.subclass('LinearTrajectory', { + tCurrent : 0, + + + init : function initLinearTrajectory(owner, x1,y1, x2,y2, tdist, tCurrent){ + Y.bindAll(this, 'compare', 'closer', 'intersects'); + + this.owner = owner; + this.game = owner.game; + this.map = this.game.map; + + this.reset(x1,y1, x2,y2, tdist, tCurrent); + }, + + reset : function reset(x1,y1, x2,y2, tdist, tCurrent){ + if (x1 instanceof Array && y1 instanceof Array) { + tdist = x2; + y2 = y1[1]; x2 = y1[0]; + y1 = x1[1]; x1 = x1[0]; + } + + // init with raw numbers to do calculations + Line.init.call(this, x1,y1, x2,y2, tdist || this.tdist); + + // Find appropriate edge in direction of line + 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) + ; + + // Move goal point beyond far wall to avoid rotations post-reflection + x2 = this.x2 = edge.x; + y2 = this.y2 = edge.y; + this.p2 = new Vec(x2,y2); + Vec.init.call(this, x2-x1, y2-y1); + + this.tCurrent = tCurrent || 0; + this.resetBound(); + return this; + }, + + // Determine how much time can pass before we risk teleporting + // We'll need to reset this whenever the bounding box changes size + resetBound : function resetBound(){ + this.tBound = + BOUND_SIZE_RATIO * Math.min( + Math.abs(this.owner.width / this.pa), + Math.abs(this.owner.height / this.pb) ); + return this; + }, + + clone : function clone(){ + return new LinearTrajectory(this.owner, this.x1,this.y1, this.x2,this.y2, this.tdist, this.tCurrent); + }, + + + intersects : function intersects(x,y){ + var o = x; + if (o.bbox) + o = o.bbox; + if (o.isRect || o instanceof Rect) + return o.intersects(this); + return Line.fn.intersects.call(this, x,y); + }, + + intersection : function intersection(line){ + if (!line) return null; + + // Line, Vec + if (line instanceof Line || line instanceof Vec) + return Line.fn.intersection.call(this, line); + + // Rect + var o = line; + if (o.bbox) o = o.bbox; + + var hits = [], hit + , sides = o.sides; + for (var n=0, L=sides.length, side=sides[n]; n 1 ) + hits.sort(this.compare); + return hits[0]; + }, + + /** + * Compares how distant in the future two objects are on this trajectory. + * Objects that have been passed are always further away than those in the future, + * but otherwise the comparison is performed by absolute distance. + * @return -1 if a closer b, 1 if a further b, 0 if a same as b + */ + compare : function compare(a, b){ + var _a = a, _b = b; + + if ( !(a instanceof Array) ) a = this.intersection(a); + if ( !(b instanceof Array) ) b = this.intersection(b); + + // if (a.bbox || a.intersection || a instanceof Rect) a = this.intersection(a); + // if (b.bbox || b.intersection || b instanceof Rect) b = this.intersection(b); + + if ( !(a || b) ) return 0; + if ( !a ) return 1; + if ( !b ) return -1; + + var abs = Math.abs + , t = this.tCurrent + + , xa = this.calcX(a.y), ya = this.calcY(a.x) + , ta = this.iparametric(xa,ya) - t + + , xb = this.calcX(b.y), yb = this.calcY(b.x) + , tb = this.iparametric(xb,yb) - t + ; + + // If one has passed, return the other + if ( isNaN(ta) || !isFinite(ta) || (ta < 0 && tb >= 0) ) + return 1; + if ( isNaN(tb) || !isFinite(tb) || (tb < 0 && ta >= 0) ) + return -1; + + return op.cmp(abs(ta), abs(tb)); + }, + + closer : function closer(o1, o2){ + return this.compare(o1,o2) === 1 ? o2 : o1; + }, + + sortClosest : function sortClosest(o1, o2){ + var things; + if (o1 instanceof Y.YArray) + things = o1; + else if (o1 instanceof Array) + things = Y(o1); + else + things = new Y(arguments); + + return things.sort( this.compare ); + }, + + closest : function closest(o1, o2){ + return this.sortClosest.apply(this, arguments).shift(); + }, + + comesWithin : function comesWithin(pt, w,h){ + if ( !this.owner.loc ) + return false; + + if (pt instanceof Thing) pt = pt.loc; + + if ( w === undefined ){ + w = 0; h = 0; + } else if ( Y.isNumber(w.width) ){ + h = w.height; w = w.width; + } + + var cur = this.owner.loc + , fx = this.calcX(pt.y), fy = this.calcY(pt.x) + , t = this.iparametric(cur.x, cur.y) + , ft = this.iparametric(fx,fy) + , dw = Math.abs(fx - pt.x), dh = Math.abs(fy - pt.y) + ; + return ( t <= ft && (dw <= w || dh <= h) ); + }, + + canSee : function canSee(obj, ignore){ + ignore = [this.owner].concat(ignore || []); + // var blockers = this.map.denseWalls + // .apply('remove', ignore) + // .filter(this.intersects) + // .sort( this.compare ) + var blockers = this.map.denseWalls + .apply('remove', ignore).concat([ obj ]) + .filter(this.intersects) + .sort(this.compare) + , blocker = blockers.first() + ; + return !!(blocker === obj); + }, + + 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 blockers = this.map.innerWalls + .concat( this.game.units ) + .apply('remove', [this.owner].concat(ignore || []) ) + .filter( this.intersects ) + .sort( this.compare ) + + , blocker = blockers.first() + ; + + return (blocker === obj ? false : blocker); + }, + + calcIntersectTraj : function calcIntersectTraj(fireLoc, speed){ + // targetVelocityVector = math.Vector3(0, 0, 0) * aTargetSpeed + // interceptVelocityVector = math.Vector3(0, 0, 0) * aBulletSpeed + // + // tDelta = aTargetPosition - aFiringPosition + // + // Vr = targetVelocityVector - interceptVelocityVector + // a = Vr.Dot( Vr ) - aBulletSpeed * aBulletSpeed + // b = 2 * Vr.Dot( tDelta ) + // c = tDelta.Dot ( tDelta ) + // + // deter = b * b - 4 * ( a * c ) + // + // if deter < 0: + // return -1 + // else: + // ETN = 2 * ( c / pdmath.sqrt(deter) - b ) + // return ETN + + }, + + + toString : function(){ + return 'T['+this.p1+', '+this.p2+', slope='+this.slope.toFixed(3)+']'; + } +}); diff --git a/src/tanks/map/pathing/map-searching.cjs b/src/tanks/map/pathing/map-searching.cjs index 1650944..f3cfa86 100644 --- a/src/tanks/map/pathing/map-searching.cjs +++ b/src/tanks/map/pathing/map-searching.cjs @@ -7,7 +7,7 @@ var Y = require('Y').Y , manhattan = vec.manhattan , Map = require('tanks/map/pathing/map').Map -, LinearTrajectory = require('tanks/map/pathing/linear-trajectory').LinearTrajectory +, LinearTrajectory = require('tanks/map/pathing/lineartrajectory').LinearTrajectory , Bullet = require('tanks/thing/bullet').Bullet , _X = 0, _Y = 1 @@ -86,11 +86,11 @@ function nearBulletFilter(agent){ function nearEnemyFilter(agent){ var me = this; // Runs in the context of the 'me' unit; @see this.findNearLike() - return agent.isCombatant && agent.align !== me.align; + return agent.isUnit && agent.align !== me.align; } function nearEnemyInSightFilter(agent){ var me = this; // Runs in the context of the 'me' unit; @see this.findNearLike() - return ( agent.isCombatant && agent.align !== me.align && + return ( agent.isUnit && agent.align !== me.align && new LinearTrajectory(me, me.loc, agent.loc).canSee(agent) ); } diff --git a/src/tanks/thing/bullet.cjs b/src/tanks/thing/bullet.cjs index 3f1a565..fe0381c 100644 --- a/src/tanks/thing/bullet.cjs +++ b/src/tanks/thing/bullet.cjs @@ -13,8 +13,8 @@ var Y = require('Y').Y , stat = require('tanks/effects/stat') , Explosion = require('tanks/fx/explosion').Explosion , Thing = require('tanks/thing/thing').Thing -, LinearTrajectory = require('tanks/map/pathing/linear-trajectory').LinearTrajectory , Traversal = require('tanks/map/pathing/traversal').Traversal +, LinearTrajectory = require('tanks/map/pathing/lineartrajectory').LinearTrajectory , @@ -35,7 +35,8 @@ Thing.subclass('Bullet', { // Instance blocking : BoundsType.BLOCKING, - isRenderable : true, + + isCombatant : true, isProjectile : true, bounces : 0, @@ -44,6 +45,7 @@ Thing.subclass('Bullet', { width : 6, height : 6, + isRenderable : true, color: '#FFF6AE', stats : { diff --git a/src/tanks/thing/index.cjs b/src/tanks/thing/index.cjs index d4fd8a5..b6bf07d 100644 --- a/src/tanks/thing/index.cjs +++ b/src/tanks/thing/index.cjs @@ -6,7 +6,7 @@ var Y = require('Y').Y , tank = require('tanks/thing/tank') , thing = require('tanks/thing/thing') , tower = require('tanks/thing/tower') -// , unit = require('tanks/thing/unit') +, unit = require('tanks/thing/unit') ; Y.core.extend(exports, { 'Bullet' : bullet.Bullet, @@ -16,5 +16,5 @@ Y.core.extend(exports, { 'Tank' : tank.Tank, 'Thing' : thing.Thing, 'Tower' : tower.Tower, - // 'Unit' : unit.Unit + 'Unit' : unit.Unit }); diff --git a/src/tanks/thing/shield.cjs b/src/tanks/thing/shield.cjs index b2a00b9..fad604b 100644 --- a/src/tanks/thing/shield.cjs +++ b/src/tanks/thing/shield.cjs @@ -20,6 +20,7 @@ Component.subclass('Shield', { // Instance blocking : BoundsType.IRREGULAR, // Need to allow shields etc to passthrough like-aligned units + isCombatant : true, isComponent : true, isShield : true, diff --git a/src/tanks/thing/tank.cjs b/src/tanks/thing/tank.cjs index 1cdca54..bed6e6d 100644 --- a/src/tanks/thing/tank.cjs +++ b/src/tanks/thing/tank.cjs @@ -12,9 +12,9 @@ var Y = require('Y').Y , constants = require('tanks/constants') , BoundsType = constants.BoundsType , DensityType = constants.DensityType -, LinearTrajectory = require('tanks/map/pathing/linear-trajectory').LinearTrajectory +, LinearTrajectory = require('tanks/map/pathing/lineartrajectory').LinearTrajectory , Traversal = require('tanks/map/pathing/traversal').Traversal -, Thing = require('tanks/thing/thing').Thing +, Unit = require('tanks/thing/unit').Unit , Bullet = require('tanks/thing/bullet').Bullet , Lootable = require('tanks/mixins/lootable').Lootable , Barrel = require('tanks/fx/barrel').Barrel @@ -25,7 +25,7 @@ var Y = require('Y').Y Tank = exports['Tank'] = -Thing.subclass('Tank', function(Tank){ +Unit.subclass('Tank', function(Tank){ Y.core.descriptors(this, { isUnit : true, @@ -76,7 +76,7 @@ Thing.subclass('Tank', function(Tank){ this['init'] = function initTank(align){ - Thing.init.call(this, align); + Unit.init.call(this, align); this.projectile = this.defaultProjectile = Bullet.lookup(this.projectile); this.colors = Y.extend({}, this.colors); this.atkGauge = new CooldownGauge(this.cooldowns.attack, this.width+1,this.height+1); @@ -294,27 +294,6 @@ Thing.subclass('Tank', function(Tank){ }; - this['getTurretLoc'] = - function getTurretLoc(){ - var WIGGLE = 2 - , loc = this.loc - , barrel = this.barrelShape - - , theta = barrel.transform.rotate - , sin = Math.sin(theta), cos = Math.cos(theta) - - // sqrt(2)/2 * (P.width + WIGGLE) - // is max diagonal to ensure we don't overlap with the firing unit - , pw = this.projectile.fn.width - , len = barrel.bbox.width + 0.707*(pw+WIGGLE) - - , x = loc.x + len*cos - , y = loc.y + len*sin - ; - return new Vec(x,y); - }; - - /// Rendering Methods /// @@ -355,8 +334,6 @@ Thing.subclass('Tank', function(Tank){ new Barrel(b.width,b.height, b.originX,b.originY) .appendTo( this.shape ) // have to append early to avoid problems with relative positioning .position(b.x, b.y) - // .position(w2-2, h2-bh/2) - // .origin(2, bh/2) .fill( colors.barrel ) ; return this; @@ -374,12 +351,35 @@ Thing.subclass('Tank', function(Tank){ return this; }; + + this['getTurretLoc'] = + function getTurretLoc(){ + var WIGGLE = 2 + , loc = this.loc + , barrel = this.barrelShape + + , theta = barrel.transform.rotate + , sin = Math.sin(theta), cos = Math.cos(theta) + + // sqrt(2)/2 * (P.width + WIGGLE) + // is max diagonal to ensure we don't overlap with the firing unit + , pw = this.projectile.fn.width + , len = barrel.bbox.width + 0.707*(pw+WIGGLE) + + , x = loc.x + len*cos + , y = loc.y + len*sin + ; + return new Vec(x,y); + }; + + this['rotateBarrel'] = function rotateBarrel(x,y){ this.barrelShape.rotate(this.angleTo(x,y)); return this; }; + // FIXME: delegate to Barrel this['rotateBarrelRelPage'] = function rotateBarrelRelPage(pageX, pageY){ var shape = this.shape diff --git a/src/tanks/thing/thing.cjs b/src/tanks/thing/thing.cjs index 9a04e02..4982eea 100644 --- a/src/tanks/thing/thing.cjs +++ b/src/tanks/thing/thing.cjs @@ -64,10 +64,11 @@ new evt.Class('Thing', { isThing : true, isUnit : false, isCombatant : false, - isWall : false, isProjectile : false, + isWall : false, isAccessory : false, isComponent : false, + isShield : false, isActive : true, // Agent takes actions? isRenderable : false, // Agent will present itself for rendering when ready // FIXME: stupid hack diff --git a/src/tanks/thing/tower.cjs b/src/tanks/thing/tower.cjs index 393dc7d..b8ca0cc 100644 --- a/src/tanks/thing/tower.cjs +++ b/src/tanks/thing/tower.cjs @@ -11,9 +11,9 @@ var Y = require('Y').Y , constants = require('tanks/constants') , BoundsType = constants.BoundsType , DensityType = constants.DensityType -, LinearTrajectory = require('tanks/map/pathing/linear-trajectory').LinearTrajectory +, LinearTrajectory = require('tanks/map/pathing/lineartrajectory').LinearTrajectory , Traversal = require('tanks/map/pathing/traversal').Traversal -, Thing = require('tanks/thing/thing').Thing +, Unit = require('tanks/thing/unit').Unit , Bullet = require('tanks/thing/bullet').Bullet , Lootable = require('tanks/mixins/lootable').Lootable , Barrel = require('tanks/fx/barrel').Barrel @@ -24,7 +24,7 @@ var Y = require('Y').Y Tower = exports['Tower'] = -Thing.subclass('Tower', function(Tower){ +Unit.subclass('Tower', function(Tower){ Y.core.descriptors(this, { isCombatant : true, @@ -67,7 +67,7 @@ Thing.subclass('Tower', function(Tower){ this['init'] = function initTower(align){ - Thing.init.call(this, align); + Unit.init.call(this, align); this.projectile = this.defaultProjectile = Bullet.lookup(this.projectile); this.colors = Y.extend({}, this.colors); this.atkGauge = new CooldownGauge(this.cooldowns.attack, this.width+1,this.height+1); @@ -211,9 +211,7 @@ Thing.subclass('Tower', function(Tower){ if (this.shape) this.shape.remove(); var colors = this.colors - , w = this.width, w2 = w/2 - , h = this.height, h2 = h/2 - , r = w / 2 + , r = this.width / 2 ; this.shape = @@ -233,9 +231,8 @@ Thing.subclass('Tower', function(Tower){ new Barrel(b.width,b.height, b.originX,b.originY) .appendTo( this.shape ) // have to append early to avoid problems with relative positioning .position(b.x, b.y) - // .position(w2-2, h2-bh/2) - // .origin(2, bh/2) - .fill( colors.barrel ) ; + .fill( colors.barrel ) + ; return this; }; diff --git a/src/tanks/thing/unit.cjs b/src/tanks/thing/unit.cjs index e69de29..ea00ed2 100644 --- a/src/tanks/thing/unit.cjs +++ b/src/tanks/thing/unit.cjs @@ -0,0 +1,38 @@ +var Y = require('Y').Y +, Thing = require('tanks/thing/thing').Thing +, LinearTrajectory = require('tanks/map/pathing/lineartrajectory').LinearTrajectory +, Traversal = require('tanks/map/pathing/traversal').Traversal +, + +Unit = +exports['Unit'] = +Thing.subclass('Unit', { + isUnit : true, + isCombatant : true, + + nShots : 0, + + + init : function initUnit(align){ + Thing.init.call(this, align); + }, + + ableToShoot : function ableToShoot(){ + return this.nShots < this.stats.shots.val && this.cooldowns.attack.ready; + }, + + move : function move(x,y){ + if (x instanceof Array) { y=x[_Y]; x=x[_X]; } + + var loc = this.loc; + this.trajectory = new LinearTrajectory(this, loc.x,loc.y, x,y, this.movePerMs()); + + var tvsl = new Traversal(this) + , to = tvsl.traverse(this.elapsed, x,y) ; + + this.game.moveThingTo(this, to.x,to.y); + + return this; + } +}) +; -- 1.7.0.4