AI tanks now dodge
authordsc <david.schoonover@gmail.com>
Fri, 19 Nov 2010 20:50:42 +0000 (12:50 -0800)
committerdsc <david.schoonover@gmail.com>
Fri, 19 Nov 2010 20:50:42 +0000 (12:50 -0800)
src/tanks/main.js
src/tanks/thing/tank.js
src/tanks/thing/thing.js

index 6eccb99..2b26232 100644 (file)
@@ -1,13 +1,17 @@
-var btank   = null
-,   bullets = new Y.YArray()
-;
 (function(){
 jQuery(main);
 
+var btank   = null
+,   bullets = new Y.YArray()
+;
 
+this.main = main;
 function main(){
     var v = $('#viewport');
     
+    if (window.LBT) LBT.stop();
+    v.empty();
+    
     LBT = new tanks.Game();
     ctx = LBT.level.ctx;
     
index d3dfca4..b206889 100644 (file)
@@ -20,11 +20,14 @@ Tank = Thing.subclass('Tank', {
         rotate    : HALF_PI,    // rotation speed (radians/sec)
         
         power     : 1,          // attack power
-        speed     : 1,          // attack cool (sec)
-        shots     : 5           // max projectiles in the air at once
+        speed     : 0.5,        // attack cool (sec)
+        shots     : 4           // max projectiles in the air at once
     },
     
     nShots : 0,
+    currentMove : null,
+    forceCurrentMove : false,
+    currentMoveLimit : -1,
     
     
     init : function init(align){
@@ -41,9 +44,70 @@ Tank = Thing.subclass('Tank', {
         return this.nShots < this.stats.shots && this.cooldowns.attack.ready;
     },
     
+    findClosest : function findClosest(agents){
+        if (!agents || !agents.size())
+            return null;
+        
+        var manhattan = this.game.pathmap.manhattan
+        ,   bb = this.boundingBox, mid = this.midpoint
+        
+        agents.sort(function(a,b){
+            return Y.op.cmp(
+                manhattan(a.loc,mid),
+                manhattan(b.loc,mid) );
+        });
+        
+        return agents.attr(0);
+    },
+    
+    willCollide : function willCollide(bullets, wiggle){
+        wiggle = wiggle || 0;
+        var bb = this.boundingBox, mid = this.midpoint
+        ,   w = (bb.width+wiggle)/2, h = (bb.height+wiggle)/2
+        ;
+        return bullets.filter(function(b){ return !b.dead && b.trajectory.isWithin(mid, w,h); });
+    },
+    
     act : function act(){
+        
+        if ( this.forceCurrentMove && this.forceCurrentMove() && this.currentMoveLimit > NOW ) {
+            this.continueMove();
+            return this;
+        } else
+            this.forceCurrentMove = false;
+        
+        
         // Are we ready to fire?
         if ( this.cannonReady() ) {
+            
+            // Try to shoot down nearby bullets
+            var bs = this.willCollide( this.nearLike(16, Y.is(Bullet)) );
+            if ( bs.size() ) {
+                var b = this.findClosest(bs);
+                
+                // console.log('Incoming! Shoot it down!', b);
+                this.shoot(b.loc.x, b.loc.y);
+                return this;
+            }
+            
+            var bs = this.willCollide( this.nearLike(50, Y.is(Bullet)), 10 );
+            if ( bs.size() ) {
+                var b   = this.findClosest(bs), bs = [b]
+                ,   mid = this.midpoint
+                ,   trj = b.trajectory.tangent(mid)
+                
+                ,   lvl = this.game.level, w = lvl.width, h = lvl.height
+                ,   x   = (mid.x > w/2 ? w : 0)
+                ,   y   = (mid.y > h/2 ? h : 0)
+                ,   to  = this.currentMove = trj.near(x,y);
+                
+                this.forceCurrentMove = function(){ return this.willCollide(bs, 10); };
+                this.currentMoveLimit = NOW + 750;
+                
+                this.move(to.x, to.y);
+                return this;
+            }
+            
             // Try to blow up nearby tanks
             var t = this.nearLike(66, 'Y.is(Tank, _) && _.align !== '+this.align).shift();
             if (t) {
@@ -52,13 +116,6 @@ Tank = Thing.subclass('Tank', {
                 return this;
             }
             
-            // Try to shoot down nearby bullets
-            var b = this.nearLike(15, Y.is(Bullet)).shift();
-            if (b) {
-                // console.log('Incoming! Shoot it down!', b);
-                this.shoot(b.loc.x, b.loc.y);
-                return this;
-            }
         }
         
         // Nothing to shoot at? Move toward something
@@ -68,15 +125,18 @@ Tank = Thing.subclass('Tank', {
     },
     
     continueMove : function continueMove(){
-        if (!this.currentMove)
+        if ( !this.currentMove || this.currentMoveLimit <= NOW )
             this.recalculatePath();
         
         var to = this.currentMove;
         if (!to) return;
         
         this.move(to.x, to.y);
-        if ( this.boundingBox.midpoint().equals(to) )
+        if ( this.midpoint.equals(to) ) {
             this.currentMove = null;
+            this.forceCurrentMove = false;
+            this.currentMoveLimit = -1;
+        }
     },
     
     recalculatePath : function recalculatePath(){
@@ -84,12 +144,17 @@ Tank = Thing.subclass('Tank', {
         ,   pm = this.game.pathmap
         ;
         
+        // this.forceCurrentMove = Y.op.K(true);
+        // this.currentMoveLimit = NOW + 750;
+        this.forceCurrentMove = false;
+        this.currentMoveLimit = -1;
+        
         if (!t) return;
         
         // console.log(this, 'moving toward', t);
-        var end = t.boundingBox.midpoint()
+        var end = t.midpoint
         ,   bb = this.boundingBox
-        ,   mid = bb.midpoint()
+        ,   mid = this.midpoint
         ,   start = mid
         
         ,   path  = this.lastPath = pm.path(start, end, this.id)
index 66bbd78..7cf9418 100644 (file)
@@ -74,7 +74,8 @@ Thing = new Evt.Class('Thing', {
             this.shape.position(x,y);
         
         // this.createBoundingBox(x,y);
-        this.boundingBox = new Loc.BoundingBox(x1,y1, x2,y2);
+        var bb = this.boundingBox = new Loc.BoundingBox(x1,y1, x2,y2);
+        this.midpoint = bb.midpoint();
         
         return this;
     },