Moves pathmap test back. Adds collisions to player tank.
authordsc <david.schoonover@gmail.com>
Wed, 17 Nov 2010 07:41:13 +0000 (23:41 -0800)
committerdsc <david.schoonover@gmail.com>
Wed, 17 Nov 2010 07:41:13 +0000 (23:41 -0800)
notes.md
src/portal/layer.js
src/portal/math/oldline.js [deleted file]
src/tanks/config.js
src/tanks/main.js
src/tanks/map/collision.js
src/tanks/map/loc.js
src/tanks/map/pathmap.js
src/tanks/map/trajectory.js
src/tanks/ui/player.js

index 4961760..26c0f5a 100644 (file)
--- a/notes.md
+++ b/notes.md
@@ -1,10 +1,4 @@
-- use unit vectors for trajectories
---> use matrix math for reflections
-- incremental calls to move
-- collision object for recalculating pathing
-
 # Bugs
-- Have move() do incremental calls (consuming elapsed time? distance?) if a push results in a move of x or y larger than the bounding box.
 
 # TODOs
 - Move game objects into namespace `tanks`
@@ -15,3 +9,6 @@
 # Notes
 - TODO Replace *2 and /2 with shifts at compile-time
 - Clipping will suck (masking is easy -- overflow:hidden)
