function Cannonball() {
  
  this.friendly = true;
  
  this.x = 0;
  this.y = 0;
  this.v = 12;
  
  this.velocity = { x : 0, y : 0 };
  this.velocityV = 2.0;
  
  this.g = -0.4;
  
  this.damage = 0;
  
  this.hitShipOrLand = false;
  this.hitWater = false;
  this.endAnimation = 30;
  
  this.smoke;
  this.explosion;
  this.splash;
  this.rings;
  
  this.sinking = 10;
  
  this.dead = false;
  
  
  this.init = function(friendly, x, y, velocity, damage) {
    this.friendly = friendly;
    this.x = x;
    this.y = y;
    this.velocity = velocity;
    
    this.damage = damage;
    
    var pos = map.transform(this.x + (this.velocity.x / 2), this.y + (this.velocity.y / 2));
    
    this.smoke = new ParticleSystem();
    this.smoke.setMode(ParticleSystem.BURST_MODE);
    this.smoke.setType(3);
    this.smoke.setEmitter(pos.x, pos.y - (this.v + 3));
    this.smoke.setV(-1.0, 1.0, -1.0, 1.0);
    this.smoke.setA(-0.1, 0.1, -0.1, 0.1);
    this.smoke.setLife(15, 25);
    this.smoke.setParticlesPerTick(25);
    this.smoke.burst();
    
    this.explosion = new ParticleSystem();
    this.explosion.setMode(ParticleSystem.BURST_MODE);
    this.explosion.setType(4);
    this.explosion.setV(-1.5, 1.5, -3.0, 0.0);
    this.explosion.setA(-0.1, 0.1, 0.0, 0.5);
    this.explosion.setLife(3, 15);
    this.explosion.setParticlesPerTick(100);
    
    this.splash = new ParticleSystem();
    this.splash.setMode(ParticleSystem.BURST_MODE);
    this.splash.setType(5);
    this.splash.setV(-1.2, 1.2, -2.5, 0.0);
    this.splash.setA(-0.1, 0.1, 0.0, 0.5);
    this.splash.setLife(3, 15);
    this.splash.setParticlesPerTick(100);
    
    this.rings = new ParticleSystem();
    this.rings.setMode(ParticleSystem.BURST_MODE);
    this.rings.setType(6);
    this.rings.setV(-0.04, 0.04, -0.02, 0.02);
    this.rings.setLife(15, 15);
  };
  
  
  this.update = function() {
    
    if(this.hitShipOrLand) {
      if(Object.keys(this.explosion.particles).length == 0) {
        this.dead = true;
      }
      
    } else if(this.hitWater) {
      if(this.sinking > 0) {
        this.sinking--;
        if(this.sinking % 5 == 0) {
          this.rings.burst();
        }
      }
      if(Object.keys(this.splash.particles).length == 0 && Object.keys(this.rings.particles).length == 0) {
        this.dead = true;
      }
      
    } else {
      this.x += this.velocity.x;
      this.y += this.velocity.y;
      this.v += this.velocityV;
      this.velocityV += this.g;

      var roundX = Math.round(this.x);
      var roundY = Math.round(this.y);
      
      var tile = 0;
      if(roundX >= 0 && roundX < map.width && roundY >= 0 && roundY < map.height) {
        tile = map.tiles[roundX][roundY];
      }

      if(tile > 0) {
        for(var i in map.piratePorts) {
          if(map.piratePorts[i].x == roundX && map.piratePorts[i].y == roundY) {
            map.piratePorts[i].damage(this.damage);
            this.hitShipOrLand = true;
            var pos = map.transform(this.x, this.y);
            this.explosion.setEmitter(pos.x, pos.y - this.v);
            this.explosion.burst();
          }
        }
        if(map.homePort.x == roundX && map.homePort.y == roundY) {
          if(!this.friendly) {
            map.homePort.damage(this.damage);
          }
          this.hitShipOrLand = true;
          var pos = map.transform(this.x, this.y);
          this.explosion.setEmitter(pos.x, pos.y - this.v);
          this.explosion.burst();
        }
      } else {
        if(this.friendly) {
          for(var i in map.pirateShips) {
            if(map.pirateShips[i].isHit(this.x, this.y)) {
              map.pirateShips[i].dealDamage(this.damage);
              this.hitShipOrLand = true;
              var pos = map.transform(this.x, this.y);
              this.explosion.setEmitter(pos.x, pos.y - this.v);
              this.explosion.burst();
            }
          }
          
        } else {
          if(ship.isHit(this.x, this.y)) {
            ship.dealDamage(this.damage);
            this.hitShipOrLand = true;
            var pos = map.transform(this.x, this.y);
            this.explosion.setEmitter(pos.x, pos.y - this.v);
            this.explosion.burst();
          }
        }
      }
      
      if(this.v < 0) {
        
        if(tile == 0) {
          this.hitWater = true;
          var pos = map.transform(this.x, this.y);
          this.splash.setEmitter(pos.x, pos.y);
          this.splash.burst();
          this.rings.setEmitter(pos.x, pos.y);
          this.rings.burst();
          
        } else {
          this.hitShipOrLand = true;
          var pos = map.transform(this.x, this.y);
          this.explosion.setEmitter(pos.x, pos.y);
          this.explosion.burst();
        }
      } 
    }
    
    

  };
  
  
  this.draw = function() {
    
    if(this.hitShipOrLand) {
      this.explosion.draw();
      
    } else if(this.hitWater) {
      this.rings.draw();
      this.splash.draw();
      
    } else {
      var pos = map.transform(this.x, this.y);
      img.drawSprite("cannonball", pos.x - 3, pos.y - (this.v + 6), 6, 6, 0, 0);
      img.drawSprite("cannonball", pos.x - 6, pos.y - 3, 12, 6, 1, 0);
    }
    
    this.smoke.draw();
  };
  
  
};