<div id="wrapper">
<!-- Header -->
<h1 class="snake-title">Snake</h1>
<p class="snake-p">Use keyboard arrows or buttons.<br><br>1. Hitting walls is a no-no.<br>2. Don't eat yourself.<br>3. Traveling backwards is a no-no too.<br>4. Everytime you fail it's faster.</p>
<!-- Menu Container -->
<br>
<p class="snake-high-score-p">High-score</p>
<p class="snake-high-score">0</p>
<div id="menu-container">
<button class="menu-play-button" onClick="playGame()">Play</button>
</div>
<!-- Game Container -->
<div id="game-container">
<!-- Score -->
<p class="snake-score-p">Score</p>
<p class="snake-score">0</p>
<!-- Canvas, the Game -->
<canvas id="snakeGame" width="400" height="400">
</canvas>
<!-- Controls -->
<div class="controls">
<div class="control-button" id="left" onClick="Left()"><i class="fas fa-2x fa-arrow-left"></i></div>
<div class="control-button" id="up" onClick="Up()"><i class="fas fa-2x fa-arrow-up"></i></div>
<div class="control-button" id="down" onClick="Down()"><i class="fas fa-2x fa-arrow-down"></i></div>
<div class="control-button" id="right" onClick="Right()"><i class="fas fa-2x fa-arrow-right"></i></div>
</div>
</div>
<!-- Game Over Container -->
<div id="game-over-container">
<h1 class="game-over-title">Game Over</h1>
<button class="game-over-play-button" onClick="playGame()">Play Again</button>
</div>
</div>
/* Fonts */
@import 'https://fonts.googleapis.com/css?family=Press+Start+2P';
body {
margin: 0;
padding: 0;
font-family: 'Press Start 2P';
}
#wrapper {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
-webkit-box-shadow:inset 0px 0px 0px 20px #9b4637;
-moz-box-shadow:inset 0px 0px 0px 20px #9b4637;
box-shadow:inset 0px 0px 0px 20px #9b4637;
background-color: #16161a;
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
}
/* Menu Container */
#menu-container {
height: 50px;
width: 200px;
background-color: none;
display: flex;
align-items: center;
justify-content: center;
}
.menu-play-button {
font-size: 1.5rem;
font-family: 'Press Start 2P';
background-color: transparent;
border: none;
color: #fff;
text-decoration: underline;
cursor: pointer;
}
/* Game Container */
#game-container {
text-align: center;
}
.snake-title {
color: #9b4637;
font: 300 2em 'Press Start 2P', serif;
margin: 0 auto;
}
.snake-p {
color: #d58e5e;
margin-bottom: 0;
}
.snake {
width: 80px;
height: 20px;
background-color: #fff;
}
.snake-score-p, .snake-high-score-p {
color: #d58e5e;
text-decoration: underline;
}
.snake-score, .snake-high-score {
color: #fff;
margin: 0 auto;
margin-bottom: 10px;
font-size: 2rem;
}
#snakeGame {
background-color: #9b4637;
margin: 0 auto;
align-self: center;
order: 1;
border: 20px solid #d58e5e;
}
/* Control Buttons */
.controls {
margin-top: 30px;
display: flex;
order: 2;
}
.control-button {
width: 50px;
height: 50px;
background-color: #d58e5e;
margin: 0px auto;
color: #9b4637;
display: flex;
align-items: center;
cursor: pointer;
transition: s background-color ease, 0.5s color ease;
box-shadow: 0px 5px 0px #9b4637;
}
.control-button:hover {
background-color: #9b4637;
color: #d58e5e;
}
.control-button i {
margin: 0 auto;
}
/* Game Over Container */
#game-over-container {
text-align: center;
}
.game-over-title {
color: #fff;
font: 300 2em 'Press Start 2P', serif;
}
.game-over-play-button {
font-size: 1.5rem;
color: #9b4637;
font-family: 'Press Start 2P';
background-color: transparent;
border: none;
text-decoration: underline;
cursor: pointer;
}
$("#game-container").hide();
$("#game-over-container").hide();
function hideMenu() {
$(".snake-title").hide();
$(".snake-p").hide();
$("#menu-container").hide();
$(".snake-high-score-p").hide();
$(".snake-high-score").hide();
$("#game-over-container").hide();
}
function hideGame() {
$(".snake-title").hide();
$(".snake-p").hide();
$("#game-container").hide();
$("#game-over-container").show();
}
function playGame() {
hideMenu();
$("#game-over-container").hide();
$("#game-container").show();
// Draw
const canvas = document.querySelector("#snakeGame");
const ctx = canvas.getContext("2d");
const scale = 20;
const rows = canvas.height / scale;
const columns = canvas.width / scale;
// Snake Colour
const snakeColour = "#fff";
// Fruit Colour
const fruitColour = "#deb520";
// Score
const score = 0;
// Setup
(function setup() {
snake = new Snake();
fruit = new Fruit();
fruit.pickLocation();
window.setInterval(() => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
fruit.draw();
snake.update();
snake.draw();
// Eat Fruit
if (snake.eat(fruit)) {
fruit.pickLocation();
}
document.querySelector('.snake-score').innerText = snake.total;
snake.checkCollision();
}, 250);
})();
// Key Listener
window.addEventListener("keydown", evt => {
const direction = evt.key.replace("Arrow", "");
snake.changeDirection(direction);
});
// Snake
function Snake() {
this.x = 0;
this.y = 0;
this.xSpeed = scale;
this.ySpeed = 0;
this.total = 0;
this.tail = [];
// Draw Snake
this.draw = function() {
ctx.fillStyle = snakeColour;
for (let i=0; i<this.tail.length; i++) {
ctx.fillRect(this.tail[i].x, this.tail[i].y, scale, scale);
}
ctx.fillRect(this.x, this.y, scale, scale);
};
// Update Snake
this.update = function() {
for (let i=0; i<this.tail.length - 1; i++) {
this.tail[i] = this.tail[i+1];
}
this.tail[this.total - 1] = { x: this.x, y: this.y };
this.x += this.xSpeed;
this.y += this.ySpeed;
if (this.x > canvas.width) {
this.total = 0;
this.tail = [];
this.x = 0;
this.y = 0;
this.x += this.xSpeed;
hideGame();
}
if (this.y > canvas.height) {
this.total = 0;
this.tail = [];
this.x = 0;
this.y = 0;
this.x += this.xSpeed;
hideGame();
}
if (this.x < 0) {
this.total = 0;
this.tail = [];
this.x = 0;
this.y = 0;
this.x += this.xSpeed;
hideGame();
}
if (this.y < 0) {
this.total = 0;
this.tail = [];
this.x = 0;
this.y = 0;
this.x += this.xSpeed;
hideGame();
}
};
// Change Direction
this.changeDirection = function(direction) {
switch (direction) {
case "Up":
this.xSpeed = 0;
this.ySpeed = -scale * 1;
break;
case "Down":
this.xSpeed = 0;
this.ySpeed = scale * 1;
break;
case "Left":
this.xSpeed = -scale * 1;
this.ySpeed = 0;
break;
case "Right":
this.xSpeed = scale * 1;
this.ySpeed = 0;
break;
}
};
// Snake Eats
this.eat = function(fruit) {
if (this.x === fruit.x && this.y === fruit.y) {
this.total++;
return true;
}
};
// Check Collision
this.checkCollision = function() {
for (var i=0; i<this.tail.length; i++) {
if (this.x === this.tail[i].x && this.y === this.tail[i].y) {
console.log("Coliding");
this.total = 0;
this.tail = [];
this.x = 0;
this.y = 0;
hideGame();
}
}
}
}
// Button Controls
function Up() {
snake.xSpeed = 0;
snake.ySpeed = -scale * 1;
}
function Down() {
snake.xSpeed = 0;
snake.ySpeed = scale * 1;
}
function Left() {
snake.xSpeed = -scale * 1;
snake.ySpeed = 0;
}
function Right() {
snake.xSpeed = scale * 1;
snake.ySpeed = 0;
}
// Fruit
function Fruit() {
this.x;
this.y;
this.pickLocation = function() {
this.x = (Math.floor(Math.random() * rows - 1) + 1) * scale;
this.y = (Math.floor(Math.random() * columns - 1) + 1) * scale;
}
this.draw = function() {
ctx.fillStyle = fruitColour;
ctx.fillRect(this.x, this.y, scale, scale);
}
}
}