fassetar/penguins-rising

View on GitHub
src/js/game.js

Summary

Maintainability
D
2 days
Test Coverage
'use script';

var img = new Image();
img.src = "http://fassetar.github.io/penguins-rising/content/img/characters.png";
var canvas = document.getElementById("window");
var ctx = canvas.getContext('2d');
var enemies = [];
var TheTrulyDead = [];
var bosses = [];
var game = {
  paused: false,
  timer: null,
  Lvl: 1,
  Lvlcomplete: false,
  LvlEnemies: 3,
  mousePos: {
    x: 0,
    y: 0
  },
  loop: function() {
    if (!game.over && !game.paused) {
      game.update();
      draw();
    } else if (game.over) {
      var cf = confirm("Your lose! Start Over?");
      if (cf) {
        location.reload();
      }
    } //Create Pause Menu
    requestAnimFrame(game.loop);
  },
  over: false,
  startGame: function() {
    canvas.addEventListener('mousedown', mouseClick);
    window.requestAnimFrame = (
      function(callback) {
        return window.requestAnimationFrame ||
          window.webkitRequestAnimationFrame ||
          window.mozRequestAnimationFrame ||
          window.oRequestAnimationFrame ||
          window.msRequestAnimationFrame ||
          function(callback) {
            window.setTimeout(callback, 100 / 2);
          };
      })();
    game.loop();
    window.onblur = function (evt) {
        Pause(true);
    };
    document.onkeypress = (function(evt) {
  evt = evt || window.event;
  var charCode = evt.keyCode || evt.which;
  var charStr = String.fromCharCode(charCode);
  if (charStr === "p") {
    Pause();
  }
});
  },
  update: function() { //UPDATE METHOD
    if ((TheTrulyDead.length > game.LvlEnemies) && (enemies.length === 0)) {
      game.Lvlcomplete = true;
      game.LvlEnemies += 5;
      game.Lvl += 1;
      player.health = 10;
    }
    //Remove or shorten this!
    canvas.height = "innerHeight" in window ? window.innerHeight : document.documentElement.offsetHeight;
    canvas.width = "innerWidth" in window ? window.innerWidth : document.documentElement.offsetWidth;
    if (player.health <= 0) {
      game.over = true;
    }
    if (!game.Lvlcomplete && player.update) {
      player.Bullets.forEach(function(bullet) {
        bullet.update();
      });
      player.Bullets = player.Bullets.filter(function(bullet) {
        return bullet.active;
      });
      enemies.forEach(function(enemy) {
        enemy.update();
      });
      enemies = enemies.filter(function(enemy) {
        return enemy.active;
      });
      handleCollisions();
      if (game.LvlEnemies > enemies.length && (TheTrulyDead.length <= game.LvlEnemies)) {
        enemies.push(Enemy());
        bosses.push(Boss(this));
      }
    } else {
      if (!player.update) {
        console.log("you died");
      }
      enemies = [];
      TheTrulyDead = [];
      bosses = [];
      game.Lvlcomplete = false;
      document.getElementsByClassName("LvlComplete")[0].style.display = "block";
      game.paused = true;
    }
  }

};
var Pause = function (flag) {
    game.paused = (flag) ? flag : !game.paused;
    if (game.paused) {
        document.getElementsByClassName("pause")[0].style.display = "block";
    } else {
        document.getElementsByClassName("pause")[0].style.display = "none";
    }
};

function NextLevel() {
  Pause(false);
  document.getElementsByClassName("LvlComplete")[0].style.display = "none";
}

window.onresize = (function(event) {
  canvas.height = "innerHeight" in window ? window.innerHeight : document.documentElement.offsetHeight;
  canvas.width = "innerWidth" in window ? window.innerWidth : document.documentElement.offsetWidth;
})();

// EVENT LISTENERS
canvas.addEventListener('mousemove', function(evt) {
  game.mousePos = getMousePos(canvas, evt);
}, false);

function getMousePos(canvas, evt) {
  var rect = canvas.getBoundingClientRect();
  return {
    x: evt.clientX - rect.left,
    y: evt.clientY - rect.top
  };
}

function mouseClick(event) {
  event.preventDefault();
  if (!player.shot) {
    player.shoot();
    setTimeout(function() {
      player.shot = false;
    }, 500);
    player.shot = true;
  }
}
var a = document.createElement('audio');
var SoundTest = function() {
  return (!!(a.createElement('audio').canPlayType && a.canPlayType('audio/mpeg;').replace(/no/, '')));
};

//PLAYER CLASS
var player = {
  x: (canvas.width / 2),
  y: (canvas.height - 60),
  vx: 0,
  vy: 0,
  health: 10,
  Bullets: [],
  active: true,
  weapons: {
    selected: [0, 0, 0],
    choice: ["Uzi", "Hunting Rifle", "Shotgun", "Minigun"],
    secondary: ["Grenade", "Mine", "Ice Cracker", "Reaper"],
    support: ["Upgrade Wall", "Barbes Wire", "Eskimo Guards", "Polar Bear", "Mortar Support"]
  },
  draw: function() {
    ctx.save();
    ctx.translate((canvas.width / 2), canvas.height - 60);
    ctx.rotate(Math.atan2(game.mousePos.x - (canvas.width / 2), (canvas.height - 60) - game.mousePos.y));
    ctx.drawImage(img, 0, 0, 42, 59, -18, -33, 42, 59);
    ctx.restore();
  },
  update: function() {
    if (player.health < 1) {
      return false;
    } else {
      return true;
    }
  },
  shot: false,
  snd: new Audio((SoundTest) ? "http://fassetar.github.io/penguins-rising/content/audio/mp3/gunshot.mp3" : "http://fassetar.github.io/penguins-rising/content/audio/wav/gunshot.wav"),
  shoot: function() {
    var angle = Math.atan2((canvas.width / 2) - game.mousePos.x, (canvas.height - 60) - game.mousePos.y);
    player.snd.play();
    player.Bullets.push(Bullet({
      radian: angle,
      x: (canvas.width / 2) + -18 * Math.sin(angle),
      y: (canvas.height - 60) + -18 * Math.cos(angle)
    }));
  },
  displayName: 'anonymous',
  profileUrl: '',
  userId: '',
  loadLocalPlayer: function() {
    var request = gapi.client.games.players.get({
      playerId: 'me'
    });
    request.execute(function(response) {
      if (!response.displayName) {
        response.displayName = 'anonymous';
      }
      $('#welcome #message').text('Welcome, ' + response.displayName + '!');
      $('#welcomeAchievements, #welcomeleaderboards').fadeIn();
      player.displayName = response.displayName;
      player.profileUrl = response.avatarImageUrl;
      player.userId = response.playerId;
      welcome.dataLoaded(welcome.ENUM_PLAYER_DATA);
    });
  }
};

// ENEMY CLASS
function Enemy(I) {
  I = I || {};
  I.active = true;
  I.age = Math.floor(Math.random() * 128);
  I.x = Math.random() * canvas.width;
  I.y = 0;
  I.xVelocity = 0;
  I.yVelocity = 0.5;
  I.width = 42;
  I.height = 37;
  I.length = 0;
  I.frame = undefined;
  I.index = 0;
  I.elapsed = 0;
  I.snd = new Audio((SoundTest) ? "http://fassetar.github.io/penguins-rising/content/audio/mp3/cry.mp3" : "content/wav/cry.wav");
  I.animation = new AnimationData(
    [{
      x: 40,
      length: 180
    }, {
      x: 78,
      length: 180
    }, {
      x: 127,
      length: 180
    }], {
      repeats: true,
      keyframe: 0
    });
  I.reset = (function() {
    I.elapsed = 0;
    I.index = 0;
    I.frame = I.animation.frames[I.index];
  })();
  I.length = I.animation.frames.length;
  I.inBounds = function() {
    if (I.y !== canvas.height) {
      return I.x >= 0 && I.x <= canvas.width &&
        I.y >= 0 && I.y <= canvas.height;
    } else {
      player.health -= 1;
      return false;
    }
  };
  I.RnP = Math.floor(Math.random() * 3);
  I.deadAnm = [169, 204, 250];
  I.draw = function() {
    if (I.active) {
      ctx.drawImage(img, I.frame.x, 0, I.width, I.height, I.x, I.y, I.width, I.height);
    } else {
      ctx.drawImage(img, I.deadAnm[I.RnP], 0, 45, 37, I.x, I.y, 46, 37);
    }
  };
  I.update = function() {
    if (I.active) {
      I.x += I.xVelocity;
      I.y += I.yVelocity;
      I.xVelocity = Math.sin(I.age * Math.PI / 64);
      I.age++;
      I.active = I.active && I.inBounds();
      I.elapsed = I.elapsed + 30;

      if (I.elapsed >= I.frame.length) {
        I.index++;
        I.elapsed = I.elapsed - I.frame.length;
      }

      if (this.index >= this.length) {
        if (this.animation.options.repeats) {
          this.index = this.animation.options.keyframe;
        } else {
          this.index--;
        }
      }

      I.frame = I.animation.frames[I.index];
    }
  };
  I.deactive = function() {
    I.active = false;
  };
  return I;
}

// BOSS CLASS
function Boss() {}
Boss.prototype = new Enemy();

// BULLET CLASS
function Bullet(I) {
  I.type = 0;
  I.active = true;
  I.speed = 10;
  I.radian = Math.atan2((canvas.width / 2) - game.mousePos.x, (canvas.height - 60) - game.mousePos.y);
  I.xVelocity = -I.speed * Math.sin(I.radian);
  I.yVelocity = -I.speed * Math.cos(I.radian);
  I.width = 3;
  I.height = 3;
  I.color = "#000";

  I.inBounds = function() {
    return I.x >= 0 && I.x <= canvas.width &&
      I.y >= 0 && I.y <= canvas.height;
  };

  I.draw = function() {
    ctx.fillStyle = I.color;
    ctx.fillRect(I.x, I.y, I.width, I.height);
  };

  I.update = function() {
    I.x += I.xVelocity;
    I.y += I.yVelocity;

    I.active = I.active && I.inBounds();
  };
  return I;
}

// ANIMATION METHOD
function AnimationData(frames, options) {
  this.frames = frames || [{
    x: 0,
    y: 0,
    w: 0,
    h: 0,
    length: 0
  }];
  this.options = options || {
    repeats: false,
    keyframe: 0
  };
}

var border = new Image();
border.src = "https://raw.githubusercontent.com/fassetar/penguins-rising/master/src/content/img/borderline.jpg";
// DRAW METHOD
function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.drawImage(border, 23, canvas.height - 150, canvas.width - 45, 100);
  player.draw();
  TheTrulyDead.forEach(function(enemy) {
    enemy.draw();
  });
  player.Bullets.forEach(function(bullet) {
    bullet.draw();
  });
  enemies.forEach(function(enemy) {
    enemy.draw();
  });
  ctx.fillText("Kills:" + TheTrulyDead.length, 10, 50);
  ctx.fillText("Level:" + game.Lvl, 10, 70);
  ctx.fillText("Health:" + player.health, 10, 100);
}


// COLLIDE METHOD
function collides(a, b) {
  return a.x < b.x + b.width &&
    a.x + a.width > b.x &&
    a.y < b.y + b.height &&
    a.y + a.height > b.y;
}

// COLLISION HANDLER
function handleCollisions() {
  player.Bullets.forEach(function(bullet) {
    enemies.forEach(function(enemy) {
      if (collides(bullet, enemy)) {
        enemy.deactive();
        TheTrulyDead.push(enemy);
        enemy.snd.play();
        bullet.active = false;
      }
    });
  });
}