"src/tanks/globals.js",
"src/tanks/util/calc.js",
- "src/tanks/util/pathmap.js",
"src/tanks/util/grid.js",
+ "src/tanks/util/pathmap.js",
+
"src/tanks/game/game.js",
"src/tanks/game/map.js",
- "src/tanks/unit/thing.js",
- "src/tanks/unit/tank.js",
+
+ "src/tanks/thing/thing.js",
+ "src/tanks/thing/bullet.js",
+ "src/tanks/thing/tank.js",
"src/tanks/game/player.js",
+
"src/tanks/lttl.js",
"src/tanks/ui.js"
+# Bugs
+
+# TODOs
+- Move game objects into namespace `tanks`
+- Move portal into namespace (ideas: `portal`, canvas tools... `easel`, or `ezl`)
+
+
+# Notes
- Clipping is going to suck
-- TODO Replace *2 and /2 with shifts at compile-time
\ No newline at end of file
+- TODO Replace *2 and /2 with shifts at compile-time
/**
- * A line.
+ * A line in the cartesian plane.
*/
math.Line = new Y.Class('Line', math.Vec, {
init : function init(x1,y1, x2,y2, t){
- this.t = 1/(t || 1);
this.x1 = x1; this.y1 = y1; this.p1 = new math.Vec(x1,y1);
this.x2 = x2; this.y2 = y2; this.p2 = new math.Vec(x2,y2);
, yi = this.yint = -x1*m + y1
, xi = this.xint = -y1/m + x1
;
-
- this.pa = this.t*xdelta;
- this.pb = this.t*ydelta
math.Vec.init.call(this, xdelta, ydelta);
+ this.setT(t);
+ },
+
+ setT : function setT(t){
+ this.t = 1/(t || 1);
+ this.pa = this.t*this.x;
+ this.pb = this.t*this.y;
+ return this;
},
pcalc : function parametric(t){
lerp : function lerp(x, a, b) {
return a + x*(b - a);
+ },
+
+ reflect : function reflect(v, line){
+ var dot = math.Vec.dot
+ , basev = math.Vec.difference(v, line.p1);
+ return line.clone()
+ .scale(2 * dot(basev,line) / dot(line,line))
+ .subtract(basev)
+ .add(line.p1);
}
+
};
\ No newline at end of file
lerp : function lerp(x, a, b) {
return new math.Vec( math.lerp(a.x, b.x, x),
- math.lerp(a.y, b.y, x) );
- },
-
- reflect : function reflect(v, line){
- var dot = math.Vec.dot
- , basev = math.Vec.difference(v, line.p1);
- return line.clone()
- .scale(2 * dot(basev,line) / dot(line,line))
- .subtract(basev)
- .add(line.p1);
+ math.lerp(a.y, b.y, x) );
}
});
init : function init(x1,y1, x2,y2, x3,y3){
Polygon.init.call(this, [x1,x2,x3], [y1,y2,y3]);
}
+
});
+++ /dev/null
-Bullet = new Y.Class('Bullet', Thing, {
-
-
-
-});
\ No newline at end of file
/// Common Components of Computation ///
, SECONDTH = ELAPSED / 1000 // Amount of second completed in this tick
-, SQUARETH = REF_SIZE * SECONDTH // Amount of square/second covered in this tick
+, SQUARETH = REF_SIZE * SECONDTH // Amount of square/second covered in this tick
-, PI = Math.PI
-, HALF_PI = PI/2
-, PI_AND_HALF = PI + HALF_PI
-, TWO_PI = PI*2
+, PI = Math.PI
+, HALF_PI = PI/2
+, PI_AND_HALF = PI + HALF_PI
+, TWO_PI = PI*2
;
--- /dev/null
+Bullet = new Y.Class('Bullet', Thing, {
+
+ /*
+ t = time from creation
+ current_t = now - creation_time
+ */
+ /**
+ * @param {tanks.Unit} owner
+ * @param {math.Line} trajectory
+ */
+ init : function initBullet(owner, trajectory){
+ Thing.init.call(this, owner.game, owner.align);
+
+ this.owner = owner;
+ this.trajectory = trajectory;
+ this.creationTime = NOW;
+
+ this.setLocation(trajectory.x1, trajectory.y1);
+ // this.trajectory.setT(this.stats.move*SQUARETH);
+ },
+ blocking : false,
+ creationTime : 0,
+
+ stats : {
+ move : 2.0, // move speed (squares/sec)
+ range : 0.1 // attack range (squares)
+ },
+
+ fillStats : function(){
+ this.stats = Y({},
+ Thing.fillStats(this.owner.stats),
+ Thing.fillStats(this.stats) ).end();
+ },
+
+ createCooldowns : Y.op.nop,
+
+ act : function act(){
+ if (!this.dead)
+ this.move();
+ return this;
+ },
+
+ move : function move(){
+ var to = this.trajectory.pcalc( (NOW-this.creationTime) * REF_SIZE/1000 );
+ this.game.moveAgentTo(this, to.x, to.y);
+ return this;
+ }
+
+});
+
+Y(Bullet).extend({
+
+ fireAt : function fireAt(ProjectileType, owner, target){
+ var oloc = owner.loc
+ , x1 = oloc.x, y1 = oloc.y
+ , x2 = target.x, y2 = target.y
+ ;
+ return new ProjectileType(owner, new math.Line(x1,y1, x2,y2));
+ }
+
+});
\ No newline at end of file
Tank = new Y.Class('Tank', Thing, {
+ projectile : Bullet,
// Bounding box size
width : REF_SIZE*0.7,
},
fireProjectile : function fireProjectile(target){
- var AbilityType = this.projectile
- , p = new AbilityType(this, target);
+ var p = Bullet.fireAt(this.projectile, this, target);
this.bullets.push(p);
this.game.addAgent(p);
return p;
},
move : function move(){
- var toLoc = this.loc.moveByAngle(this.rotation, this.stats.move * SQUARETH);
- this.game.moveAgentTo(this, toLoc.x, toLoc.y);
+ var to = this.loc.moveByAngle(this.rotation, this.stats.move * SQUARETH);
+ this.game.moveAgentTo(this, to.x, to.y);
return this;
},
ctx.scale(PPU, PPU);
points = Y([]);
-line = mkLine(-3,2, 4,7);
+line = mkLine(5,8, 4,7);
addPoint(-5,2);
dragging = false;
function convertLoc(evt){
var off = P.layer.offset()
- , x = (evt.pageX - off.left - w2)/(PPU)
+ , x = (evt.pageX - off.left - w2)/PPU
, y = (evt.pageY - off.top - h2)/PPU * -1;
return new math.Vec(x,y);
}
, c = drawPoint(v, null, '#552F74');
}
- var rv = math.Vec.reflect(c.vec,line)
+ var rv = math.reflect(c.vec,line)
, rc = c.reflected = drawPoint(rv, null, '#F25522');
points.push(c);
}
if (window.p1) p1.remove();
if (window.p2) p2.remove();
- color = color || 'rgba(231,48,117, 0.5)';
+ color = color || 'rgba(231,48,117, 0.5)';
pcolor = pcolor || 'rgba(69,150,255, 1)';
var line = new math.Line(x1,y1, x2,y2, 10);
drawLine(-W/2, line.calcY(-W2), line.calcX(H2), H2, color);
}
function drawLine(x1,y1, x2,y2, color, width){
- ctx.beginPath();
- ctx.lineWidth = width || PX;
- ctx.strokeStyle = color || '#000000';
- ctx.moveTo(x1, -y1);
- ctx.lineTo(x2, -y2);
- ctx.stroke();
- ctx.closePath();
+ if ([x1,y1, x2,y2].some(isNaN)) {
+ throw new Error('Value is NaN!'+'('+x1+','+y1+') ('+x2+','+y2+')');
+ }
+ try {
+ ctx.beginPath();
+ ctx.lineWidth = width || PX;
+ ctx.strokeStyle = color || '#000000';
+ ctx.moveTo(x1, -y1);
+ ctx.lineTo(x2, -y2);
+ ctx.stroke();
+ ctx.closePath();
+ } catch (e) {
+ console.log('drawLine error:', e, '(',x1,y1,')', '(',x2,y2,')');
+ }
}
function drawPoint(x,y, color, r){