Initial commit

This commit is contained in:
clb92
2016-07-05 21:02:51 +02:00
commit 55bfd6e774
7 changed files with 492 additions and 0 deletions

77
css/styles.css Normal file
View File

@@ -0,0 +1,77 @@
* {
margin: 0;
padding: 0;
font-family: sans-serif;
}
html, body {
height: 100%;
background-color: #333;
}
.error {
position: absolute;
float: left;
top: 10%;
width: 100%;
font-size: 20pt;
color: #333;
text-align: center;
z-index: 100;
color: red;
}
#gameCanvas {
position: absolute;
float: left;
width: 100%;
height: 100%;
z-index: 99;
/* filter: blur(40px);
-webkit-filter: blur(40px); */
transition: all .1s ease;
-webkit-transition: all .1s ease;
-moz-transition: all .1s ease;
}
#popup-text {
position: absolute;
float: left;
top: 40%;
width: 100%;
font-size: 42pt;
color: #333;
text-align: center;
z-index: 100;
filter: blur(0px);
-webkit-filter: blur(0px);
transition: all .5s ease;
-webkit-transition: all .5s ease;
-moz-transition: all .5s ease;
}
#overlay {
position: absolute;
float: left;
height: 100%;
width: 100%;
z-index: 102;
opacity: 1;
background-color: #333;
transition: all 1s ease;
-webkit-transition: all 1s ease;
-moz-transition: all 1s ease;
}
.hidden {
filter: blur(40px) !important;
-webkit-filter: blur(40px) !important;
opacity: 0 !important;
transition: all .5s ease;
-webkit-transition: all .5s ease;
-moz-transition: all .5s ease;
}
.hidden-overlay {
opacity: 0 !important;
}

20
index.html Normal file
View File

@@ -0,0 +1,20 @@
<!doctype html>
<html>
<head>
<title>Snake</title>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="css/styles.css">
<script src="js/resources.class.js"></script>
<script src="js/snake.class.js"></script>
<script src="js/canvas.class.js"></script>
<script src="js/game.class.js"></script>
<script src="js/snake.js"></script>
</head>
<body id="body">
<canvas id="gameCanvas">
<p class="error">Your browser does not support HTML5 Canvas!</p>
</canvas>
<p id="popup-text">Ready?<br><small><small>Press Space, ESC or P to begin. Those keys also pause/unpause.</small></small></p>
<div id="overlay"></div>
</body>
</html>

68
js/canvas.class.js Normal file
View File

@@ -0,0 +1,68 @@
/**
* Canvas class
*/
var Canvas = function(game, canvasId) {
this.game = game;
this.canvas = document.getElementById(canvasId);
this.context = this.canvas.getContext("2d");
this.canvas.setAttribute('height', window.innerHeight);
this.canvas.setAttribute('width', window.innerWidth);
this.color = "lightgrey";
this.clear();
this.prep();
}
Canvas.prototype.drawAll = function() {
for (var h = 0; h < this.game.grid.height; h++) {
for (var w = 0; w < this.game.grid.width; w++) {
this.context.fillStyle = this.color;
this.context.fillRect(w * this.game.gridSize, h * this.game.gridSize, this.game.gridSize, this.game.gridSize);
for (var i in this.game.snake.locations) {
if (this.game.snake.locations[i][0] === w && this.game.snake.locations[i][1] === h) {
this.context.fillStyle = "purple";
this.context.fillRect(w * this.game.gridSize, h * this.game.gridSize, this.game.gridSize, this.game.gridSize);
}
}
}
}
}
Canvas.prototype.setTile = function(type, x, y) {
switch (type) {
case ('board'):
this.context.fillStyle = this.color;
break;
case ('snake'):
this.context.fillStyle = "purple";
break;
case ('food'):
this.context.fillStyle = "green";
break;
case ('death'):
this.context.fillStyle = "red";
break;
case ('faster'):
this.context.fillStyle = "#708BF4";
break;
case ('slower'):
this.context.fillStyle = "#3135C4";
break;
case ('bonus'):
this.context.fillStyle = "gold";
break;
default:
this.context.fillStyle = this.color;
break;
}
this.context.fillRect(x * this.game.gridSize, y * this.game.gridSize, this.game.gridSize, this.game.gridSize);
}
Canvas.prototype.prep = function() {
this.context.fillStyle = this.color;
this.context.fillRect(0, 0, this.canvas.width, this.canvas.height);
}
Canvas.prototype.clear = function() {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
}

127
js/game.class.js Normal file
View File

@@ -0,0 +1,127 @@
/**
* Game class
*/
var Game = function() {
this.gameover = false;
this.paused = true;
this.gameLoop = null;
this.gameLoopCount = 0;
this.score = 0;
this.speedNormal = 80;
this.speedModifierNormal = 1;
this.speedModifier = 1;
this.effects = {
bonus: 0,
speedChange: 0
};
this.gridSize = 20;
this.grid = {
width: 0,
height: 0
};
this.canvas = new Canvas(this, "gameCanvas");
this.initGrid();
this.snake = new Snake(this);
this.resources = new Resources(this);
}
Game.prototype.initGrid = function() {
this.grid.width = Math.floor(this.canvas.canvas.width / this.gridSize);
this.grid.height = Math.floor(this.canvas.canvas.height / this.gridSize);
}
Game.prototype.start = function() {
this.paused = false;
/* var parent = this;
this.gameLoop = setInterval(function(){
parent.gameLoopCount++;
if (parent.gameLoopCount % (100 / parent.resources.droprateModifier) === 0 || parent.gameLoopCount === 1) {
parent.resources.dropRandom();
}
if (parent.effects.speedChange > 0) {
parent.effects.speedChange--;
} else {
parent.speedModifier = parent.speedModifierNormal;
}
parent.update();
}, 80 / this.speedModifier); */
var parent = this;
var interval = this.speedNormal / this.speedModifier;
function gameLoop() {
if (!parent.paused) {
parent.gameLoopCount++;
if (parent.gameLoopCount % (150 / parent.resources.droprateModifier) === 0 || parent.gameLoopCount === 1) {
parent.resources.dropRandom();
}
if (parent.effects.speedChange > 0) {
parent.effects.speedChange--;
} else {
parent.speedModifier = parent.speedModifierNormal;
}
parent.update();
}
interval = parent.speedNormal / parent.speedModifier;
setTimeout(gameLoop, interval);
}
setTimeout(gameLoop, interval);
}
Game.prototype.update = function() {
this.snake.move();
}
Game.prototype.togglePause = function() {
this.paused = (this.paused ? false : true);
if (this.paused) {
//clearInterval(this.gameLoop);
this.canvas.canvas.style.filter = "blur(40px)";
document.getElementById("popup-text").textContent = "Paused!";
document.getElementById("popup-text").removeAttribute("class");
} else {
this.canvas.canvas.style.filter = "blur(0px)";
document.getElementById("popup-text").setAttribute("class", "hidden");
this.start();
}
}
Game.prototype.applyEffect = function(effect) {
console.log("Effect pickup: " + effect);
switch (effect) {
case ('food'):
console.log("food");
this.score++;
this.snake.embiggen(1);
break;
case ('death'):
console.log("death");
this.end();
break;
case ('faster'):
console.log("faster");
this.speedModifier = 1.7;
this.effects.speedChange = 150;
break;
case ('slower'):
console.log("slower");
this.speedModifier = .6;
this.effects.speedChange = 100;
break;
case ('bonus'):
console.log("bonus");
this.score = this.score + 15;
this.snake.embiggen(5);
break;
}
console.log(this);
}
Game.prototype.end = function() {
this.gameover = true;
clearInterval(this.gameLoop);
this.canvas.canvas.style.transition = "all 1s ease-out";
this.canvas.canvas.style.filter = "blur(20px)";
document.getElementById("popup-text").textContent = "Game over!";
document.getElementById("popup-text").removeAttribute("class");
}

68
js/resources.class.js Normal file
View File

@@ -0,0 +1,68 @@
/**
* Resources class
*/
var Resources = function(game) {
this.game = game;
this.droprateModifier = 5;
this.maxDrops = 100;
this.types = [
'food',
'food',
'food',
'food',
'food',
'food',
'food',
'food',
'food',
'food',
'food',
'food',
'food',
'food',
'food',
'food',
'bonus',
'bonus',
'death',
'death',
'death',
'faster',
'faster',
'faster',
'slower',
'slower'
];
this.locations = [];
}
Resources.prototype.checkLocation = function(x, y) {
for (var i = 0; i < this.locations.length; i++) {
if (this.locations[i][0] === x) {
for (var i = 0; i < this.locations.length; i++) {
if (this.locations[i][0] === x && this.locations[i][1] === y) {
return this.locations[i][2];
}
}
}
}
return null;
}
Resources.prototype.dropRandom = function() {
if (!this.game.paused) {
if (this.locations.length < this.maxDrops) {
var randDrop = this.getRandomInt(0, this.types.length - 1);
var randX = this.getRandomInt(0, this.game.grid.width - 1);
var randY = this.getRandomInt(0, this.game.grid.height - 1);
this.game.canvas.setTile(this.types[randDrop], randX, randY);
this.locations.push([randX, randY, this.types[randDrop]]);
}
}
}
Resources.prototype.getRandomInt = function(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}

101
js/snake.class.js Normal file
View File

@@ -0,0 +1,101 @@
/**
* Snake class
*/
var Snake = function(game) {
this.game = game;
this.length = 3;
this.justEaten = 0;
this.nextDirection = 'up';
this.previousDirection = 'up';
this.locations = [];
for (var i = 0; i < this.length; i++) {
this.locations[i] = [Math.floor(game.grid.width / 2), Math.floor(game.grid.height / 2) + i];
}
}
Snake.prototype.changeDirection = function(direction = '') {
if (direction !== '') {
switch (this.previousDirection) {
case ('up'):
this.nextDirection = (direction === 'down' ? this.nextDirection : direction);
break;
case ('down'):
this.nextDirection = (direction === 'up' ? this.nextDirection : direction);
break;
case ('left'):
this.nextDirection = (direction === 'right' ? this.nextDirection : direction);
break;
case ('right'):
this.nextDirection = (direction === 'left' ? this.nextDirection : direction);
break;
}
}
}
Snake.prototype.move = function() {
if (!this.game.paused && !this.game.gameover) {
switch (this.nextDirection) {
case ('up'):
var newX = this.locations[0][0];
var newY = this.locations[0][1] - 1;
break;
case ('down'):
var newX = this.locations[0][0];
var newY = this.locations[0][1] + 1;
break;
case ('left'):
var newX = this.locations[0][0] - 1;
var newY = this.locations[0][1];
break;
case ('right'):
var newX = this.locations[0][0] + 1;
var newY = this.locations[0][1];
break;
default:
break;
}
this.previousDirection = this.nextDirection;
if (newX > this.game.canvas.width) {
newX = 1;
}
if (newX < this.game.canvas.width) {
newX = this.game.canvas.width - 1;
}
if (newY > this.game.canvas.height) {
newY = 1;
}
if (newY < this.game.canvas.height) {
newY = this.game.canvas.height - 1;
}
var effect = this.game.resources.checkLocation(newX, newY);
if (effect !== null) {
this.game.applyEffect(effect);
}
for (var i = 0; i < this.locations.length; i++) {
if (this.locations[i][0] === newX) {
for (var i = 0; i < this.locations.length; i++) {
if (this.locations[i][0] === newX && this.locations[i][1] === newY) {
this.game.end();
}
}
}
}
if (this.justEaten > 0) {
this.justEaten--;
} else {
this.game.canvas.setTile('board', this.locations[this.locations.length - 1][0], this.locations[this.locations.length - 1][1]);
this.locations.splice(this.locations.length - 1, 1);
}
this.locations.unshift([newX, newY]);
this.game.canvas.setTile('snake', this.locations[0][0], this.locations[0][1]);
}
}
Snake.prototype.embiggen = function(count) {
this.justEaten = count;
}

31
js/snake.js Normal file
View File

@@ -0,0 +1,31 @@
var init = function () {
var game = new Game();
game.canvas.canvas.style.filter = "blur(40px)";
game.canvas.drawAll();
setTimeout(function(){
document.getElementById("overlay").setAttribute("class", "hidden-overlay");
}, 300);
document.onkeydown = checkKey;
function checkKey(e) {
e = e || window.event;
if (e.keyCode == '38') { // up arrow
game.snake.changeDirection((game.paused || game.gameover ? '' : 'up'));
} else if (e.keyCode == '40') { // down arrow
game.snake.changeDirection((game.paused || game.gameover ? '' : 'down'));
} else if (e.keyCode == '37') { // left arrow
game.snake.changeDirection((game.paused || game.gameover ? '' : 'left'));
} else if (e.keyCode == '39') { // right arrow
game.snake.changeDirection((game.paused || game.gameover ? '' : 'right'));
} else if (e.keyCode == '32' || e.keyCode == '27' || e.keyCode == '80') { // spacebar or escape or p
if (!game.gameover) {
game.togglePause();
} else {
location.reload();
}
}
}
};
window.addEventListener('load', init);