Skip to content

Instantly share code, notes, and snippets.

@straker straker/README.md
Last active Jun 12, 2019

Embed
What would you like to do?
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

License

(CC0 1.0 Universal) You're free to use this game and code in any project, personal or commercial. There's no need to ask permission before using these. Giving attribution is not required, but appreciated.

<!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>
@iammanmohit

This comment has been minimized.

Copy link

commented Mar 18, 2018

Wow!!! It's GREAT!!!

@GandalfTheGinger

This comment has been minimized.

Copy link

commented Mar 23, 2018

There is a problem when I hit the wall I don't die so could you fix that in some way and could you tell me how you fixed cause i'm curious

@yotamefr

This comment has been minimized.

Copy link

commented Mar 26, 2018

GandalfTheGinger it's not a bug. That's how the original game was, I'm pretty sure.

@Mr-Alpheous

This comment has been minimized.

Copy link

commented Apr 4, 2018

woooow wow it nice but score is missing

@Tigermagooster

This comment has been minimized.

Copy link

commented Apr 6, 2018

How to control?

@SawyerBx

This comment has been minimized.

Copy link

commented Apr 14, 2018

Could you add a way to control it on mobile?

@andrewreed549

This comment has been minimized.

Copy link

commented May 9, 2018

heres the mobile code

<title>snake</title> <style>

body {
background:blue;
}
canvas {
border:3px solid;
background:#efe;
}

.control {
position:relative;
border-radius:10px;
width:70px;
height:30px;
bottom:-30px;
}

button {
outline:0;
}
</style>

<script> var canvas = document.getElementById('game'); var context = canvas.getContext('2d'); var grid = 10; var colors = "rgb(" +Math.floor(Math.random() * 226) +"," +Math.floor(Math.random() * 226) +"," +Math.floor(Math.random() * 226) +")"; var snake = { x: 160, y: 160, dx: grid, dy: 0, cells: [], maxCells: 4 }; var count = 0; var apple = { x: 320, y: 320 }; function getRandomInt(min, max) { return Math.floor(Math.random() * (max - min)) + min; } function loop() { requestAnimationFrame(loop); if (++count < 7) { return; } count = 0; context.clearRect(0,0,canvas.width,canvas.height); snake.x += snake.dx; snake.y += snake.dy; // wrap snake position on edge of screen if (snake.x < 0) { snake.x = canvas.width - grid; } else if (snake.x >= canvas.width) { snake.x = 0; } if (snake.y < 0) { snake.y = canvas.height - grid; } else if (snake.y >= canvas.height) { snake.y = 0; } snake.cells.unshift({x: snake.x, y: snake.y}); if (snake.cells.length > snake.maxCells) { snake.cells.pop(); } context.fillStyle = 'green'; context.fillRect(apple.x, apple.y, grid-1, grid-1) context.fillStyle = colors; snake.cells.forEach(function(cell, index) { context.fillRect(cell.x, cell.y, grid-1, grid-1); if (cell.x === apple.x && cell.y === apple.y) { snake.maxCells++; apple.x = getRandomInt(0, 30) * grid; apple.y = getRandomInt(0, 30) * grid; } for (var i = index + 1; i < snake.cells.length; i++) { if (cell.x === snake.cells[i].x && cell.y === snake.cells[i].y) { alert("you lose, your score is") alert(snake.maxCells) colors = "rgb(" +Math.floor(Math.random() * 226) +"," +Math.floor(Math.random() * 226) +"," +Math.floor(Math.random() * 226) +")"; 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; } } }); } function left(){ if (snake.dx === 0) { snake.dx = -grid; snake.dy = 0; } } function up(){ if ( snake.dy === 0) { snake.dy = -grid; snake.dx = 0; } } function right(){ if ( snake.dx === 0) { snake.dx = grid; snake.dy = 0; } } function down(){ if (snake.dy === 0) { snake.dy = grid; snake.dx = 0; } } function hack(){ if (snake.maxCells){ snake.maxCells++; } } function hackd(){ if (snake.maxCells){ colors = "rgb(" +Math.floor(Math.random() * 226) +"," +Math.floor(Math.random() * 226) +"," +Math.floor(Math.random() * 226) +")"; } } function hacku(){ if (snake.maxCells){ apple.x = getRandomInt(0, 25) * grid; apple.y = getRandomInt(0, 25) * grid; } } document.addEventListener('keydown', function(e) { // prevent snake from backtracking on itself if (e.which === 37 && snake.dx === 0) { snake.dx = -grid; snake.dy = 0; } else if (e.which === 38 && snake.dy === 0) { snake.dy = -grid; snake.dx = 0; } else if (e.which === 39 && snake.dx === 0) { snake.dx = grid; snake.dy = 0; } else if (e.which === 40 && snake.dy === 0) { snake.dy = grid; snake.dx = 0; } requestAnimationFrame(loop); </script>
@GandalfTheGinger

This comment has been minimized.

Copy link

commented May 14, 2018

could you please add the scoring

@HenryAkaya

This comment has been minimized.

Copy link

commented May 24, 2018

heres the mobile code

<title>snake</title> <style> body { background:blue; } canvas { border:3px solid; background:#efe; }

.control {
position:relative;
border-radius:10px;
width:70px;
height:30px;
bottom:-30px;
}

button {
outline:0;
}
</style>

<script> var canvas = document.getElementById('game'); var context = canvas.getContext('2d'); var grid = 10; var colors = "rgb(" +Math.floor(Math.random() * 226) +"," +Math.floor(Math.random() * 226) +"," +Math.floor(Math.random() * 226) +")"; var snake = { x: 160, y: 160, dx: grid, dy: 0, cells: [], maxCells: 4 }; var count = 0; var apple = { x: 320, y: 320 }; function getRandomInt(min, max) { return Math.floor(Math.random() * (max - min)) + min; } function loop() { requestAnimationFrame(loop); if (++count < 7) { return; } count = 0; context.clearRect(0,0,canvas.width,canvas.height); snake.x += snake.dx; snake.y += snake.dy; // wrap snake position on edge of screen if (snake.x < 0) { snake.x = canvas.width - grid; } else if (snake.x >= canvas.width) { snake.x = 0; } if (snake.y < 0) { snake.y = canvas.height - grid; } else if (snake.y >= canvas.height) { snake.y = 0; } snake.cells.unshift({x: snake.x, y: snake.y}); if (snake.cells.length > snake.maxCells) { snake.cells.pop(); } context.fillStyle = 'green'; context.fillRect(apple.x, apple.y, grid-1, grid-1) context.fillStyle = colors; snake.cells.forEach(function(cell, index) { context.fillRect(cell.x, cell.y, grid-1, grid-1); if (cell.x === apple.x && cell.y === apple.y) { snake.maxCells++; apple.x = getRandomInt(0, 30) * grid; apple.y = getRandomInt(0, 30) * grid; } for (var i = index + 1; i < snake.cells.length; i++) { if (cell.x === snake.cells[i].x && cell.y === snake.cells[i].y) { alert("you lose, your score is") alert(snake.maxCells) colors = "rgb(" +Math.floor(Math.random() * 226) +"," +Math.floor(Math.random() * 226) +"," +Math.floor(Math.random() * 226) +")"; 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; } } }); } function left(){ if (snake.dx === 0) { snake.dx = -grid; snake.dy = 0; } } function up(){ if ( snake.dy === 0) { snake.dy = -grid; snake.dx = 0; } } function right(){ if ( snake.dx === 0) { snake.dx = grid; snake.dy = 0; } } function down(){ if (snake.dy === 0) { snake.dy = grid; snake.dx = 0; } } function hack(){ if (snake.maxCells){ snake.maxCells++; } } function hackd(){ if (snake.maxCells){ colors = "rgb(" +Math.floor(Math.random() * 226) +"," +Math.floor(Math.random() * 226) +"," +Math.floor(Math.random() * 226) +")"; } } function hacku(){ if (snake.maxCells){ apple.x = getRandomInt(0, 25) * grid; apple.y = getRandomInt(0, 25) * grid; } } document.addEventListener('keydown', function(e) { // prevent snake from backtracking on itself if (e.which === 37 && snake.dx === 0) { snake.dx = -grid; snake.dy = 0; } else if (e.which === 38 && snake.dy === 0) { snake.dy = -grid; snake.dx = 0; } else if (e.which === 39 && snake.dx === 0) { snake.dx = grid; snake.dy = 0; } else if (e.which === 40 && snake.dy === 0) { snake.dy = grid; snake.dx = 0; } requestAnimationFrame(loop); </script>

@andrewreed549
This code for mobile did not work.

@dehuachen

This comment has been minimized.

Copy link

commented May 25, 2018

@HenryAkaya @SawyerBx
Here is a mobile version:

<!DOCTYPE html>
<html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title></title>
  <style>
  html, body {
    height: 100%;
    margin: 0;
  }

  body {
    background: black;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow-y: hidden;
  }
  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 snake = {
  x: 160,
  y: 160,
  dx: grid,
  dy: 0,
  cells: [],
  maxCells: 4
};
var count = 0;
var apple = {
  x: 320,
  y: 320
};

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);

  snake.x += snake.dx;
  snake.y += snake.dy;

  // wrap snake position on edge of screen
  if (snake.x < 0) {
    snake.x = canvas.width - grid;
  }
  else if (snake.x >= canvas.width) {
    snake.x = 0;
  }

  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
  context.fillStyle = 'green';
  snake.cells.forEach(function(cell, index) {
    context.fillRect(cell.x, cell.y, grid-1, grid-1);

    // snake ate apple
    if (cell.x === apple.x && cell.y === apple.y) {
      snake.maxCells++;

      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++) {
      
      // collision. 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;
      }
    }
  });
}

var allowedTime = 200;
var startX = 0;
var startY = 0;

document.addEventListener('touchstart', function(e){
    var touch = e.changedTouches[0]
    startX = touch.pageX
    startY = touch.pageY
    startTime = new Date().getTime()
    e.preventDefault()
}, false)

document.addEventListener('touchmove', function(e){
    e.preventDefault()
}, false)

document.addEventListener('touchend', function(e){
    var touch = e.changedTouches[0]
    distX = touch.pageX - startX
    distY = touch.pageY - startY

    if (Math.abs(distX) > Math.abs(distY)) {
      if (distX > 0 && snake.dx === 0) {
        snake.dx = grid;
        snake.dy = 0;
      }
      else if (distX < 0 && snake.dx === 0) {
        snake.dx = -grid;
        snake.dy = 0;
      }
    } else {
      if (distY > 0 && snake.dy === 0) {
        snake.dy = grid;
        snake.dx = 0;
      }
      else if (distY < 0 && snake.dy === 0) {
        snake.dy = -grid;
        snake.dx = 0;
      }
    }
    e.preventDefault();

}, false)

document.addEventListener('keydown', function(e) {
  // prevent snake from backtracking on itself
  if (e.which === 37 && snake.dx === 0) {
    snake.dx = -grid;
    snake.dy = 0;
  }
  else if (e.which === 38 && snake.dy === 0) {
    snake.dy = -grid;
    snake.dx = 0;
  }
  else if (e.which === 39 && snake.dx === 0) {
    snake.dx = grid;
    snake.dy = 0;
  }
  else if (e.which === 40 && snake.dy === 0) {
    snake.dy = grid;
    snake.dx = 0;
  }
});

requestAnimationFrame(loop);
</script>
</body>
</html>
@Bluwinters

This comment has been minimized.

Copy link

commented Jun 5, 2018

How does the computer know the input for the snake movement what line of code was that

@ericsondevan

This comment has been minimized.

Copy link

commented Jun 30, 2018

it is nice but i need help on how to add score and pause button.

@JesseBS2

This comment has been minimized.

Copy link

commented Sep 7, 2018

@Bluwinters

It’s practically the last line of JavaScript code, right above the final requestAnimationFrame(loop)
key up:
`document.addEventListener('keydown', function(e){

if(e.which == 37){
snake.dy= -grid;
snake.dx = 0;
}

})`

that code is all correct(Although 37 Might not be the Up arrow, It could also be Left, Right or Down)

@subeshb1

This comment has been minimized.

Copy link

commented Oct 4, 2018

@Jackolanturn0

This comment has been minimized.

Copy link

commented Oct 23, 2018

I am a beginner at coding, and lots of times I base my code off of this code. It's awesome!

@Smt1195

This comment has been minimized.

Copy link

commented Nov 9, 2018

woooow wow it nice but score is missing

@Smt1195

This comment has been minimized.

Copy link

commented Nov 9, 2018

Copy this and enjoy. It has score an highscore added to it

<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; } #p1 { color:red; position:absolute; left:100px; top:10px; } #p2 { color:red; position:absolute; left:100px; top:30px; } #score { color:yellow; position:absolute; left:155px; top:10px; } #high { color:yellow; position:absolute; left:195px; top:30px; } </style>

SCORE:

HIGHSCORE:

<script> var canvas = document.getElementById('game'); var context = canvas.getContext('2d'); var grid = 16; var count = 0; var score=0; var max=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++;
  score+=10;
  //max=score;
  document.getElementById('score').innerHTML=score;

  // 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) 
 { 
 
    if(score>max)
    {
     max=score;
    }
	snake.x = 160;
    snake.y = 160;
    snake.cells = [];
    snake.maxCells = 4;
    snake.dx = grid;
    snake.dy = 0;
	score=0;
    apple.x = getRandomInt(0, 25) * grid;
    apple.y = getRandomInt(0, 25) * grid;
    document.getElementById('high').innerHTML=max;
  }
}

}

);

}
// 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>

@noamboy2006

This comment has been minimized.

Copy link

commented Nov 18, 2018

<script> var canvas = document.getElementById('game'); var context = canvas.getContext('2d'); var grid = 16; var count = 0; var snake = { x: 160, y: 160, dx: grid, dy: 0, cells: [], maxCells: 4 }; var apple = { x: 320, y: 320 }; function getRandomInt(min, max) { return Math.floor(Math.random() * (max - min)) + min; } function loop() { requestAnimationFrame(loop); if (++count < 4) { return; } count = 0; context.clearRect(0,0,canvas.width,canvas.height); snake.x += snake.dx; snake.y += snake.dy; if (snake.x < 0) { snake.x = canvas.width - grid; } else if (snake.x >= canvas.width) { snake.x = 0; } if (snake.y < 0) { snake.y = canvas.height - grid; } else if (snake.y >= canvas.height) { snake.y = 0; } snake.cells.unshift({x: snake.x, y: snake.y}); if (snake.cells.length > snake.maxCells) { snake.cells.pop(); } context.fillStyle = 'red'; context.fillRect(apple.x, apple.y, grid-1, grid-1); context.fillStyle = 'green'; snake.cells.forEach(function(cell, index) { context.fillRect(cell.x, cell.y, grid-1, grid-1); if (cell.x === apple.x && cell.y === apple.y) { snake.maxCells++; apple.x = getRandomInt(0, 25) * grid; apple.y = getRandomInt(0, 25) * grid; } for (var i = index + 1; i < snake.cells.length; i++) { if (cell.x === snake.cells[i].x && cell.y === snake.cells[i].y) { alert((snake.maxcells-4)+"점"); 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; } } }); } document.addEventListener('keydown', function(e) { if (e.which === 37 && snake.dx === 0) { snake.dx = -grid; snake.dy = 0; } else if (e.which === 38 && snake.dy === 0) { snake.dy = -grid; snake.dx = 0; } else if (e.which === 39 && snake.dx === 0) { snake.dx = grid; snake.dy = 0; } else if (e.which === 40 && snake.dy === 0) { snake.dy = grid; snake.dx = 0; } }); requestAnimationFrame(loop); </script>

score is here

@JesseBS2

This comment has been minimized.

Copy link

commented Nov 20, 2018

@straker Hello! I am a big fan of this, project. I actually created an AI in pure javaScript to beat the game(because I stink at snake), it still has it's fair share of glitches, and hasn't once beaten the game, but I would still really like it if you checked out the repository here: https://github.com/JesseBS2/Snake-Ai

@nedwar01

This comment has been minimized.

Copy link

commented Nov 26, 2018

Beautiful! Thanks for this guys

@Mubarak1234

This comment has been minimized.

Copy link

commented Jan 11, 2019

Hi
how to add score in snake on HTML.
tell me

@ismailmuktar

This comment has been minimized.

Copy link

commented Jan 13, 2019

thanks so much.

@firdous1

This comment has been minimized.

Copy link

commented Mar 7, 2019

<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> <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>

@HTMLstar1325

This comment has been minimized.

Copy link

commented Apr 1, 2019

It's great! it is a little too fast to move around without missing the `apples.

@kylecumber

This comment has been minimized.

Copy link

commented May 1, 2019

so this was coded in html javasctript

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.