Last active
November 12, 2022 17:00
-
-
Save daephx/80be1b2eb2ed5ebd5e253ca460a37f5b to your computer and use it in GitHub Desktop.
[Snake] Snake game as gist #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
{ | |
"scripts": [], | |
"styles": [] | |
} |
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
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>Basic Snake HTML Game</title> | |
<meta charset="UTF-8" /> | |
<style src="style.css"></style> | |
</head> | |
<body> | |
<canvas id="game"></canvas> | |
<script src="script.js"></script> | |
</body> | |
</html> |
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
var canvas = document.getElementById("game"); | |
canvas.width = window.innerWidth; | |
canvas.height = window.innerHeight; | |
var ctx = canvas.getContext("2d"); | |
var gamePaused = false; | |
window.onload = function () { | |
console.clear(); | |
console.log("Starting game..."); | |
}; | |
window.onresize = function () { | |
console.log("resizing window"); | |
resizeCanvas(); | |
}; | |
function resizeCanvas() { | |
canvas.width = window.innerWidth; | |
canvas.height = window.innerHeight; | |
} | |
// "Ctx" is your canvas context | |
// "Width," "Height," and other vars that start with a capital letter are set according | |
// to your canvas size or preference | |
var grid = 16; | |
var count = 0; | |
var snake = { | |
x: 160, | |
y: 160, | |
// Snake velocity. moves one grid length every frame in either the x or y direction | |
dx: grid, | |
dy: 0, | |
// Keep track of all grids the snake body occupies | |
cells: [], | |
// Length of the snake. grows when eating an apple | |
maxCells: 4, | |
}; | |
var apple = { | |
x: 320, | |
y: 320, | |
}; | |
// Get random whole numbers in a specific range | |
// @See https://stackoverflow.com/a/1527820/2124254 | |
function getRandomInt(min, max) { | |
return Math.floor(Math.random() * (max - min)) + min; | |
} | |
// Game loop | |
function loop() { | |
if (gamePaused) return; // <--- stop looping | |
requestAnimationFrame(loop); | |
// Slow game loop: default 60fps (60/4 = 15) | |
if (++count < 6) { | |
return; | |
} | |
count = 0; | |
ctx.clearRect(0, 0, canvas.width, canvas.height); | |
// Move snake by it's velocity | |
snake.x += snake.dx; | |
snake.y += snake.dy; | |
// Wrap snake position horizontally on edge of screen | |
if (snake.x < 0) { | |
snake.x = canvas.width - grid; | |
} else if (snake.x >= canvas.width) { | |
snake.x = 0; | |
} | |
// Wrap snake position vertically on edge of screen | |
if (snake.y < 0) { | |
snake.y = canvas.height - grid; | |
} else if (snake.y >= canvas.height) { | |
snake.y = 0; | |
} | |
// Keep track of where snake has been. front of the array is always the head | |
snake.cells.unshift({ x: snake.x, y: snake.y }); | |
// Remove cells as we move away from them | |
if (snake.cells.length > snake.maxCells) { | |
snake.cells.pop(); | |
} | |
// Draw apple | |
ctx.fillStyle = "red"; | |
ctx.fillRect(apple.x, apple.y, grid - 1, grid - 1); | |
// Draw snake one cell at a time | |
ctx.fillStyle = "green"; | |
snake.cells.forEach(function (cell, index) { | |
// Drawing 1 px smaller than the grid creates a grid effect in the snake body so you can see how long it is | |
ctx.fillRect(cell.x, cell.y, grid - 1, grid - 1); | |
// Snake ate apple | |
if (cell.x === apple.x && cell.y === apple.y) { | |
snake.maxCells++; | |
// Canvas is 400x400 which is 25x25 grids | |
apple.x = getRandomInt(0, 25) * grid; | |
apple.y = getRandomInt(0, 25) * grid; | |
} | |
// Check collision with all cells after this one (modified bubble sort) | |
for (var i = index + 1; i < snake.cells.length; i++) { | |
// Snake occupies same space as a body part. reset game | |
if (cell.x === snake.cells[i].x && cell.y === snake.cells[i].y) { | |
snake.x = 160; | |
snake.y = 160; | |
snake.cells = []; | |
snake.maxCells = 4; | |
snake.dx = grid; | |
snake.dy = 0; | |
apple.x = getRandomInt(0, 25) * grid; | |
apple.y = getRandomInt(0, 25) * grid; | |
} | |
} | |
}); | |
} | |
// listen to keyboard events to move the snake | |
document.addEventListener("keydown", function (e) { | |
// Prevent snake from backtracking on itself by checking that it's | |
// not already moving on the same axis (pressing left while moving | |
// left won't do anything, and pressing right while moving left | |
// shouldn't let you collide with your own body) | |
// Left arrow key | |
if (e.which === 37 && snake.dx === 0) { | |
snake.dx = -grid; | |
snake.dy = 0; | |
} | |
// Up arrow key | |
else if (e.which === 38 && snake.dy === 0) { | |
snake.dy = -grid; | |
snake.dx = 0; | |
} | |
// Right arrow key | |
else if (e.which === 39 && snake.dx === 0) { | |
snake.dx = grid; | |
snake.dy = 0; | |
} | |
// Down arrow key | |
else if (e.which === 40 && snake.dy === 0) { | |
snake.dy = grid; | |
snake.dx = 0; | |
} | |
// Escape Key | |
else if (e.which === 27) { | |
console.log("pause"); | |
if (!gamePaused) { | |
gamePaused = true; | |
} else if (gamePaused) { | |
gamePaused = false; | |
} | |
} | |
}); | |
// Start the game | |
requestAnimationFrame(loop); |
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
body { | |
margin: 0; | |
} | |
body { | |
/* background: black; */ | |
display: flex; | |
/* align-items: center; */ | |
/* justify-content: center; */ | |
} | |
canvas { | |
background: black; | |
/* height: 100vh; */ | |
/* width: 100vw; */ | |
/* max-width: 100%; */ | |
overflow: hidden; | |
/* box-sizing: border-box; */ | |
/* border: 2px solid green; */ | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment