Skip to content

Instantly share code, notes, and snippets.

@vkobel
Last active August 29, 2015 14:07
Show Gist options
  • Save vkobel/0c19ed991b4254ab4005 to your computer and use it in GitHub Desktop.
Save vkobel/0c19ed991b4254ab4005 to your computer and use it in GitHub Desktop.
invaders pure js
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
body{
background-color: #333;
text-align: center;
font-family: Helvetica;
color: #999;
}
canvas{
padding: 7px;
}
</style>
<title>Space Invaders</title>
</head>
<body>
<h1>Space Invaders</h1>
<canvas id="screen" width="1600" height="800"></canvas>
<script src="spaceinvaders.js"></script>
</body>
</html>
;(function(){
var Game = function(canvasId){
var canvas = document.getElementById(canvasId);
var screen = canvas.getContext("2d");
this.gameSize = { x: canvas.width, y: canvas.height };
screen.fillStyle = "#666";
screen.strokeStyle = '#FFAC38';
screen.lineWidth = 1;
this.bodies = createInvaders(this).concat(new Player(this, this.gameSize));
var self = this;
var tick = function(){
self.update();
self.draw(screen, self.gameSize);
requestAnimationFrame(tick);
}
tick();
};
Game.prototype = {
update: function(){
var bodies = this.bodies;
var notCollidingWithAnything = function(b1){
return bodies.filter(function(b2){ return colliding(b1, b2); }).length === 0;
};
this.bodies = this.bodies.filter(notCollidingWithAnything);
for(var i = 0; i < this.bodies.length; i++){
if(this.bodies[i].center.x - this.bodies[i].size.x > this.gameSize.x ||
this.bodies[i].center.x < 0 ||
this.bodies[i].center.y < 0 ||
this.bodies[i].center.y - this.bodies[i].size.y > this.gameSize.y){
this.bodies.remove(i);
}else
this.bodies[i].update();
}
},
draw: function(screen, gameSize){
screen.clearRect(0, 0, gameSize.x, gameSize.y);
for(var i = 0; i < this.bodies.length; i++){
this.bodies[i].draw(screen, gameSize);
}
},
addBody: function(body){
this.bodies.push(body);
},
invadersBelow: function(invader){
return this.bodies.filter(function(b){
return b instanceof Invader &&
b.center.y > invader.center.y &&
b.center.x - invader.center.x < invader.size.x;
}).length > 0;
},
};
var Player = function(game, gameSize){
this.game = game;
this.size = { x: 30, y: 30 };
this.center = { x: gameSize.x / 2, y: gameSize.y - this.size.x / 2 };
this.keyboarder = new Keyboarder();
}
Player.prototype = {
update: function(){
if(this.keyboarder.isDown(this.keyboarder.KEYS.LEFT)){
this.center.x -= 10;
} else if(this.keyboarder.isDown(this.keyboarder.KEYS.RIGHT)){
this.center.x += 10;
}
if(this.keyboarder.isDown(this.keyboarder.KEYS.SPACE)){
var bullet = new Bullet({ x: this.center.x, y: this.center.y - this.size.x / 2 },
{ x: getRandomInt(-3, 3), y: -20 });
this.game.addBody(bullet);
}
},
draw: function(screen, gameSize){
drawRect(screen, this);
}
}
var Bullet = function(center, velocity){
this.size = { x: 1, y: 1 };
this.center = center;
this.oldX = center.x;
this.oldY = center.y;
this.velocity = velocity;
}
Bullet.prototype = {
update: function(){
this.oldX = this.center.x;
this.oldY = this.center.y;
this.center.x += this.velocity.x;
this.center.y += this.velocity.y;
},
draw: function(screen, gameSize){
screen.beginPath();
screen.moveTo(this.oldX - this.size.x / 2,
this.oldY - this.size.y / 2);
screen.lineTo(this.center.x - this.size.x / 2,
this.center.y - this.size.y / 2);
screen.stroke();
}
}
var Invader = function(game, center){
this.game = game;
this.size = { x: 30, y: 30 };
this.center = center;
this.patrolX = 0;
this.speedX = 8;
}
Invader.prototype = {
update: function(){
if(this.patrolX < 0 || this.patrolX > 900){
this.speedX = -this.speedX;
}
this.center.x += this.speedX;
this.patrolX += this.speedX;
if(Math.random() > 0.99 && !this.game.invadersBelow(this)){
var bullet = new Bullet({ x: this.center.x, y: this.center.y + this.size.x / 2 },
{ x: getRandomInt(-4, 4), y: 10 });
this.game.addBody(bullet);
}
},
draw: function(screen, gameSize){
drawRect(screen, this);
}
}
var createInvaders = function(game){
var invaders = [];
for(var i = 0; i < 36; i++){
var x = 20 + (i % 12) * 60;
var y = 20 + ~~(i / 12) * 60; // ~ is NOT operator, apply it 2 times and it removes the decimals
invaders.push(new Invader(game, { x: x, y: y }));
}
return invaders;
}
var drawRect = function(screen, body){
screen.fillRect(body.center.x - body.size.x / 2,
body.center.y - body.size.y / 2,
body.size.x, body.size.y);
};
var Keyboarder = function(){
var keyState = {};
window.onkeydown = function(e){
keyState[e.keyCode] = true;
};
window.onkeyup = function(e){
keyState[e.keyCode] = false;
};
this.isDown = function(keyCode){
return keyState[keyCode] === true;
};
this.KEYS = { LEFT: 37, RIGHT: 39, SPACE: 32 };
}
var colliding = function(b1, b2){
return !(b1 === b2 ||
b1.center.x + b1.size.x / 2 < b2.center.x - b2.size.x / 2 ||
b1.center.y + b1.size.y / 2 < b2.center.y - b2.size.y / 2 ||
b1.center.x - b1.size.x / 2 > b2.center.x + b2.size.x / 2 ||
b1.center.y - b1.size.y / 2 > b2.center.y + b2.size.y / 2);
}
var getRandomInt = function (min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}
window.onload = function(){
new Game("screen");
}
})();
// Array Remove - By John Resig (MIT Licensed)
Array.prototype.remove = function(from, to) {
var rest = this.slice((to || from) + 1 || this.length);
this.length = from < 0 ? this.length + from : from;
return this.push.apply(this, rest);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment