Skip to content

Instantly share code, notes, and snippets.

@ZiKT1229
Forked from straker/README.md
Created November 6, 2018 07:03
Show Gist options
  • Star 25 You must be signed in to star a gist
  • Fork 20 You must be signed in to fork a gist
  • Save ZiKT1229/5935a10ce818ea7b851ea85ecf55b4da to your computer and use it in GitHub Desktop.
Save ZiKT1229/5935a10ce818ea7b851ea85ecf55b4da to your computer and use it in GitHub Desktop.
Basic Snake HTML Game

Basic Snake HTML Game

Snake is a fun game to make as it doesn't require a lot of code (less than 100 lines with all comments removed). This is a basic implementation of the snake game, but it's missing a few things intentionally and they're left as further exploration for the reader.

Further Exploration

  • Score
    • When the snake eats an apple, the score should increase by one. Use context.fillText() to display the score to the screen
  • Mobile and touchscreen support
  • Better apple spawning
    • Currently the apple spawns in any random grid in the game, even if the snake is already on that spot. Improve it so it only spanws in empty grid locations
<!DOCTYPE html>
<html>
<head>
<title></title>
<style>
html, body {
height: 100%;
margin: 0;
}
body {
background: black;
display: flex;
align-items: center;
justify-content: center;
}
canvas {
border: 1px solid white;
}
</style>
</head>
<body>
<canvas width="400" height="400" id="game"></canvas>
<script>
var canvas = document.getElementById('game');
var context = canvas.getContext('2d');
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() {
requestAnimationFrame(loop);
// slow game loop to 15 fps instead of 60 (60/15 = 4)
if (++count < 4) {
return;
}
count = 0;
context.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
context.fillStyle = 'red';
context.fillRect(apple.x, apple.y, grid-1, grid-1);
// draw snake one cell at a time
context.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
context.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;
}
});
// start the game
requestAnimationFrame(loop);
</script>
</body>
</html>
@AzeemRehman22
Copy link

nice bro

@CorneliusChristian
Copy link

thanks bro

@CorneliusChristian
Copy link

hi i will use it for testing :)

@ChoedanKal
Copy link

Nice!

@JanluOfficial
Copy link

I may as well turn this into a desktop app xD

@dr-bonez
Copy link

@ZiKT1229 how are you licensing this code?

@davetheminecrafter1
Copy link

this is so cool

@Wozski
Copy link

Wozski commented Apr 25, 2022

It is Awesome!!

@GraysonPit
Copy link

How do I implement the score?

@CorvoBonk
Copy link

Brilliant.

@3koZQLkz7n
Copy link

Can someone tell me how to implement a score counter and a high score??? i am using notepad++ btw

@J-zinu
Copy link

J-zinu commented Jul 28, 2022

nice

@noc1357
Copy link

noc1357 commented Sep 6, 2022

how make a score btw?

@QuickMash
Copy link

You could create a counter using JavaScript.

@schoolgamer1239
Copy link

bruh I JUST FOOLED ALL MY FRIENDSS WITH THIS CODE

@J0513-301
Copy link

Hey! Quick question, any way to change the amount of apples spawning?

Thanks a lot!

Hey, I wanted to just say, you can make another by creating a second variable (perhaps var apple2)? and wherever you see the first apple included in the code, just duplicate it and change it to apple 2. Hope this helps =)

@J0513-301
Copy link

J0513-301 commented Jan 13, 2023

how make a score btw?

(I'm not sure if this code depends on the platform you use)
I made a score like this..
div class="container"
span id="score" class="score"
0
/span
div class="words"
div class="center"
Apples eaten /div
/div
/div
(The "<" symbols made text disappear for whatever reason so just pretend the divs and spans have "<" around them)
And the JS looks like this:
var oldScore = 0; function addOldScore() { if (score > oldScore) { oldScore = score; alert ("New high score! " + oldScore); //I did an alert but you can make a custom score } else { //Whatever you want when their score didn't beat their old score } } var resetScore = function() { score = 0; renderScore(); } var score = 0; var scoreElement = document.querySelector( '.score' ); var addPoint = function() { score++; renderScore(); } var renderScore = function() { scoreElement.innerHTML = score; }
And in this if statement(if (cell.x === snake.cells[i].x && cell.y === snake.cells[i].y )), add this:
addOldScore(); resetScore();
Let me know if there are any issues =)

@someshwarholkar
Copy link

how to control its speed
// slow game loop to 15 fps instead of 60 (60/15 = 4)
if (++count < 4) {
return;
}
increases this value 4(8)

@jsinc-sebastian
Copy link

Just shows a black BG with corners

@Qweenfumzy20
Copy link

How do I set it to tell the player if it win or lose

@AnkanTheCoder
Copy link

How do I control it(keys)?

@J0513-301
Copy link

How do I control it(keys)?

It should have arrow key controls already, the code is there. Just use up, down, left, right

@bodizeno
Copy link

wow cool

@ZuuZoo
Copy link

ZuuZoo commented Nov 9, 2023

How can i change that to everytime when the snake ates a apple it's spawns a new delayed and i don't want the delay. How can i fix that?

@J0513-301
Copy link

J0513-301 commented Nov 9, 2023

How do I set it to tell the player if it win or lose

So In the code there’s a function (this one): `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;
  } `

So after snake.dy = 0; the game is restarting so you can put anything after that line to make it show the player won or lost. I suggest making a div that is blank from the start and then the game restart function makes the div equal to a specific text such as you died. To make a you won screen you would have to implement a few more things depending on what you consider as winning. Let me know if you need any more help

@ImthySafa
Copy link

Nice bro

@svenwlive
Copy link

Please help me with adding the score to the game. I'm not very good with programming, so im hoping someone is able to at least show me anything.
image
currently it looks something like this.

@J0513-301
Copy link

Please help me with adding the score to the game. I'm not very good with programming, so im hoping someone is able to at least show me anything.
image
currently it looks something like this.

So the picture is what it’s supposed to look like, so you are on the right track. Can you let me know what Software your using to place the code in? That way I know how to better assist you, and you can also check my previous comments and replies as I have answered similar questions before. Let me know =]

@svenwlive
Copy link

Please help me with adding the score to the game. I'm not very good with programming, so im hoping someone is able to at least show me anything.
image
currently it looks something like this.

So the picture is what it’s supposed to look like, so you are on the right track. Can you let me know what Software your using to place the code in? That way I know how to better assist you, and you can also check my previous comments and replies as I have answered similar questions before. Let me know =]

Im using VS Code connected to GitHub with codespaces.

@NwDEVIN
Copy link

NwDEVIN commented Apr 11, 2024

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment