BattleTanks

Here is my latest experiment BattleTanks! :player:

Its a simple tank game, done entirely in AS (and compiled using this online compiler cause I don’t have Flash at work). It incorporates a number of AI elements including line of sight calculation and basic obstacle avoidance. The AI is pretty stupid and I’m going to improve on them as soon as I optimize the code some. But enjoy and it was fun to build.

Arrows to move A/D to rotate turrent and S/Space to fire

SWF

Source:


class BattleTanks {
 var tanks;
 var map;
 var count;
 var max_speed;
 var friction;
 var braking;
 var accel;
 var turnspeed;
 var bounce_factor;
 var tankscale;
 var num_enemies;
 var bullet_speed;
 var damage;
 var explosions;
 var num_particles;
 function BattleTanks(path) {
  //define global variable
  defineGlobals(path);
  //generate map
  //map = genMap(40, 40, 25);
  map =  [ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
      [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
      [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
      [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1],
      [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1],
      [1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1],
      [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
      [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
      [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
      [1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
      [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
      [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
      [1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1],
      [1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1],
      [1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1],
      [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
      [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
      [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
      [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
      [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
      [1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1],
      [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
      [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
      [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
      [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
      [1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1],
      [1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1],
      [1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1],
      [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
      [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
      [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
      [1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
      [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
      [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
      [1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1],
      [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1],
      [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1],
      [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
      [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
      [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] ];
  //draw map
  drawMap(map, path);
  //create tanks
  tanks.push(newTank(path, true, map, 3, 3, 90));
  tanks.push(newTank(path, false, map, 37, 3, 180));
  tanks.push(newTank(path, false, map, 37, 37, -90));
  tanks.push(newTank(path, false, map, 3, 37, 0));
 }
 function newTank(target, player, map, x, y, rotate) {
  var ob;
  var ref = this;
  var tank = target.createEmptyMovieClip("tank"+(count++), count);
  //draw the tank graphics
  drawTank(tank);
  createTurret(tank);
  //set position and define basic variable
  tank.sx = x;
  tank.sy = y;
  tank.sr = rotate;
  tank.player = player;
  tank._alpha = 0;
  tank.alive = false;
  tank.die = function() {
   if (this.alive) {
    ref.explode(this);
   }
   this.alive = false;
   this.onEnterFrame = function() {
    if (this._alpha>0) {
     this._alpha -= 7;
    } else {
     this._x = this.sx*10;
     this._y = this.sy*10;
     this._rotation = this.sr;
     this.turret._rotation = 0;
     this.vel = 0;
     ref.calculateTreads(tank);
     //apply key controls if tank is player controlled
     if (player) {
      tank.shot = false;
      tank.onEnterFrame = function() {
       if (this._alpha<100) {
        this._alpha += 5;
       } else {
        this.alive = true;
       }
       ref.calculateTreads(this);
       ref.drawTreads(this);
       this.vel *= ref.friction;
       //get rid of errors caused by decimal anomalies
       this.vel = Math.floor(this.vel*10)/10;
       if (Key.isDown(Key.UP)) {
        //acceleration style 2
        this.vel = Math.min(ref.max_speed, this.vel+ref.accel);
       }
       if (Key.isDown(Key.DOWN)) {
        //acceleration style 2
        this.vel = Math.max(-ref.max_speed, this.vel-ref.accel);
       }
       if (Key.isDown(Key.LEFT)) {
        this._rotation -= ref.turnspeed;
       }
       if (Key.isDown(Key.RIGHT)) {
        this._rotation += ref.turnspeed;
       }
       //turret rotation
       if (Key.isDown(65)) {
        this.turret._rotation += ref.turnspeed;
       }
       if (Key.isDown(68)) {
        this.turret._rotation -= ref.turnspeed;
       }
       //shooting
       if (Key.isDown(Key.SPACE) || Key.isDown(83)) {
        if (this.shot == false) {
         this.shoot();
         this.shot = true;
        }
       } else {
        this.shot = false;
       }
       //movement calculations
       var xmov = Math.cos(this._rotation*(Math.PI/180))*this.vel;
       var ymov = Math.sin(this._rotation*(Math.PI/180))*this.vel;
       //wall collision
       ob = new Object();
       ob.clip = this;
       ob.height = this.body._height/2;
       ob.width = this.body._width/2;
       ob.x = this._x;
       ob.y = this._y;
       ob.xtile = Math.floor(this._x/10);
       ob.ytile = Math.floor(this._y/10);
       //movement
       ref.getCorners(this._x, this._y+ymov, ob);
       if (ymov<0) {
        if (ob.upleft && ob.upright) {
         ob.y += ymov;
        } else {
         ob.y = ob.ytile*10+ob.height;
        }
       }
       if (ymov>0) {
        if (ob.downleft && ob.downright) {
         ob.y += ymov;
        } else {
         ob.y = (ob.ytile+1)*10-ob.height;
        }
       }
       ref.getCorners(this._x+xmov, this._y, ob);
       if (xmov<0) {
        if (ob.upleft && ob.downleft) {
         ob.x += xmov;
        } else {
         ob.x = ob.xtile*10+ob.width;
        }
       } else if (xmov>0) {
        if (ob.upright && ob.downright) {
         ob.x += xmov;
        } else {
         ob.x = (ob.xtile+1)*10-ob.width;
        }
       }
       this._x = ob.x;
       this._y = ob.y;
      }
      ;
     } else {
      this.count = Math.floor(Math.random()*15);
      this.shoot_count = 0;
      this.los = -1;
      this.decel = 0;
      this.mov_angle = this._rotation;
      this.onEnterFrame = function() {
       var xdist, ydist, dist, angle, xam, yam, ca, sa, tx, ty, dif, rot;
       if (this._alpha<100) {
        this._alpha += 5;
       } else {
        this.alive = true;
       }
       this.count++;
       if(this.count > 2999) {
        this.count = 0;
       }
       //draw tread marks
       ref.calculateTreads(this);
       ref.drawTreads(this);
       //calculate current position
       this.scx = Math.floor(this._x/10);
       this.scy = Math.floor(this._y/10);
       ca = Math.cos(this._rotation*(Math.PI/180));
       sa = Math.sin(this._rotation*(Math.PI/180));
       //
       //rotate turret if line of site
       //
       if (ref.tanks[this.los].alive == false) {
        this.los = -1;
       } else {
        this.olos = this.los;
       }
       if (this.los>-1 && this.count % 15 == 0) {
        //calculate line of sight
        xdist = Math.floor(this._x/10)-Math.floor(ref.tanks[this.los]._x/10);
        ydist = Math.floor(this._y/10)-Math.floor(ref.tanks[this.los]._y/10);
        dist = Math.sqrt(xdist*xdist+ydist*ydist);
        angle = Math.atan2(-ydist, -xdist);
        xam = Math.cos(angle)*10;
        yam = Math.sin(angle)*10;
        this.los_angle = angle*(180/Math.PI);
        x = this._x;
        y = this._y;
        for (var i = 0; i<dist; i++) {
         x += xam;
         y += yam;
         if (ref.map[Math.floor(y/10)][Math.floor(x/10)] == 1) {
          this.los = -1;
          break;
         }
        }
       }
       if (this.los == -1 && this.count % 15 == 0) {
        for (var k = 0; k<ref.tanks.length; k++) {
         if (k != this.olos && ref.tanks[k] != this) {
          //calculate line of sight
          xdist = Math.floor(this._x/10)-Math.floor(ref.tanks[k]._x/10);
          ydist = Math.floor(this._y/10)-Math.floor(ref.tanks[k]._y/10);
          dist = Math.sqrt(xdist*xdist+ydist*ydist);
          angle = Math.atan2(-ydist, -xdist);
          xam = Math.cos(angle)*10;
          yam = Math.sin(angle)*10;
          this.los_angle = angle*(180/Math.PI);
          x = this._x;
          y = this._y;
          this.los = k;
          for (var i = 0; i<dist; i++) {
           x += xam;
           y += yam;
           if (ref.map[Math.floor(y/10)][Math.floor(x/10)] == 1) {
            this.los = -1;
            break;
           }
          }
          if (this.los != -1) {
           break;
          }
         }
        }
       }
       if (this.los == -1) {
        this.los_angle = this._rotation;
        this.shoot_count = 0;
       }
       dif = Math.abs(this.turret._rotation+this._rotation-this.los_angle);
       if (dif>3) {
        rot = (this.turret._rotation+this._rotation);
        if (this.los_angle<0) {
         this.los_angle += 360;
        } else if (this.los_angle>360) {
         this.los_angle -= 360;
        }
        if (rot<0) {
         rot += 360;
        } else if (rot>360) {
         rot -= 360;
        }
        dif = this.los_angle-rot;
        if (dif>0) {
         if (dif>ref.turnspeed) {
          this.turret._rotation += ref.turnspeed;
         } else {
          this.turret._rotation += dif+Math.random()*3-1.5;
         }
        } else {
         dif *= -1;
         if (dif>ref.turnspeed) {
          this.turret._rotation -= ref.turnspeed;
         } else {
          this.turret._rotation -= dif+Math.random()*3-1.5;
         }
        }
        if(this.turret._rotation < 0) {
         this.turret._rotation += 360;
        } else if(this.turret._rotation > 360) {
         this.turret._rotation -= 360;
        }
       }
       this.shoot_count++;
       if (dif<15 && this.shoot_count % 5 == 0 && ref.tanks[this.los].alive == true) {
        this.shoot();
       }
       //
       //follow random path
       //
       if (this.los>-1) {
        tx = ref.tanks[this.los]._x;
        ty = ref.tanks[this.los]._y;
        angle = Math.atan2(ty-this._y, tx-this._x)*(180/Math.PI);
        dif = angle-this._rotation;
        if (dif>180) {
         this.reverseAngle();
         this.mov_angle = angle-180;
        } else {
         this.mov_angle = angle;
        }
       } else {
        this.mov_angle += Math.random()*22-11;
       }
       if (Math.abs(this._rotation-this.mov_angle)>1) {
        rot = this._rotation;
        if (this.mov_angle<0) {
         this.mov_angle += 360;
        } else if (this.mov_angle>360) {
         this.mov_angle -= 360;
        }
        if (rot<0) {
         rot += 360;
        } else if (rot>360) {
         rot -= 360;
        }
        dif = this.mov_angle-rot;
        if (dif>0) {
         if (dif>ref.turnspeed) {
          this._rotation += ref.turnspeed;
         } else {
          this._rotation += dif;
         }
        } else {
         dif *= -1;
         if (dif>ref.turnspeed) {
          this._rotation -= ref.turnspeed;
         } else {
          this._rotation -= dif;
         }
        }
        if(this._rotation < 0) {
         this._rotation += 360;
        } else if(this._rotation > 360) {
         this._rotation -= 360;
        }
       }
       //obstacle avoidance
       x = this.rtx;
       y = this.rty;
       this.rcol = 0;
       this.lcol = 0;
       for (var k = 8; k>0; k--) {
        x += ca*4;
        y += sa*4;
        if (ref.map[Math.floor(y/10)][Math.floor(x/10)] == 1) {
         this.rcol = k;
         break;
        }
       }
       x = this.ltx;
       y = this.lty;
       for (var k = 8; k>0; k--) {
        x += ca*3;
        y += sa*3;
        if (ref.map[Math.floor(y/10)][Math.floor(x/10)] == 1) {
         this.lcol = k;
         break;
        }
       }
       if(this.rcol > 0 && this.lcol > 0) {
        if(this.col_count++ > 40) {
         this.reverseDirection();
         this.col_count = 0;
        }
       } else {
        this.decel = 0;
        this.col_count = 0;
       }
       if (this.rcol>0) {
        this._rotation += ref.turnspeed*this.rcol*1.4;
        this.mov_angle = this._rotation;
        this.decel += .1;
       }
       if (this.lcol>0) {
        this._rotation -= ref.turnspeed*this.lcol*1.4;
        this.mov_angle = this._rotation;
        this.decel += .1;
       }
       this.vel = Math.min(ref.max_speed, this.vel+ref.accel+this.decel);
       //
       //rotation/movement
       //
       //movement
       //movement calculations
       this.vel *= ref.friction;
       this.vel = Math.floor(this.vel*10)/10;
       var xmov = ca*this.vel;
       var ymov = sa*this.vel;
       //wall collision
       ob = new Object();
       ob.clip = this;
       ob.height = this.body._height/2;
       ob.width = this.body._width/2;
       ob.x = this._x;
       ob.y = this._y;
       ob.xtile = Math.floor(this._x/10);
       ob.ytile = Math.floor(this._y/10);
       //movement
       ref.getCorners(this._x, this._y+ymov, ob);
       if (ymov<0) {
        if (ob.upleft && ob.upright) {
         ob.y += ymov;
        } else {
         ob.y = ob.ytile*10+ob.height+1;
         this.collide();
        }
       }
       if (ymov>0) {
        if (ob.downleft && ob.downright) {
         ob.y += ymov;
        } else {
         ob.y = (ob.ytile+1)*10-ob.height-1;
         this.collide();
        }
       }
       ref.getCorners(this._x+xmov, this._y, ob);
       if (xmov<0) {
        if (ob.upleft && ob.downleft) {
         ob.x += xmov;
        } else {
         ob.x = ob.xtile*10+ob.width+1;
         this.collide();
        }
       } else if (xmov>0) {
        if (ob.upright && ob.downright) {
         ob.x += xmov;
        } else {
         ob.x = (ob.xtile+1)*10-ob.width-1;
         this.collide();
        }
       }
       this._x = ob.x;
       this._y = ob.y;
      }
      ;
      tank.collide = function() {
       //this.reverseDirection();
      }
      ;
      tank.reverseDirection = function() {
       this._rotation += 180;
       this.turret._rotation += 180;
       this.mov_angle += 180+Math.random()*90-45;
       ref.calculateTreads(this);
      }
      ;
     }
     tank.shoot = function() {
      var bullet = this._parent.createEmptyMovieClip("bullet"+(ref.count++), ref.count);
      ref.elevateTankDepth();
      var angle = this.turret._rotation+this._rotation;
      var ca = Math.cos(angle*(Math.PI/180));
      var sa = Math.sin(angle*(Math.PI/180));
      bullet._x = ca*9+this._x;
      bullet._y = sa*9+this._y;
      bullet.xspeed = ca*ref.bullet_speed;
      bullet.yspeed = sa*ref.bullet_speed;
      bullet._rotation = angle;
      bullet.parent = this;
      ref.drawBox(bullet, 1, 1, 0, 0, 0x000000);
      bullet.onEnterFrame = function() {
       this._x += this.xspeed;
       this._y += this.yspeed;
       if (ref.map[Math.floor(this._y/10)][Math.floor(this._x/10)] == 1 || this._x>400 || this._x<0 || this._y>400 || this._y<0) {
        this.removeMovieClip();
       } else {
        for (var i in ref.tanks) {
         if (ref.tanks*.hitTest(this) && ref.tanks* != this.parent && ref.tanks*.alive) {
          ref.tanks*.die();
          this.removeMovieClip();
         }
        }
       }
      }
      ;
     }
     ;
    }
   }
   ;
  }
  ;
  tank.die();
  return tank;
 }
 function isOpen(x, y) {
  var open = true;
  if (map[y][x+1] != 0 || map[y+1][x] != 0 || map[y+1][x+1] != 0) {
   open = false;
  }
  return open;
 }
 function calcTDist(ob, x, y) {
  return Math.abs(ob.x-x)+Math.abs(ob.y-y);
 }
 function inArrayXY(arr, x, y) {
  for (var i in arr) {
   if (arr*.x == x && arr*.y == y) {
    return i;
   }
  }
  return -1;
 }
 function elevateTankDepth() {
  for (var i = 0; i<tanks.length; i++) {
   tanks*.swapDepths(count-(i+1));
  }
 }
 function drawTreads(tank) {
  var tread = tank._parent.createEmptyMovieClip("tread"+(count++), count);
  elevateTankDepth();
  tread.lineStyle(0, 0x000000, 100);
  tread._alpha = 30;
  tread.moveTo(tank.ortx, tank.orty);
  tread.lineTo(tank.rtx, tank.rty);
  tread.moveTo(tank.oltx, tank.olty);
  tread.lineTo(tank.ltx, tank.lty);
  tread.onEnterFrame = function() {
   this._alpha -= .15;
   if (this._alpha<3) {
    this.removeMovieClip();
   }
  }
  ;
 }
 function calculateTreads(tank) {
  tank.ortx = tank.rtx;
  tank.orty = tank.rty;
  tank.oltx = tank.ltx;
  tank.olty = tank.lty;
  tank.rtx = Math.cos((tank._rotation-90)*(Math.PI/180))*(3*tankscale)+tank._x;
  tank.rty = Math.sin((tank._rotation-90)*(Math.PI/180))*(3*tankscale)+tank._y;
  tank.ltx = Math.cos((tank._rotation-90)*(Math.PI/180))*(-3*tankscale)+tank._x;
  tank.lty = Math.sin((tank._rotation-90)*(Math.PI/180))*(-3*tankscale)+tank._y;
 }
 function getCorners(x, y, ob) {
  //var bounds = ob.clip.getBounds();
  ob.downY = Math.floor((y+ob.height-1)/10);
  ob.upY = Math.floor((y-ob.height)/10);
  ob.leftX = Math.floor((x-ob.width)/10);
  ob.rightX = Math.floor((x+ob.width-1)/10);
  //check if they are walls
  ob.upleft = (map[ob.upY][ob.leftX] == 0);
  ob.downleft = (map[ob.downY][ob.leftX] == 0);
  ob.upright = (map[ob.upY][ob.rightX] == 0);
  ob.downright = (map[ob.downY][ob.rightX] == 0);
 }
 function drawTank(tank) {
  var target = tank.createEmptyMovieClip("body", 1);
  target._xscale = target._yscale=100*tankscale;
  target._x = -(5*tankscale);
  target._y = -(4.5*tankscale);
  target.lineStyle(1, 0x000000, 100);
  target.moveTo(1, 0);
  target.lineTo(9, 0);
  target.moveTo(0, 1);
  target.lineTo(10, 1);
  target.moveTo(1, 2);
  target.lineTo(1, 7);
  target.moveTo(9, 2);
  target.lineTo(9, 7);
  target.moveTo(0, 8);
  target.lineTo(10, 8);
  target.moveTo(1, 9);
  target.lineTo(9, 9);
  target.lineStyle(1, 0xFFFFFF, 100);
  for (var i = 2; i<9; i++) {
   target.moveTo(i, 2);
   target.lineTo(i, 7);
  }
 }
 function createTurret(tank) {
  var turret = tank.createEmptyMovieClip("turret", 2);
  var target = turret.createEmptyMovieClip("graphics", 1);
  var shot_exit = target.createEmptyMovieClip("shot_exit", 1);
  shot_exit._x = 9;
  shot_exit._y = 2;
  target._xscale = target._yscale=100*tankscale;
  target._x = -(1.5*tankscale);
  target._y = -(2*tankscale);
  target.lineStyle(1, 0x000000, 100);
  target.moveTo(0, 1);
  target.lineTo(0, 3);
  target.moveTo(1, 0);
  target.lineTo(2, 0);
  target.moveTo(3, 1);
  target.lineTo(3, 3);
  target.moveTo(1, 4);
  target.lineTo(2, 4);
  target.moveTo(3, 2);
  target.lineTo(9, 2);
 }
 function explode(tank) {
  if (explosions) {
   var expl = tank._parent.createEmptyMovieClip("explode"+(count++), count);
   var part;
   var ref = this;
   var i;
   part = expl.createEmptyMovieClip("outline", 0);
   part._x = tank._x;
   part._y = tank._y;
   part.lineStyle(0, 0x000000, 50);
   part.moveTo(10, 0);
   for (i = 0;i<=7;i++) {
    part.curveTo(0, 0, Math.cos(i*0.89)*10, Math.sin(i*0.89)*10);
   }
   part.onEnterFrame = function() {
    this._alpha -= 2;
    if(this._alpha <= 0) {
     this._parent.removeMovieClip();
    }
   }
   for (i = 1; i<num_particles; i++) {
    part = expl.createEmptyMovieClip("particle"+i, i);
    var angle = Math.random()*2*Math.PI;
    var ca = Math.cos(angle);
    var sa = Math.sin(angle);
    part._x = tank._x;
    part._y = tank._y;
    var vel = Math.random()*3-1.5;
    part.xspeed = ca*vel;
    part.yspeed = sa*vel;
    part._rotation = angle;
    part.parent = this;
    ref.drawBox(part, 1, 1, 0, 0, 0x000000);
    part.onEnterFrame = function() {
     this._x += this.xspeed;
     this._y += this.yspeed;
     this._alpha -= 7;
     if (this._alpha<0) {
      this.removeMovieClip();
     }
    }
    ;
   }
  }
 }
 function drawBox(target, xdim, ydim, x, y, col) {
  target.lineStyle(undefined);
  target.beginFill(col);
  target.moveTo(x, y);
  target.lineTo(x+xdim, y);
  target.lineTo(x+xdim, y+ydim);
  target.lineTo(x, y+ydim);
  target.endFill();
 }
 function drawMap(map, target) {
  for (var y = 0; y<map.length; y++) {
   for (var x = 0; x<map[y].length; x++) {
    if (map[y][x] == 1) {
     drawBox(target, 10, 10, x*10, y*10, 0x000000);
    }
   }
  }
 }
 function genMap(xdim, ydim, num) {
  var xlength, ylength, xpos, ypos, arr;
  var map_arr = new Array();
  //generate empty map
  for (var x = 0; x<xdim; x++) {
   arr = new Array();
   for (var y = 0; y<ydim; y++) {
    arr.push(0);
   }
   map_arr.push(arr);
  }
  //generate blocks
  for (var i = 0; i<num; i++) {
   xlength = Math.round(Math.random()*5);
   ylength = Math.round(Math.random()*5);
   xpos = Math.round(Math.random()*xdim);
   ypos = Math.round(Math.random()*ydim);
   for (var x = 0; x<xlength; x++) {
    for (var y = 0; y<ylength; y++) {
     map_arr[y+ypos][x+xpos] = 1;
    }
   }
  }
  return map_arr;
 }
 function defineGlobals(path) {
  count = 2;
  tanks = new Array();
  max_speed = 2;
  friction = .8;
  accel = .8;
  turnspeed = 5;
  bounce_factor = -0.7;
  tankscale = 1;
  num_enemies = 5;
  bullet_speed = 6;
  damage = 10;
  explosions = true;
  num_particles = 80;
 }
 public static function main () {
  var b = new BattleTanks(_root);
 }
}