Last active
March 28, 2018 18:21
-
-
Save mmaltsev/a6e4746127c4145c18e87c4e0ee1e0b9 to your computer and use it in GitHub Desktop.
Snake Game
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<style> | |
#overlay { | |
position: absolute; | |
width: 400px; | |
height: 400px; | |
background-color: gray; | |
opacity: 0.8; | |
font-size: 70px; | |
font-weight: 800; | |
color: white; | |
text-align: center; | |
line-height: 400px; | |
cursor: default; | |
font-family: fantasy | |
} | |
#head { | |
font-size: 20px; | |
font-family: monospace; | |
margin-bottom: 10px; | |
} | |
</style> | |
<div id="head"><div id="score-wrap">Score: <span id="score"></span></div></div> | |
<div id="overlay"></div> | |
<canvas id="gameInterface" width="400" height="400"></ canvas> | |
<script> | |
window.onload = function() { | |
canvasElement = document.getElementById('gameInterface') | |
overlayElement = document.getElementById('overlay') | |
overlayElement.style.display = 'none' | |
overlayElement.innerText = 'l l' | |
canvasContext = canvasElement.getContext('2d') | |
document.addEventListener('keydown', keyPush) | |
gameAction = setInterval(game, 100) | |
} | |
// Initializing constants and global variables | |
headPosition = { x: 10, y: 10 } | |
gridSize = 20 | |
cellSIze = 20 | |
edgeCoordinates = { x: 20, y: 20 } | |
fruitPosition = { x: 15, y: 15 } | |
step = { x: 1, y: 0 } | |
tail = 5 | |
gameSpeed = 1 | |
score = 0 | |
setScore() | |
trail = [] | |
// Snake movement | |
function game() { | |
headPosition.x += step.x | |
headPosition.y += step.y | |
// Handling snake getting to the edge of the field | |
if (headPosition.x < 0) headPosition.x = gridSize - 1 | |
if (headPosition.x > gridSize - 1) headPosition.x = 0 | |
if (headPosition.y < 0) headPosition.y = gridSize - 1 | |
if (headPosition.y > gridSize - 1) headPosition.y = 0 | |
// Outlining the game field | |
canvasContext.fillStyle = 'darkgreen' | |
canvasContext.fillRect(0, 0, canvasElement.width, canvasElement.height) | |
// Outlining the snake | |
canvasContext.fillStyle = 'black' | |
for (var i = 0 ; i < trail.length; i++) { | |
canvasContext.fillRect(trail[i].x * cellSIze, trail[i].y * cellSIze, cellSIze - 2, cellSIze - 2) | |
if (trail[i].x == headPosition.x && trail[i].y == headPosition.y) { | |
tail = 5 | |
gameSpeed = 1 | |
score = 0 | |
trail = [] | |
gameOver() | |
//setNewGameSpeed() | |
} | |
} | |
trail.push({ x: headPosition.x, y: headPosition.y }) | |
while (trail.length > tail) { | |
trail.shift() | |
} | |
// Handling fruit eating | |
if (fruitPosition.x == headPosition.x && fruitPosition.y == headPosition.y) { | |
tail++ | |
score ++ | |
gameSpeed += 0.05 | |
setScore() | |
setNewGameSpeed() | |
// Generating new fruit position | |
while (isInTrail(fruitPosition.x, 'x') && isInTrail(fruitPosition.y, 'y')) { | |
fruitPosition.x = Math.floor(Math.random() * gridSize) | |
fruitPosition.y = Math.floor(Math.random() * gridSize) | |
} | |
} | |
// Outlining the fruit | |
canvasContext.fillStyle = 'gray' | |
canvasContext.fillRect(fruitPosition.x * cellSIze, fruitPosition.y * cellSIze, cellSIze - 2, cellSIze - 2) | |
} | |
function gameOver() { | |
setScore() | |
clearInterval(gameAction) | |
setTimeout(function() { | |
setNewGameSpeed() | |
}, 1000) | |
} | |
function isInTrail(val, key) { | |
for (let piece of trail) | |
if (piece[key] === val) | |
return true | |
return false | |
} | |
function setNewGameSpeed() { | |
clearInterval(gameAction) | |
gameAction = setInterval(game, 100 / gameSpeed) | |
} | |
function setScore() { | |
document.getElementById('score').innerText = score | |
} | |
function keyPush(evt) { | |
switch(evt.keyCode) { | |
case 37: // left arrow | |
step.x = -1 | |
step.y = 0 | |
break | |
case 38: // up arrow | |
step.x = 0 | |
step.y = -1 | |
break | |
case 39: // right arrow | |
step.x = 1 | |
step.y = 0 | |
break | |
case 40: // down arrow | |
step.x = 0 | |
step.y = 1 | |
break | |
case 32: // space | |
if (overlayElement.style.display === 'none') { | |
clearInterval(gameAction) | |
overlayElement.style.display = 'initial' | |
} else if (overlayElement.style.display === 'initial') { | |
overlayElement.style.display = 'none' | |
gameAction = setInterval(game, 100 / gameSpeed) | |
} | |
break | |
} | |
} | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment