diff --git a/Dockerfile b/Dockerfile
index d93dc5e..e474c32 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,6 +1,6 @@
FROM nginx:stable-alpine-slim
LABEL authors="tebarius"
-LABEL description="nginx_with_404_games"
+LABEL description="nginx_with_404_and_502_games"
-COPY ./404_games /usr/share/nginx/html
+COPY ./games /usr/share/nginx/html
CMD ["nginx", "-g", "daemon off;"]
diff --git a/games/404.html b/games/404.html
new file mode 100644
index 0000000..b6d4f9f
--- /dev/null
+++ b/games/404.html
@@ -0,0 +1,28 @@
+
+
+ups.. Page not Found !!! 404-Alarm!!!!
+
+
+
+404 - Alert
+... page not found ...
+
+
+
+
+
+
+
+
+
diff --git a/games/502.html b/games/502.html
new file mode 100644
index 0000000..3e15527
--- /dev/null
+++ b/games/502.html
@@ -0,0 +1,28 @@
+
+
+ups.. Bad Gateway !!! 502-Alarm!!!!
+
+
+
+502 - Alert
+... Bad Gateway - (maybe subdomain is temporarily down) ...
+
+
+
+
+
+
+
+
+
diff --git a/404_games/index.html b/games/index.html
similarity index 90%
rename from 404_games/index.html
rename to games/index.html
index 0cd5560..b6d4f9f 100644
--- a/404_games/index.html
+++ b/games/index.html
@@ -14,7 +14,7 @@ var randomBetween = function(f, to){
return Math.floor(Math.random() * to) + f;
}
var randomGame = function(){
- var games = ["pacman", "space-invaders", "snake"];
+ var games = ["pacman404", "space-invaders404", "snake404"];
var randomGame = randomBetween(0,games.length);
return games[randomGame];
}
diff --git a/404_games/pacman/data/map.png b/games/pacman404/data/map.png
similarity index 100%
rename from 404_games/pacman/data/map.png
rename to games/pacman404/data/map.png
diff --git a/404_games/pacman/images/32_dot.png b/games/pacman404/images/32_dot.png
similarity index 100%
rename from 404_games/pacman/images/32_dot.png
rename to games/pacman404/images/32_dot.png
diff --git a/404_games/pacman/images/32_player_close.png b/games/pacman404/images/32_player_close.png
similarity index 100%
rename from 404_games/pacman/images/32_player_close.png
rename to games/pacman404/images/32_player_close.png
diff --git a/404_games/pacman/images/32_player_open.png b/games/pacman404/images/32_player_open.png
similarity index 100%
rename from 404_games/pacman/images/32_player_open.png
rename to games/pacman404/images/32_player_open.png
diff --git a/404_games/pacman/images/bg_center.png b/games/pacman404/images/bg_center.png
similarity index 100%
rename from 404_games/pacman/images/bg_center.png
rename to games/pacman404/images/bg_center.png
diff --git a/404_games/pacman/images/bg_down.png b/games/pacman404/images/bg_down.png
similarity index 100%
rename from 404_games/pacman/images/bg_down.png
rename to games/pacman404/images/bg_down.png
diff --git a/404_games/pacman/images/bg_left.png b/games/pacman404/images/bg_left.png
similarity index 100%
rename from 404_games/pacman/images/bg_left.png
rename to games/pacman404/images/bg_left.png
diff --git a/404_games/pacman/images/bg_right.png b/games/pacman404/images/bg_right.png
similarity index 100%
rename from 404_games/pacman/images/bg_right.png
rename to games/pacman404/images/bg_right.png
diff --git a/404_games/pacman/images/bg_up.png b/games/pacman404/images/bg_up.png
similarity index 100%
rename from 404_games/pacman/images/bg_up.png
rename to games/pacman404/images/bg_up.png
diff --git a/404_games/pacman/images/enemy_red.png b/games/pacman404/images/enemy_red.png
similarity index 100%
rename from 404_games/pacman/images/enemy_red.png
rename to games/pacman404/images/enemy_red.png
diff --git a/404_games/pacman/index.html b/games/pacman404/index.html
similarity index 100%
rename from 404_games/pacman/index.html
rename to games/pacman404/index.html
diff --git a/404_games/pacman/js/ai.js b/games/pacman404/js/ai.js
similarity index 100%
rename from 404_games/pacman/js/ai.js
rename to games/pacman404/js/ai.js
diff --git a/404_games/pacman/js/assets.js b/games/pacman404/js/assets.js
similarity index 100%
rename from 404_games/pacman/js/assets.js
rename to games/pacman404/js/assets.js
diff --git a/404_games/pacman/js/collision.js b/games/pacman404/js/collision.js
similarity index 100%
rename from 404_games/pacman/js/collision.js
rename to games/pacman404/js/collision.js
diff --git a/404_games/pacman/js/controls.js b/games/pacman404/js/controls.js
similarity index 100%
rename from 404_games/pacman/js/controls.js
rename to games/pacman404/js/controls.js
diff --git a/404_games/pacman/js/draw.js b/games/pacman404/js/draw.js
similarity index 100%
rename from 404_games/pacman/js/draw.js
rename to games/pacman404/js/draw.js
diff --git a/404_games/pacman/js/game.js b/games/pacman404/js/game.js
similarity index 100%
rename from 404_games/pacman/js/game.js
rename to games/pacman404/js/game.js
diff --git a/404_games/pacman/js/objects.js b/games/pacman404/js/objects.js
similarity index 100%
rename from 404_games/pacman/js/objects.js
rename to games/pacman404/js/objects.js
diff --git a/404_games/pacman/js/objectsLoad.js b/games/pacman404/js/objectsLoad.js
similarity index 100%
rename from 404_games/pacman/js/objectsLoad.js
rename to games/pacman404/js/objectsLoad.js
diff --git a/404_games/pacman/js/update.js b/games/pacman404/js/update.js
similarity index 100%
rename from 404_games/pacman/js/update.js
rename to games/pacman404/js/update.js
diff --git a/404_games/pacman/js/utils.js b/games/pacman404/js/utils.js
similarity index 100%
rename from 404_games/pacman/js/utils.js
rename to games/pacman404/js/utils.js
diff --git a/games/pacman502/data/map.png b/games/pacman502/data/map.png
new file mode 100644
index 0000000..07834e8
Binary files /dev/null and b/games/pacman502/data/map.png differ
diff --git a/games/pacman502/images/32_dot.png b/games/pacman502/images/32_dot.png
new file mode 100644
index 0000000..78e2a33
Binary files /dev/null and b/games/pacman502/images/32_dot.png differ
diff --git a/games/pacman502/images/32_player_close.png b/games/pacman502/images/32_player_close.png
new file mode 100644
index 0000000..034b215
Binary files /dev/null and b/games/pacman502/images/32_player_close.png differ
diff --git a/games/pacman502/images/32_player_open.png b/games/pacman502/images/32_player_open.png
new file mode 100644
index 0000000..70c88a1
Binary files /dev/null and b/games/pacman502/images/32_player_open.png differ
diff --git a/games/pacman502/images/bg_center.png b/games/pacman502/images/bg_center.png
new file mode 100644
index 0000000..79f614e
Binary files /dev/null and b/games/pacman502/images/bg_center.png differ
diff --git a/games/pacman502/images/bg_down.png b/games/pacman502/images/bg_down.png
new file mode 100644
index 0000000..72bf9a4
Binary files /dev/null and b/games/pacman502/images/bg_down.png differ
diff --git a/games/pacman502/images/bg_left.png b/games/pacman502/images/bg_left.png
new file mode 100644
index 0000000..3f5edd9
Binary files /dev/null and b/games/pacman502/images/bg_left.png differ
diff --git a/games/pacman502/images/bg_right.png b/games/pacman502/images/bg_right.png
new file mode 100644
index 0000000..3b28cac
Binary files /dev/null and b/games/pacman502/images/bg_right.png differ
diff --git a/games/pacman502/images/bg_up.png b/games/pacman502/images/bg_up.png
new file mode 100644
index 0000000..54b1bf8
Binary files /dev/null and b/games/pacman502/images/bg_up.png differ
diff --git a/games/pacman502/images/enemy_red.png b/games/pacman502/images/enemy_red.png
new file mode 100644
index 0000000..c7bb213
Binary files /dev/null and b/games/pacman502/images/enemy_red.png differ
diff --git a/games/pacman502/index.html b/games/pacman502/index.html
new file mode 100644
index 0000000..a2e150c
--- /dev/null
+++ b/games/pacman502/index.html
@@ -0,0 +1,23 @@
+
+
+
+
+ 404 Pacman
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/games/pacman502/js/ai.js b/games/pacman502/js/ai.js
new file mode 100644
index 0000000..b93f34c
--- /dev/null
+++ b/games/pacman502/js/ai.js
@@ -0,0 +1,23 @@
+var updateEnemies = function(modifier){
+
+ for (var i= 0; i < enemies.length; i++){
+ var enemy = enemies[i];
+ if (isCollidingBlocks(enemy,enemy.direction)){
+ changeDirection(enemy);
+
+ } else {
+ move(enemy, modifier);
+ }
+ }
+}
+
+var changeDirection = function(enemy){
+ var tol = p(-5,0);
+ var randomDirection = randomBetween(0, 3);
+ switch(randomDirection){
+ case 0: if (!isCollidingBlocks(enemy, LEFT, tol)) enemy.direction = LEFT;break;
+ case 1: if (!isCollidingBlocks(enemy, RIGHT, tol)) enemy.direction = RIGHT;break;
+ case 2: if (!isCollidingBlocks(enemy, UP, tol)) enemy.direction = UP;break;
+ default: if (!isCollidingBlocks(enemy, DOWN, tol)) enemy.direction = DOWN;break;
+ }
+}
diff --git a/games/pacman502/js/assets.js b/games/pacman502/js/assets.js
new file mode 100644
index 0000000..8873734
--- /dev/null
+++ b/games/pacman502/js/assets.js
@@ -0,0 +1,20 @@
+var setImage = function(img){
+ var i = new Image();
+ i.src = img;
+ return i;
+};
+
+// Hero image
+var playerImageClose = setImage("images/32_player_close.png");
+var playerImageOpen = setImage("images/32_player_open.png");
+
+var monsterImage = setImage("images/enemy_red.png");
+
+var dotImage = setImage("images/32_dot.png");
+
+var backgroundImage = {};
+backgroundImage.center = setImage("images/bg_center.png");
+backgroundImage.left = setImage("images/bg_left.png");
+backgroundImage.right = setImage("images/bg_right.png");
+backgroundImage.down = setImage("images/bg_down.png");
+backgroundImage.up = setImage("images/bg_up.png");
diff --git a/games/pacman502/js/collision.js b/games/pacman502/js/collision.js
new file mode 100644
index 0000000..d5b2686
--- /dev/null
+++ b/games/pacman502/js/collision.js
@@ -0,0 +1,71 @@
+//http://gamedev.stackexchange.com/questions/13774/how-do-i-detect-the-direction-of-2d-rectangular-object-collisions
+var collision = new Collision();
+
+var RIGHT = { x: 1, y: 0};
+var LEFT = { x: -1, y: 0};
+var UP = { x: 0, y: -1};
+var DOWN = { x: 0, y: 1};
+
+function Collision(){
+
+ this.onCollisionChange = function(ojb1, obj2, size, callback) {
+ var isColliding = false;
+ setInterval(
+ function(){
+ var beforeStatus = isColliding;
+ isColliding = collision(obj1, obj2, size);
+ if (beforeStatus != isColliding) callback();
+ }, 100);
+ }
+
+ this.isCollidingDirection = function(obj1, obj2, direction, offset){
+ switch(direction){
+ case LEFT: return collision.containsLeft(obj1, obj2, SIZE, offset); break;
+ case RIGHT: return collision.containsRight(obj1, obj2, SIZE, offset); break;
+ case UP: return collision.containsUp(obj1, obj2, SIZE, offset); break;
+ case DOWN: return collision.containsDown(obj1, obj2, SIZE, offset); break;
+ default: console.log("Undefined direction");
+ }
+ }
+
+ this.contains = function(obj, p, size){
+ var contains = p.x > obj.x && p.x < (obj.x + size) &&
+ p.y > obj.y && p.y < (obj.y + size);
+ return contains;
+ }
+
+ this.collision = function(obj1, obj2, size){
+ return obj1.x <= (obj2.x + size)
+ && obj2.x <= (obj1.x + size)
+ && obj1.y <= (obj2.y + size)
+ && obj2.y <= (obj1.y + size)
+ }
+
+ this.containsLeft = function(obj1, obj2, size, offset){
+ return this.contains(obj1, addCoords(middlePoints(obj2, size).left, offset) , size);
+ }
+ this.containsRight = function(obj1, obj2, size, offset){
+ return this.contains(obj1, addCoords(middlePoints(obj2, size).right, offset), size);
+ }
+ this.containsUp = function(obj1, obj2, size, offset){
+ return this.contains(obj1, addCoords(middlePoints(obj2, size).top, offset), size);
+ }
+ this.containsDown = function(obj1, obj2, size, offset){
+ return this.contains(obj1, addCoords( middlePoints(obj2, size).bottom, offset), size);
+ }
+
+ var addCoords = function(point, offset) {
+ return p(point.x + offset.x, point.y + offset.y);
+ }
+
+ var middlePoints = function(obj, size){
+ var middleX = (obj.x + obj.x + size) / 2; //(obj.x *2 + size) / 2; ?
+ var middleY = (obj.y + obj.y + size) / 2;
+ return {
+ left: p(obj.x, middleY),
+ right: p(obj.x + size , middleY),
+ top: p(middleX, obj.y),
+ bottom: p(middleX, obj.y + size),
+ }
+ }
+}
diff --git a/games/pacman502/js/controls.js b/games/pacman502/js/controls.js
new file mode 100644
index 0000000..7712aa0
--- /dev/null
+++ b/games/pacman502/js/controls.js
@@ -0,0 +1,21 @@
+// Handle keyboard controls
+var keysDown = {};
+
+var KEY_UP =38, KEY_DOWN =40, KEY_LEFT =37, KEY_RIGHT =39;
+
+addEventListener("keydown", function (e) {
+ keysDown[e.keyCode] = true;
+}, false);
+
+addEventListener("keyup", function (e) {
+ delete keysDown[e.keyCode];
+}, false);
+
+
+//Called from update.js
+var controls = function(modifier){
+ if (KEY_LEFT in keysDown && !isCollidingBlocks(player, LEFT, p(-5,0))) player.direction = LEFT;
+ if (KEY_RIGHT in keysDown && !isCollidingBlocks(player,RIGHT, p(5,0))) player.direction = RIGHT;
+ if (KEY_UP in keysDown && !isCollidingBlocks(player,UP, p(0,-5))) player.direction = UP;
+ if (KEY_DOWN in keysDown && !isCollidingBlocks(player,DOWN, p(0,5))) player.direction = DOWN;
+}
diff --git a/games/pacman502/js/draw.js b/games/pacman502/js/draw.js
new file mode 100644
index 0000000..52d03ff
--- /dev/null
+++ b/games/pacman502/js/draw.js
@@ -0,0 +1,87 @@
+// Create the canvas
+var canvas = document.getElementById("canvas");
+var ctx = canvas.getContext("2d");
+
+var SIZE = 32;
+
+var directionToRotation = function(direction){
+ switch(direction){
+ case RIGHT : return 0;
+ case LEFT: return 180;
+ case DOWN: return 90;
+ case UP: return 270;
+
+ }
+}
+// Draw everything
+var render = function () {
+ // ctx.clearRect(0,0,canvas.width,canvas.height);
+/*
+ if (bgReady) {
+ ctx.drawImage(bgImage,0 , 0);
+ }*/
+ ctx.fillStyle="black";
+ ctx.fillRect(0,0,canvas.width,canvas.height);
+
+ drawBackground();
+
+ if (!player.dead) {
+ var image;
+ if(player.sprite == 0) image = playerImageClose;
+ else image = playerImageOpen;
+ //TODO rotate with direction
+ // ctx.drawImage(image, player.x, player.y, SIZE, SIZE);
+ var rotation = directionToRotation(player.direction);
+ drawRotated(image, player.x, player.y, rotation);
+ }
+
+ for (var i=0; i < dots.length; i++){
+ var dot = dots[i];
+ ctx.drawImage(dotImage, dot.x, dot.y ,SIZE, SIZE);
+ }
+
+ for (var i=0; i < enemies.length; i++){
+ var enemy = enemies[i];
+ ctx.drawImage(monsterImage, enemy.x, enemy.y,SIZE, SIZE);
+
+ }
+ if (false) //DEBUG
+ for (var i=0; i < blocks.length; i++){
+ var block = blocks[i];
+ ctx.drawImage(monsterImage, block.x, block.y ,SIZE, SIZE);
+ }
+
+
+
+ if (player.dead){
+ ctx.fillStyle = "red";
+ ctx.font = "48px Helvetica";
+ ctx.textAlign = "center";
+ ctx.textBaseline = "top";
+ ctx.fillText("Game Over", canvas.width / 2, canvas.height/ 2);
+ }
+};
+
+function drawBackground(){
+ for (var i= 0; i < background.length; i++){
+ var b = background[i];
+
+ //ctx.drawImage(backgroundImage.center, b.x, b.y ,SIZE, SIZE);
+ for (var j= 0; j < b.directions.length; j++){
+ var d = b.directions[j];
+ ctx.drawImage(backgroundImage[d], b.x, b.y ,SIZE, SIZE);
+ }
+ }
+}
+var TO_RADIANS = Math.PI/180;
+
+//http://creativejs.com/2012/01/day-10-drawing-rotated-images-into-canvas/
+function drawRotated(image, x, y, angle) {
+ var halfWidth = image.width/2;
+ var halfHeight = image.height/2;
+ ctx.save();
+ ctx.translate(x +halfWidth, y + halfHeight);
+ ctx.rotate(angle * TO_RADIANS);
+ ctx.drawImage(image, -halfWidth, -halfHeight);
+ ctx.restore();
+ }
diff --git a/games/pacman502/js/game.js b/games/pacman502/js/game.js
new file mode 100644
index 0000000..325ec7f
--- /dev/null
+++ b/games/pacman502/js/game.js
@@ -0,0 +1,21 @@
+// The main game loop
+var main = function () {
+ var now = Date.now();
+ var delta = now - then;
+
+ update(delta / 1000);
+ render();
+
+ then = now;
+
+ // Request to do this again ASAP
+ requestAnimationFrame(main);
+};
+
+// Cross-browser support for requestAnimationFrame
+var w = window;
+requestAnimationFrame = w.requestAnimationFrame || w.webkitRequestAnimationFrame || w.msRequestAnimationFrame || w.mozRequestAnimationFrame;
+
+// Let's play this game!
+var then = Date.now();
+main();
diff --git a/games/pacman502/js/objects.js b/games/pacman502/js/objects.js
new file mode 100644
index 0000000..b4916a9
--- /dev/null
+++ b/games/pacman502/js/objects.js
@@ -0,0 +1,12 @@
+// Game objects
+var player = {
+ direction: LEFT,
+ speed: 100,
+ sprite: 0
+}
+
+var enemies = [];
+var dots = [];
+var blocks = [];
+
+var background = [];
diff --git a/games/pacman502/js/objectsLoad.js b/games/pacman502/js/objectsLoad.js
new file mode 100644
index 0000000..21f8400
--- /dev/null
+++ b/games/pacman502/js/objectsLoad.js
@@ -0,0 +1,75 @@
+var BLACK = {r: 0, g: 0, b: 0};
+var WHITE = {r: 255, g: 255, b: 255};
+var YELLOW = {r: 255, g: 255, b: 0};
+var GREEN = {r: 0, g: 255, b: 0};
+var ORANGE = {r: 255, g: 127, b: 0};
+var CYAN = {r: 0, g: 255, b: 255};
+var RED = {r: 255, g: 0, b: 0};
+var PINK = {r: 255, g: 0, b: 255};
+
+var addEnemy = function(x, y){
+ var enemy = {
+ direction: DOWN,
+ speed: 100,
+ x: x,
+ y: y
+ };
+ enemies.push(enemy);
+}
+
+var bg = function(x, y , dirs) {
+ return {
+ x: x * SIZE,
+ y: y * SIZE,
+ directions: dirs
+ }
+}
+
+loadImagePixels("data/map.png", function(pixels){
+
+ pixelBackground(pixels);
+
+ for(i=0;i canvas.height ) obj.y = 0 ;
+}
+
+var isCollidingBlocks = function(obj, direction, offset){
+ if (!offset) offset = p(0,0);
+ for (var i=0; i < blocks.length; i++){
+ var block = blocks[i];
+
+ var isColliding = collision.isCollidingDirection(block, obj, direction, offset);
+ if (isColliding) return true;
+ }
+ return false;
+}
diff --git a/games/pacman502/js/utils.js b/games/pacman502/js/utils.js
new file mode 100644
index 0000000..4154892
--- /dev/null
+++ b/games/pacman502/js/utils.js
@@ -0,0 +1,48 @@
+var loadJSON = function (path, success, error)
+{
+ var oReq = new XMLHttpRequest();
+ oReq.onload = function reqListener () {
+ jsonData = JSON.parse(this.responseText);
+ //console.log("Loading JSON data", jsonData);
+ success(jsonData);
+ };;
+ oReq.open("get", path, true);
+ oReq.send();
+}
+
+var p = function(x,y){ return {x: x, y: y}; }
+
+var loadImagePixels = function(image, callback){
+
+ var img = new Image();
+ img.src = image;
+ img.onload = function() {
+ console.log("Image " + image + " loaded " + img.width + "x" +img.height);
+ var canvas = document.createElement('canvas');
+ document.body.appendChild(canvas);
+
+ var ctx = canvas.getContext('2d');
+ canvas.width = img.width;
+ canvas.height = img.height;
+ ctx.drawImage(img, 0, 0);
+ img.style.display = 'none';
+ var imgData = ctx.getImageData(0,0,canvas.width, canvas.height);
+
+ var pixels = [];
+ for(i=0;i
+
+
+
+ 404 snake
+
+
+
+
+
+
+
+
+
+
diff --git a/games/snake502/js/controls.js b/games/snake502/js/controls.js
new file mode 100644
index 0000000..b19e01c
--- /dev/null
+++ b/games/snake502/js/controls.js
@@ -0,0 +1,20 @@
+// Handle keyboard controls
+var keysDown = {};
+
+var KEY_UP =38, KEY_DOWN =40, KEY_LEFT =37, KEY_RIGHT =39;
+
+addEventListener("keydown", function (e) {
+ keysDown[e.keyCode] = true;
+}, false);
+
+addEventListener("keyup", function (e) {
+ delete keysDown[e.keyCode];
+}, false);
+
+//Called from update.js
+var controls = function(){
+ if (KEY_LEFT in keysDown) GAME_STATE.snake.move('l');
+ if (KEY_RIGHT in keysDown) GAME_STATE.snake.move('r');
+ if (KEY_UP in keysDown) GAME_STATE.snake.move('u');
+ if (KEY_DOWN in keysDown) GAME_STATE.snake.move('d');
+}
diff --git a/games/snake502/js/draw.js b/games/snake502/js/draw.js
new file mode 100644
index 0000000..73f00fc
--- /dev/null
+++ b/games/snake502/js/draw.js
@@ -0,0 +1,43 @@
+// Create the canvas
+var canvas = document.getElementById("canvas");
+var ctx = canvas.getContext("2d");
+
+var SIZE = 32;
+
+Cell.prototype.draw = function(){
+ switch(this.content){
+ case 'SNAKE':
+ ctx.fillStyle="gray";
+ break;
+ case 'BLOCK':
+ ctx.fillStyle="black";
+ break;
+ case 'FOOD':
+ ctx.fillStyle="silver";
+ break;
+ }
+ if (this.content && this.content != 'INVALID'){
+ ctx.fillRect(this.x*BLOCK_SIZE, this.y*BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE)
+ }
+}
+
+// Draw everything
+var render = function () {
+ if (GAME_STATE.game_over) {
+ ctx.fillStyle = "rgb(250, 0, 0)";
+ ctx.font = "48px Helvetica";
+ ctx.textAlign = "center";
+ ctx.textBaseline = "top";
+ ctx.fillText("Game Over", canvas.width / 2, canvas.height * 2 / 3);
+ }
+ else {
+ // draw the background
+ ctx.fillStyle="white";
+ ctx.fillRect(0,0,canvas.width,canvas.height);
+
+ // draw game state
+ Object.keys(GAME_STATE.grid).forEach(function(key){
+ GAME_STATE.grid[key].draw();
+ });
+ }
+};
diff --git a/games/snake502/js/framework.js b/games/snake502/js/framework.js
new file mode 100644
index 0000000..2613715
--- /dev/null
+++ b/games/snake502/js/framework.js
@@ -0,0 +1,34 @@
+// The main game loop
+var main = function () {
+ var now = Date.now();
+ var delta = now - then;
+
+ controls();
+ render();
+
+ then = now;
+
+ // Request to do this again ASAP
+ requestAnimationFrame(main);
+};
+
+//var canvas = document.createElement('canvas');
+//document.body.appendChild(canvas);
+
+
+
+setInterval(function(){update()}, 300);
+
+// Cross-browser support for requestAnimationFrame
+var w = window;
+requestAnimationFrame =
+ (
+ w.requestAnimationFrame ||
+ w.webkitRequestAnimationFrame ||
+ w.msRequestAnimationFrame ||
+ w.mozRequestAnimationFrame
+ );
+
+// Let's play this game!
+var then = Date.now();
+initGameState(main);
diff --git a/games/snake502/js/logic.js b/games/snake502/js/logic.js
new file mode 100644
index 0000000..0370d01
--- /dev/null
+++ b/games/snake502/js/logic.js
@@ -0,0 +1,140 @@
+var BLOCK_SIZE = 16;
+
+function update(){
+ if (GAME_STATE.complete) GAME_STATE.snake.update();
+}
+
+function initGameState(callback){
+ GAME_STATE.grid = {};
+ loadImagePixels("data/map.png", function(rows){
+ rows.forEach(function(row, i){
+ row.forEach(function(pixel, j){
+ var cell = new Cell(i,j);
+ if (isColor(pixel, BLACK))
+ cell.content = 'BLOCK';
+ else if (isColor(pixel, GREEN))
+ cell.content = 'INVALID';
+ else if (isColor(pixel, RED)){
+ cell.content = 'SNAKE';
+ GAME_STATE.snake = new Snake(cell);
+ }
+ GAME_STATE.grid[[i,j]] = cell;
+ GAME_STATE.gameHeight = i;
+ GAME_STATE.gameWidth = j;
+ });
+ });
+ Grid.newFood();
+ GAME_STATE.complete = true;
+ callback();
+ });
+}
+
+var GAME_STATE = {
+ snake: null,
+ grid: null,
+ gameOver: false,
+ gameHeight: 0,
+ gameWidth: 0,
+}
+
+function Grid(){}
+
+Grid.get = function(x,y){
+ return GAME_STATE.grid[[x,y]];
+}
+
+Grid.set = function(x, y, content){
+ var cell = GAME_STATE.grid[[x,y]];
+ cell.content = content;
+ return cell;
+}
+
+Grid.unset = function(x, y){
+ var cell = GAME_STATE.grid[[x,y]];
+ cell.content = null;
+ return cell;
+}
+
+Grid.randomFree = function(){
+ do{
+ var row = Math.floor(Math.random() * GAME_STATE.gameHeight);
+ var col = Math.floor(Math.random() * GAME_STATE.gameWidth);
+ var cell = this.get(row,col);
+ } while (cell.content);
+ return cell;
+}
+
+Grid.newFood = function (){
+ var freeCell = this.randomFree();
+ freeCell.content = 'FOOD';
+}
+
+function Cell(x,y){
+ this.x = x;
+ this.y = y;
+ this.content = null;
+}
+
+
+function Snake(initCell){
+ this.body = [initCell];
+ this.dir = {x: -1, y: 0}; // start moving to the left
+}
+
+Snake.prototype.head = function(){
+ return this.body[0];
+}
+
+Snake.prototype.tail = function(){
+ return this.body[-1];
+}
+
+Snake.prototype.move = function(dir){
+ switch(dir){
+ case 'l':
+ this.dir = {x: -1, y: 0};
+ break;
+ case 'r':
+ this.dir = {x: 1, y: 0};
+ break;
+ case 'u':
+ this.dir = {x: 0, y: -1};
+ break;
+ case 'd':
+ this.dir = {x: 0, y: 1};
+ break;
+ }
+}
+
+Snake.prototype.update = function(dir){
+ // compute new position of the head
+ var head = this.head();
+ var dir = this.dir;
+ var newX = head.x + dir.x;
+ var newY = head.y + dir.y;
+ var newHead = Grid.get(newX, newY);
+
+ // check collisions
+
+ // if food, grow (on the head)
+ if (newHead.content == 'FOOD') {
+ newHead.content = 'SNAKE';
+ this.body.unshift(newHead);
+ Grid.newFood();
+ }
+
+ // if block, die
+ else if (newHead.content != null){
+ GAME_STATE.game_over = true;
+ }
+
+ // else, move
+ else {
+ oldTail = this.body.pop();
+ oldTail.content = null;
+
+ newHead.content = 'SNAKE';
+ this.body.unshift(newHead);
+ }
+
+}
diff --git a/games/snake502/js/utils.js b/games/snake502/js/utils.js
new file mode 100644
index 0000000..11ee39e
--- /dev/null
+++ b/games/snake502/js/utils.js
@@ -0,0 +1,47 @@
+var loadImagePixels = function(image, callback){
+
+ var img = new Image();
+ img.src = image;
+ img.onload = function() {
+ console.log("Image " + image + " loaded " + img.width + "x" +img.height);
+ var canvas = document.createElement('canvas');
+ document.body.appendChild(canvas);
+
+ var ctx = canvas.getContext('2d');
+ canvas.width = img.width;
+ canvas.height = img.height;
+ ctx.drawImage(img, 0, 0);
+ img.style.display = 'none';
+ var imgData = ctx.getImageData(0,0,canvas.width, canvas.height);
+
+ var pixels = [];
+ for(i=0;i
+
+
+
+ 404 Space Invaders
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/games/space-invaders502/js/ai.js b/games/space-invaders502/js/ai.js
new file mode 100644
index 0000000..f8c5cfd
--- /dev/null
+++ b/games/space-invaders502/js/ai.js
@@ -0,0 +1,41 @@
+var updateEnemies = function(){
+
+ if (hasReachedEnd()) {
+ changeEnemyDirection();
+ return;
+ }
+ var enemyMovement;
+ if (enemyDirection == LEFT) enemyMovement = -10;
+ else enemyMovement = 10;
+
+ for (var i = 0 ; i < enemies.length; i++){
+ var enemy = enemies[i];
+ enemy.x = enemy.x + enemyMovement ;
+ }
+}
+
+var hasReachedEnd = function(){
+ var threshold = 32;
+
+ for (var i = 0 ; i < enemies.length; i++){
+ var enemy = enemies[i];
+ if (enemyDirection == RIGHT && enemy.x > canvas.width - threshold - 32) return true;
+ else if (enemyDirection == LEFT && enemy.x < threshold) return true;
+ }
+ return false;
+}
+
+var changeEnemyDirection = function(){
+ if (enemyDirection == LEFT) enemyDirection = RIGHT;
+ else enemyDirection = LEFT;
+
+ for (var i = 0 ; i < enemies.length; i++){
+ var enemy = enemies[i];
+ enemy.y = enemy.y + 30 ;
+ }
+}
+
+var enemyShot = function(){
+ var enemy = enemies[Math.floor(Math.random()*enemies.length)];
+ enemyShots.push({x:enemy.x, y: enemy.y});
+}
diff --git a/games/space-invaders502/js/assets.js b/games/space-invaders502/js/assets.js
new file mode 100644
index 0000000..b427a80
--- /dev/null
+++ b/games/space-invaders502/js/assets.js
@@ -0,0 +1,45 @@
+/**
+Ship and laser assets by Cpt_Flash
+Available at: http://opengameart.org/content/space-ships-2-units
+License: GPL 3.0
+**/
+
+// Background image
+var bgReady = false;
+var bgImage = new Image();
+
+bgImage.onload = function () {
+ bgReady = true;
+};
+bgImage.src = "images/background.png";
+
+// Hero image
+var heroReady = false;
+var heroImage = new Image();
+heroImage.onload = function () {
+ heroReady = true;
+};
+heroImage.src = "images/32_player.png";
+
+// Monster image
+var monsterReady = false;
+var monsterImage = new Image();
+monsterImage.onload = function () {
+ monsterReady = true;
+};
+monsterImage.src = "images/32_enemy.png";
+
+// Hero image
+var shotReady = false;
+var shotImage = new Image();
+shotImage.onload = function () {
+ shotReady = true;
+};
+shotImage.src = "images/32_laser_blue.png";
+
+var shotRedReady = false;
+var shotRedImage = new Image();
+shotRedImage.onload = function () {
+ shotRedReady = true;
+};
+shotRedImage.src = "images/32_laser_red.png";
diff --git a/games/space-invaders502/js/controls.js b/games/space-invaders502/js/controls.js
new file mode 100644
index 0000000..a437955
--- /dev/null
+++ b/games/space-invaders502/js/controls.js
@@ -0,0 +1,40 @@
+// Handle keyboard controls
+var keysDown = {};
+
+var KEY_UP =38, KEY_DOWN =40, KEY_LEFT =37, KEY_RIGHT =39;
+
+addEventListener("keydown", function (e) {
+ keysDown[e.keyCode] = true;
+}, false);
+
+addEventListener("keyup", function (e) {
+ delete keysDown[e.keyCode];
+}, false);
+
+addEventListener("mousemove", function(evt) {
+ hero.x = evt.pageX - 24 ;
+}, false);
+
+var lastShot = 0;
+var SHOT_DELAY = 1000;
+
+addEventListener("click", function(evt) {
+ if (!hero.dead) {
+ var now = new Date().getTime();
+ if (lastShot +SHOT_DELAY < now ) {
+ lastShot = now;
+ playerShots.push({x:evt.pageX, y: hero.y});
+ }
+ }
+}, false);
+
+
+//Called from update.js
+var controls = function(modifier){
+ if (KEY_LEFT in keysDown) { // Player holding left
+ hero.x -= hero.speed * modifier;
+ }
+ if (KEY_RIGHT in keysDown) { // Player holding right
+ hero.x += hero.speed * modifier;
+ }
+}
diff --git a/games/space-invaders502/js/draw.js b/games/space-invaders502/js/draw.js
new file mode 100644
index 0000000..184af78
--- /dev/null
+++ b/games/space-invaders502/js/draw.js
@@ -0,0 +1,45 @@
+// Create the canvas
+var canvas = document.getElementById("canvas");
+var ctx = canvas.getContext("2d");
+
+var SIZE = 32;
+
+var vy = 0;
+// Draw everything
+var render = function () {
+ if (bgReady) {
+
+ ctx.drawImage(bgImage, 0, vy);
+ ctx.drawImage(bgImage, 0, bgImage.height-Math.abs(vy));
+
+ if (Math.abs(vy) > bgImage.height) vy = 0;
+ vy -= 2;
+ }
+
+ if (heroReady && !hero.dead) {
+ ctx.drawImage(heroImage, hero.x, hero.y,SIZE, SIZE);
+ }
+
+ for (var i=0; i < enemies.length; i++){
+ var enemy = enemies[i];
+ ctx.drawImage(monsterImage, enemy.x, enemy.y,SIZE, SIZE);
+
+ }
+ for (var i=0; i < enemyShots.length; i++){
+ var shot = enemyShots[i];
+ ctx.drawImage(shotRedImage, shot.x, shot.y ,SIZE, SIZE);
+ }
+
+ for (var i=0; i < playerShots.length; i++){
+ var shot = playerShots[i];
+ ctx.drawImage(shotImage, shot.x, shot.y ,SIZE, SIZE);
+ }
+
+ if (hero.dead){
+ ctx.fillStyle = "rgb(250, 0, 0)";
+ ctx.font = "48px Helvetica";
+ ctx.textAlign = "center";
+ ctx.textBaseline = "top";
+ ctx.fillText("Game Over", canvas.width / 2, canvas.height/ 2);
+ }
+};
diff --git a/games/space-invaders502/js/game.js b/games/space-invaders502/js/game.js
new file mode 100644
index 0000000..f6a5848
--- /dev/null
+++ b/games/space-invaders502/js/game.js
@@ -0,0 +1,28 @@
+// Reset the game when the player catches a monster
+var reset = function () {
+ hero.x = canvas.width / 2;
+ hero.y = canvas.height - 64;
+};
+
+// The main game loop
+var main = function () {
+ var now = Date.now();
+ var delta = now - then;
+
+ update(delta / 1000);
+ render();
+
+ then = now;
+
+ // Request to do this again ASAP
+ requestAnimationFrame(main);
+};
+
+// Cross-browser support for requestAnimationFrame
+var w = window;
+requestAnimationFrame = w.requestAnimationFrame || w.webkitRequestAnimationFrame || w.msRequestAnimationFrame || w.mozRequestAnimationFrame;
+
+// Let's play this game!
+var then = Date.now();
+reset();
+main();
diff --git a/games/space-invaders502/js/objects.js b/games/space-invaders502/js/objects.js
new file mode 100644
index 0000000..ff54c8a
--- /dev/null
+++ b/games/space-invaders502/js/objects.js
@@ -0,0 +1,29 @@
+// Game objects
+var hero = {};
+var playerShots = [];
+var enemyShots = [];
+
+var shotSpeed = 200;
+
+var RIGHT = 1, LEFT = 0;
+var enemies = [];
+var enemyDirection = RIGHT;
+var loadEnemy = function(offset, json){
+ var size = 32;
+
+ for (var i = 0; i< json.length; i++){
+ var pos = json[i];
+ var enemy = {x: offset.x + pos.x * size, y: offset.y + pos.y * size} ;
+ enemies.push(enemy);
+ }
+}
+
+loadJSON('enemies.json',
+ function(data) {
+
+ loadEnemy({ x: 50, y: 50 }, data.five);
+ loadEnemy({ x: 180, y: 50 }, data.zero);
+ loadEnemy({ x: 300, y: 50 }, data.two);
+ },
+ function(xhr) { console.error(xhr); }
+);
diff --git a/games/space-invaders502/js/update.js b/games/space-invaders502/js/update.js
new file mode 100644
index 0000000..6ab20c8
--- /dev/null
+++ b/games/space-invaders502/js/update.js
@@ -0,0 +1,45 @@
+
+// Update game objects
+var update = function (modifier) {
+ controls(modifier);
+
+ for (var i = 0; i< playerShots.length; i++){
+ var shot = playerShots[i];
+ shot.y = shot.y - modifier * shotSpeed;
+
+ for (var e= 0; e < enemies.length; e++){
+ var enemy = enemies[e];
+ if (collision(shot, enemy)) {
+ console.log("Collision with enemy ", shot, enemy);
+ playerShots.splice(i, 1);
+ enemies.splice(e, 1);
+ break;
+ }
+ }
+ }
+
+ for (var i = 0; i< enemyShots.length; i++){
+ var shot = enemyShots[i];
+ shot.y = shot.y + modifier * shotSpeed;
+
+ if (collision(shot, hero)) {
+ console.log("Collision with hero ", shot, hero);
+ enemyShots.splice(i, 1);
+ hero.dead = true;
+ }
+ }
+ //updateEnemies();
+ // Are they touching?
+};
+
+var collision = function(shot, enemy){
+ return shot.x <= (enemy.x + 32)
+ && enemy.x <= (shot.x + 32)
+ && shot.y <= (enemy.y + 32)
+ && enemy.y <= (shot.y + 32)
+}
+
+//AI METHODS
+setInterval(function(){updateEnemies()}, 500);
+
+setInterval(function(){enemyShot()}, 1000);
diff --git a/games/space-invaders502/js/utils.js b/games/space-invaders502/js/utils.js
new file mode 100644
index 0000000..f17f8b3
--- /dev/null
+++ b/games/space-invaders502/js/utils.js
@@ -0,0 +1,11 @@
+var loadJSON = function (path, success, error)
+{
+ var oReq = new XMLHttpRequest();
+ oReq.onload = function reqListener () {
+ jsonData = JSON.parse(this.responseText);
+ console.log("Loading JSON data", jsonData);
+ success(jsonData);
+ };;
+ oReq.open("get", path, true);
+ oReq.send();
+}
diff --git a/readme.md b/readme.md
index 037a0ef..d3b7c5f 100644
--- a/readme.md
+++ b/readme.md
@@ -1,3 +1,5 @@
# 404 ;)
Games from https://github.com/coconauts/404-games with some minor-changes to build a self-running Docker-Container
+
+and properly also added modified games for error 502
\ No newline at end of file