# Snake project

Completed example (<https://codepen.io/arkev/pen/pDdoL?editors=0010>)

<https://codepen.io/davmarksman/pen/YzVvmBL>

## Instructions

#### 1. Create canvas

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

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

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

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

```javascript
 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](https://78538796-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MRttXj8afsKu7gyhuLF%2F-Mg6OXO1k4WdfUFxQovN%2F-Mg6V982AlIwUUWZ5Cmv%2Fimage.png?alt=media\&token=d1f4b721-3daa-4a86-a82d-08c38dcb1f63)

#### 4.5 Checkpoint

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

![](https://78538796-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MRttXj8afsKu7gyhuLF%2F-Mg6XMyrI3jGj594JNAi%2F-Mg6cG_0qk5eO85mvVl4%2Fimage.png?alt=media\&token=f5ca1038-d15f-4918-8a33-19f6152ffe6e)

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

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

![](https://78538796-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MRttXj8afsKu7gyhuLF%2F-Mg6XMyrI3jGj594JNAi%2F-Mg6cKNoiO_ISZ26YUR_%2Fimage.png?alt=media\&token=fde6d3a4-c55d-4956-898b-ac73474b7f0c)

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

```javascript
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.

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

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