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