TheBeta
Search
K
Comment on page

Snake project

Instructions

1. Create canvas

<canvas id="canvas" width="400" height="400"></canvas>

2. Check created correctly. Explain variables. Case is important

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const width = 400;
const height = 400;
// other way of declaring variable is let. will explain later
ctx.fillStyle = "white";
ctx.fillRect(0, 0, width, height);
ctx.strokeStyle = "black";
ctx.strokeRect(0, 0, width, height);

3. Function

function drawBoard(){
// alert("Hello");
ctx.fillStyle = "white";
ctx.fillRect(0, 0, width, height);
ctx.strokeStyle = "black";
ctx.strokeRect(0, 0, width, height);
}
drawBoard();

4. Paint a cell. Demo in Paint what will do

  • Resize canvas
  • Draw 2d shape. Line type and fill
const cw = 10; // cell width
function paintCell(x, y){
ctx.fillStyle = "blue";
ctx.fillRect(x*cw, y*cw, cw, cw);
ctx.strokeStyle = "white";
ctx.strokeRect(x*cw, y*cw, cw, cw);
}
paintCell(3,2);
Explain Coordinate system and how it matches up to pixels

4.5 Checkpoint

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const width = 400;
const height = 400;
const cw = 10;
let snake;
let game_loop = null;
let dir;
let food;
function drawBoard(){
ctx.fillStyle = "white";
ctx.fillRect(0, 0, width, height);
ctx.strokeStyle = "black";
ctx.strokeRect(0, 0, width, height);
}
function paintCell(x, y){
ctx.fillStyle = "blue";
ctx.fillRect(x*cw, y*cw, cw, cw);
ctx.strokeStyle = "white";
ctx.strokeRect(x*cw, y*cw, cw, cw);
}
function paint(){
drawBoard();
}
function init(){
createSnake();
createFood();
dir = "right";
if(typeof game_loop != "undefined") clearInterval(game_loop);
game_loop = setInterval(paint, 200);
}
function createFood()
{
// todo later
}
function createSnake()
{
// start here
}
init();

5. Create a snake

Explain for loop (instead of manually typing, computer count) and arrays
let snake; // let as will change
function createSnake()
{
let length = 5; //Length of the snake
snake_array = []; //Empty array to start with
for(let i = length-1; i>=0; i--)
{
//This will create a horizontal snake starting from the top left
snake_array.push({x: i, y:0});
}
}

6. Draw snake

function drawSnake()
{
for(let i=0; i<snake.length; i++)
{
paintCell(snake[i].x, snake[i].y);
}
}
// add to paint
drawSnake();

7. Lets make the snake move

let dir;
let game_loop;
function moveSnake()
{
var newX = snake[0].x;
var newY = snake[0].y;
if(dir == "right") newX++;
else if(dir == "left") newX--;
else if(dir == "up") newY--;
else if(dir == "down") newY++;
var tail = snake.pop(); //pops out the last cell
tail.x = newX;
tail.y = newY;
snake.unshift(tail); //puts back the tail as the first cell
}
function paint(){
drawBoard();
moveSnake();
paint_cell(food.x, food.y);
drawSnake();
}
function init(){
createSnake();
dir = "right";
if(typeof game_loop != "undefined") clearInterval(game_loop);
game_loop = setInterval(paint, 200);
}
init();

8. Lets make the snake move in different directions

function changeDirection(event){
const key = event.keyCode;
//We will add another clause to prevent reverse gear
if(key == "37" && dir != "right"){
dir = "left";
} else if(key == "38" && dir != "down"){
dir = "up";
} else if(key == "39" && dir != "left"){
dir = "right";
} else if(key == "40" && dir != "up"){
dir = "down";
}
}
document.addEventListener("keydown", changeDirection);

9. Lets End the game if you hit a boundary

There are two cases in which the game can end:
  • The head of the snake collides with its body.
  • The head of the snake collides with the canvas boundary.
function hasGameEnded(){
if(snake[0].x < 0){
return true;
} else if(snake[0].x > width/cw){
return true;
} else if(snake[0].y < 0){
return true;
} else if(snake[0].y > height/cw){
return true;
}
return false;
}
// add this inside paint()
if(hasGameEnded()){
//restart game
init();
return;
}

10. Lets add food

let food;
function createFood()
{
food = {
x: Math.round(Math.random()*(width-cw)/cw),
y: Math.round(Math.random()*(height-cw)/cw),
};
}
//
paintCell(food.x, food.y);