+- Should use unit vectors for trajectories?
+--> matrix math for reflections?
+
index ebf2f50..bc8bf6c 100644 (file)
@@ -221,7 +221,7 @@ Layer = new Y.Class('Layer', {
         // if (pos.left !== undefined)  pos.left -= this.offsetX;
         // if (pos.top  !== undefined)  pos.top  -= this.offsetY;
         
-        this.boundingBox = this.boundingBox.moveTo(pos.left,pos.top);
+        this.boundingBox = this.boundingBox.add(pos.left,pos.top);
         this.loc = this.boundingBox.p1;
         this.css(pos);
         return this;
diff --git a/src/portal/math/oldline.js b/src/portal/math/oldline.js
deleted file mode 100644 (file)
index b13b4bf..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-(function(){
-
-var 
-HALF_PI = Math.PI/2,
-SIN_HALF_PI = Math.sin(HALF_PI),
-COS_HALF_PI = Math.cos(HALF_PI);
-
-
-/**
- * A line in the cartesian plane.
- */
-math.Line = new Y.Class('Line', math.Vec, {
-    
-    init : function initLine(x1,y1, x2,y2, tdist){
-        this.x1 = x1; this.y1 = y1;
-        this.x2 = x2; this.y2 = y2;
-        
-        var xdelta = x2-x1, ydelta = y2-y1
-        ,    m = this.slope  =  ydelta/xdelta
-        ,   yi = this.yint   = -x1*m + y1
-        ,   xi = this.xint   = -y1/m + x1
-        ;
-        math.Vec.init.call(this, xdelta, ydelta);
-        
-        this.p1 = new math.Vec(x1,y1);
-        this.p2 = new math.Vec(x2,y2);
-        
-        this.theta = Math.atan2(ydelta, xdelta);
-        this._cos  = Math.cos(this.theta);
-        this._sin  = Math.sin(this.theta);
-        
-        this.setTScale(tdist);
-    },
-    
-    clone : function clone(){
-        return new math.Line(this.x1,this.y1, this.x2,this.y2, this.tdist);
-    },
-    
-    equals : function equals(line){
-        return ( this.slope === line.slope
-            && this.x1 === line.x1 && this.y1 === line.y1
-            && this.x2 === line.x2 && this.y2 === line.y2 );
-    },
-    
-    intersects : function intersects(x,y){
-        var o = x;
-        if (o instanceof math.Line)
-            return this.slope !== o.slope || this.equals(o);
-        
-        if (o instanceof math.Vec) {
-            x = o.x;
-            y = o.y;
-        }
-        return this.calcY(x) === y;
-    },
-    
-    isWithin : function isWithin(pt, w,h){
-        if ( !Y.isNumber(w) ){
-            h = w.height; w = w.width;
-        }
-        var dw = Math.abs(this.calcX(pt.y) - pt.x)
-        ,   dh = Math.abs(this.calcY(pt.x) - pt.y) ;
-        return dw <= w || dh <= h ;
-    },
-    
-    setTScale : function setTScale(tdist){
-        if (tdist) {
-            this.tdist = tdist;
-            this.pa = tdist * this._cos;
-            this.pb = tdist * this._sin;
-        } else {
-            this.tdist = this.y / this._sin;
-            this.pa = this.x;
-            this.pb = this.y;
-        }
-        return this;
-    },
-    
-    parametric : function parametric(t){
-        return new math.Vec( this.x1 + t*this.pa ,
-                             this.y1 + t*this.pb );
-    },
-    
-    pointAtX : function pointAtX(x){
-        return new math.Vec(x, this.calcY(x));
-    },
-    
-    pointAtY : function pointAtY(y){
-        return new math.Vec(this.calcX(y), y);
-    },
-    
-    near : function near(x,y){
-        if ( !isFinite(this.slope) )
-            return this.pointAtY(y);
-        else
-            return this.pointAtX(x);
-    },
-    
-    calcY : function calcY(x){
-        return (x === this.xint ? 0 : x*this.slope + this.yint);
-    },
-    
-    calcX : function calcX(y){
-        return (y === this.yint ? 0 : y/this.slope + this.xint);
-    },
-    
-    base : function base(){
-        if (!this._base)
-            this._base = new math.Line(0,0, this.x,this.y);
-        return this._base;
-    },
-    
-    tangent : function tangent(at){
-        var slope = this.slope;
-        
-        if ( slope === 0 )
-            return new math.Line(at.x,at.y, at.x,at.y+1, this.tdist);
-        
-        if ( !isFinite(slope) )
-            return new math.Line(at.x,at.y, at.x+1,at.y, this.tdist);
-        
-        var x1 = at.x, y1 = at.y
-        ,   x2 = at.x - at.y + (at.y !== this.y1 ? this.y1 : this.y2)
-        ,   y2 = at.y + at.x - (at.x !== this.x1 ? this.x1 : this.x2) ;
-        return new math.Line(x1,y1, x2,y2, this.tdist);
-    },
-    
-    toString : function toString(){
-        return '['+this.p1+', '+this.p2+', slope='+this.slope.toFixed(3)+']';
-    }
-    
-});
-
-})();
\ No newline at end of file
index 7092331..97513b4 100644 (file)
@@ -5,6 +5,6 @@ tanks.config = {
         traceTrajectories : true
     },
     debug : {
-        projectiles : 1
+        projectiles : 2
     }
 };
\ No newline at end of file
index 3d3035b..6764658 100644 (file)
@@ -1,10 +1,7 @@
 var btank   = null
 ,   bullets = new Y.YArray()
 ;
-
-
 (function(){
-
 jQuery(main);
 
 
@@ -27,8 +24,8 @@ function main(){
     new Player(LBT, T);
     
     setupUI();
-    B = bullets.attr(0);
-    T = B.trajectory;
+    // B = bullets.attr(0);
+    // T = B.trajectory;
 }
 
 
index b1694f2..ee4ea47 100644 (file)
@@ -1,5 +1,7 @@
 Collision = new Y.Class('Collision', {
     
-    
+    init : function initCollision(line, to){
+        
+    },
     
 });
\ No newline at end of file
index edc840a..4178962 100644 (file)
@@ -186,7 +186,7 @@ Loc.BoundingBox = new Y.Class('BoundingBox', Loc.Rect, {
     
     attr : Y.attr.methodize(),
     
-    moveTo : function moveTo(x,y){
+    add : function add(x,y){
         return new Loc.BoundingBox(x,y, x+this.width,y+this.height);
     },
     
index 9aeb818..6d43b88 100644 (file)
@@ -38,84 +38,60 @@ PathMap = new Y.Class('PathMap', QuadTree, {
         return obj;
     },
     
-    attemptMove : function attemptMove(obj, trj, to){
-        var wall, blocker, what
-        ,   clamp = math.clamp
-        ,   bb = obj.boundingBox
-        ,   minW = 2,            minH = 2
-        ,   maxW = this.width-2, maxH = this.height-2
-        ,   bw = bb.width,       bh = bb.height
-        ,   x1 = to.x,           y1 = to.y
-        ,   x2 = x1+bw,          y2 = y1+bh
+    moveBlocked : function moveBlocked(agent, trj, to){
+        var blockers, blocker, msg
+        ,   side = null
+        
+        ,   bb = agent.boundingBox
+        ,   bw = bb.width,          bh = bb.height
+        ,   offX = agent.offsetX,   offY = agent.offsetY
+        
+        ,   x1 = to.x+offX,         y1 = to.y+offY
+        ,   x2 = x1+bw,             y2 = y1+bh
         ;
         
-        // Check for collision with the walls to prevent teleporting units
-        // if (x1 < minW || x2 > maxW || y1 < minH || y2 > maxH){
-        //     blocker = this.game.level;
-        //     what = 'LevelWall on the ';
-        //     
-        //     if (x1 < minW) {
-        //         what = 'left';
-        //         wall = this.walls.left;
-        //         to = trj.pointAtX(minW);
-        //     
-        //     } else if (x2 > maxW) {
-        //         what = 'right';
-        //         wall = this.walls.right;
-        //         to = trj.pointAtX(maxW-bw);
-        //     
-        //     } else if (y1 < minH) {
-        //         what = 'top';
-        //         wall = this.walls.top;
-        //         to = trj.pointAtY(minH);
-        //     
-        //     } else if (y2 > maxH) {
-        //         what = 'bottom';
-        //         wall = this.walls.bottom;
-        //         to = trj.pointAtY(maxH-bh);
-        //     }
-        //     
-        //     what += ' at '+wall;
-        //     return { 'ok':!wall, 'to':to, 'wall':wall, 'blocker':blocker, 'what':what };
-        // }
+        blockers = this.get(x1,y1, x2,y2).remove(agent).end();
+        blocker = blockers[0];
         
-        // Check for pathmap collisions
-        var blockers = this.get(x1,y1, x2,y2).remove(obj);
-        if (blockers.size() > 1){
-            console.log('multiple blockers! '+blockers._o.slice(0));
-            return { 'ok':false, 'corner':true };
-        }
+        // Not blocked
+        if (!blocker) return false;
         
-        blocker = blockers.shift();
-        if ( blocker ) {
-            what = blocker+' on the ';
+        // 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) {
-                what += 'left';
-                wall = B.sides.left;
-                to   = trj.pointAtX(B.x1-bw);
+                msg += 'left';
+                side = B.sides.left;
+                to   = trj.pointAtX(B.x1-bw-offX-1);
+                
             } else if (bb.x1 >= B.x2 && x1 < B.x2) {
-                what += 'right';
-                wall = B.sides.right;
-                to   = trj.pointAtX(B.x2);
+                msg += 'right';
+                side = B.sides.right;
+                to   = trj.pointAtX(B.x2-offX+1);
+                
             } else if (bb.y2 <= B.y1 && y2 > B.y1) {
-                what += 'top';
-                wall = B.sides.top;
-                to   = trj.pointAtY(B.y1-bh);
+                msg += 'top';
+                side = B.sides.top;
+                to   = trj.pointAtY(B.y1-bh-offY-1);
+                
             } else if (bb.y1 >= B.y2 && y1 < B.y2) {
-                what += 'bottom';
-                wall = B.sides.bottom;
-                to   = trj.pointAtY(B.y2);
+                msg += 'bottom';
+                side = B.sides.bottom;
+                to   = trj.pointAtY(B.y2-offY+1);
             }
+            
+            msg += ' side';
         }
         
-        // to.setXY(
-        //     clamp(to.x, 2,maxW-2),
-        //     clamp(to.y, 2,maxH-2) );
-        
-        what += ' at '+wall;
-        return { 'ok':!wall, 'to':to, 'wall':wall, 'blocker':blocker, 'what':what };
+        return { 'msg':msg, 'blockers':blockers, 'side':side, 'to':to };
     },
     
     
index fae22dd..546354b 100644 (file)
@@ -51,61 +51,30 @@ Trajectory = new Y.Class('Trajectory', math.Line, {
         ;
         
         do {
-            var t, to, ng, x1,y1, x2,y2, bs, blocker, blockers, what, wall;
+            var t, to, _to, ng
+            ,   test, blockers, side
+            ;
             
             t = Math.min(this.tBound, dt);
             dt -= t;
             this.elapsed += t;
             
-            var _to = to = this.parametric(this.elapsed);
-            x1 = to.x+offX; y1 = to.y+offY;
-            x2 = x1+bw;     y2 = y1+bh;
+            _to  = to = this.parametric(this.elapsed);
+            test = this.pathmap.moveBlocked(o, this, to);
             
-            bs = this.pathmap.get(x1,y1, x2,y2).remove(o).end();
-            blocker = bs[0];
-            
-            // Literal corner case :P
-            if (bs.length > 1) {
-                console.log('multiple blockers! '+bs.slice(0));
-                what = 'corner of '+bs.slice(0);
-                to = loc;
-                ng = this.p1; // XXX: recalculate?
-                
-            // Normal reflection against one line
-            } else if ( blocker ) {
-                what = blocker+' on the ';
+            // Blocked! Reflect trajectory
+            if ( test ) {
+                to       = test.to;
+                side     = test.side;
+                blockers = test.blockers;
                 
-                var B = blocker.boundingBox;
-                if (bb.x2 <= B.x1 && x2 > B.x1) {
-                    what += 'left';
-                    wall = B.sides.left;
-                    to   = this.pointAtX(B.x1-bw-offX-1);
-                    
-                } else if (bb.x1 >= B.x2 && x1 < B.x2) {
-                    what += 'right';
-                    wall = B.sides.right;
-                    to   = this.pointAtX(B.x2-offX+1);
-                    
-                } else if (bb.y2 <= B.y1 && y2 > B.y1) {
-                    what += 'top';
-                    wall = B.sides.top;
-                    to   = this.pointAtY(B.y1-bh-offY-1);
-                    
-                } else if (bb.y1 >= B.y2 && y1 < B.y2) {
-                    what += 'bottom';
-                    wall = B.sides.bottom;
-                    to   = this.pointAtY(B.y2-offY+1);
+                if ( blockers.length > 1 ) {
+                    to = loc;
+                    ng = this.p1; // XXX: recalculate?
+                } else {
+                    ng = math.reflect(this.p2, side);
                 }
                 
-                ng = math.reflect(this.p2, wall);
-            }
-            
-            // No collision: don't change trajectory
-            if (!ng) {
-                this.depth = 0;
-                
-            // New goal-point: change trajectory
-            } else {
                 var og = this.p2;
                 this.reset(to.x,to.y, ng.x,ng.y);
                 
@@ -113,7 +82,7 @@ Trajectory = new Y.Class('Trajectory', math.Line, {
                     console.log([
                         '['+TICKS+':'+_dt+' ('+this.depth+')] '+this.owner+' reflected!',
                         '  wanted:  '+_to+' x ('+(_to.x+bw)+','+(_to.y+bh)+')',
-                        '  blocker: '+what,
+                        '  blocker: '+test.msg,
                         '  old:',
                         '    loc:   '+bb.p1,
                         '    goal:  '+og,
@@ -128,7 +97,6 @@ Trajectory = new Y.Class('Trajectory', math.Line, {
                 ng = null;
                 
                 this.owner.render(this.game.level);
-                // this.owner.render(this.game.level).draw();
                 
                 if (this.depth++ < 5) {
                     // dt += t; // do this step over again
@@ -139,6 +107,11 @@ Trajectory = new Y.Class('Trajectory', math.Line, {
                     LBT.stop();
                     throw new Error('Reflection limit reached!');
                 }
+                
+                
+            // No collision: don't change trajectory
+            } else {
+                this.depth = 0;
             }
             
         } while (dt > 0);
index 1f1d4f4..06c412f 100644 (file)
@@ -4,7 +4,7 @@ Action = {
     
     moveDirFromKey : {
         37: "left", 38: "up", 39: "right", 40: "down",
-        65: "left", 87: "up", 83: "right", 68: "down"
+        65: "left", 87: "up", 68: "right", 83: "down"
     }
 };
 
@@ -22,8 +22,9 @@ Player = new Y.Class('Player', {
         
         this.activeKeys = new Y.YArray();
         
-        this.game = game;
         this.tank = tank;
+        this.game = game;
+        this.pathmap = game.pathmap;
         tank.act = this.act; // Override tank actions with player control
         tank.move = this.move;
         
@@ -51,7 +52,9 @@ Player = new Y.Class('Player', {
     },
     
     keydown : function keydown(evt){
-        this.activeKeys.push(evt.which+'');
+        var k = evt.which+'';
+        if ( !this.activeKeys.has(k) )
+            this.activeKeys.push(k);
         this.updateMeta(evt);
     },
     
@@ -93,8 +96,16 @@ Player = new Y.Class('Player', {
     
     move : function move(dir){
         var tank  = this.tank
-        ,   toLoc = tank.loc.moveByDir(dir, (tank.stats.move * SQUARETH));
-        this.game.moveAgentTo(tank, toLoc.x, toLoc.y);
+        ,   toLoc = tank.loc.moveByDir(dir, (tank.stats.move * SQUARETH))
+        
+        ,   x = toLoc.x, y = toLoc.y
+        ,   bb = tank.boundingBox.add(x,y)
+        
+        ,   blockers = this.pathmap.get(bb.x1,bb.y1, bb.x2,bb.y2).remove(tank)
+        ;
+        
+        if ( !blockers.size() )
+            this.game.moveAgentTo(tank, x,y);
     }
     
 });
\ No newline at end of file