Intro to JavaScript for Games:
Building Snake
Why?
- Awesome learning tool
- Challenging
- Fun
- You get to play the games as you build them! (QA is fun)
Tools
- HTML/CSS/jQuery
- Canvas
- Web sockets
- Libraries
Examples!
- Tanks
- Tetris
- Dots & Boxes
- Canvas Visualizations
- Magar.io
Tank Arena
-Utilizes web sockets to let people fight against each other
-https://github.com/yusefmarra/Tank-Arena
-http://tank-arena.herokuapp.com/
Dots and Boxes
- Kierston Hill
- jQ html/css
- https://github.com/KierstonHill83/Dots-and-Boxes-Game
Quattro's Revenge
- Johnny Lamb
- Vanilla JS.
- https://github.com/JohnnyLamb/Quatros-Revenge
Tetris
-Charlie Blackstock
-vanilla js / canvas.
-http://blackstc.github.io/tetris/
-https://github.com/blackstc/tetris
Canvas Visualizations
- Ethan Mannette
- https://github.com/Mannette/intro-to-canvas
Agar.io clone
-Keith Hopkins
-project to learn to build AIs
-https://github.com/keithhopkins/node-agario-clone
Starcraft
- http://gloomyson.github.io/StarCraft/
- what!
-possibilities are endless...
Today:
- we are going to build Snake.
- work together, meet people, have fun.
- clone this repo down: https://github.com/zbunde/Snake
Step 0: Setup
- git clone git@github.com:zbunde/Snake.git
- Every completed step is a branch
- you can get unstuck by checking out that specific branch!
- git checkout step
Step 1: HTML
-we need to add a canvas element to our index.html file and give it a width and height.
-this is where our game is going to be displayed.
-give the page a heading if you want!
-we need to include our snake.js file also, since this is where all of our code is going to live.
<canvas id="canvas" width="600" height="600"></canvas>
<script type="text/javascript" src="snake.js"></script>
Step 1: Code
<head>
<script type="text/javascript" src="snake.js"></script>
</head>
<body>
<h3> Snake </h3>
<canvas id="canvas" width="600" height="600"></canvas>
</body>
index.html
git checkout step1-if you get stuck:
Step 2: Draw a border
-let's draw a border around our canvas so we know what we are working on.
-in our snake.js file let's write a function
called drawBorder that does just that.
-first we need to find the canvas and set it to a variable so we can access it.
var canvas = document.getElementById("canvas");
Step 2: Continued
-now that we have a canvas to work with we can set it's context.
-we will use the 2d context for this game, since snake is a 2d game.
-context is what gives us access to all of the canvas drawing functions for 2d.
var canvas = document.getElementById("canvas");
var context = canvas.getContext('2d');
Step 2: Continued
-now that we have context, we can start drawing things on our page!
-we will use the canvas.width and canvas.height to draw a border around the entire canvas.
function drawBorder(){
var canvas = document.getElementById("canvas");
var context = canvas.getContext('2d');
context.strokeRect(0,0, canvas.width, canvas.height);
}Step 2: Continued
-now we just need to call our function once the dom loads.
document.addEventListener("DOMContentLoaded", function() {
drawBorder();
});
Step 2: Code
- now that we have a border, lets give it some color!
-lets set our context.strokeStyle to any color of your choice!
- if you get stuck:
function drawBorder(){
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
context.strokeStyle = '#E28D05'
context.strokeRect(0,0, canvas.width, canvas.height);
}
git checkout step2Step 3: Intervals
- We need to write a function that causes our game to 'tick' so that we can update our movement, check for death, and paint the canvas again.
- This code is going to be a bit complex so let's write a Game function that will hold it.
- I added a color parameter to our drawBorder function to demonstrate an interval.
-We will delete the conditional and count variable, this is to demonstrate how an interval works.
function Game (){
var count = 0
var interval = function() {
count ++
if(count % 2 == 0){
drawBorder('green');
}
else {
drawBorder('red')
}
setTimeout(function() {
requestAnimationFrame(interval);
}, 1000);
};
interval();
}
function drawBorder(color){
var canvas = document.getElementById("canvas");
var context = canvas.getContext('2d');
context.strokeStyle = color
context.lineWidth=10;
context.strokeRect(0,0, canvas.width, canvas.height);
}document.addEventListener("DOMContentLoaded", function() {
Game()
});git checkout IntervalExampleStep 3: Intervals
- We will delete the conditional and count variable, they were just to demo an interval.
-Lower our interval time to 240ms, 1,000ms is REALLY slow for a game.
-Inside of our interval function we need to do the following things(no particular order yet):
1. Update Snake.
2. Draw Snake.
3. Check if it is still alive.
4. See if it ate food.
5. Request the next frame.
Step 3: Intervals
function Game (){
var interval = function() {
drawBorder('orange')
}
setTimeout(function() {
requestAnimationFrame(interval);
}, 240);
};
interval();
}
function drawBorder(color){
var canvas = document.getElementById("canvas");
var context = canvas.getContext('2d');
context.strokeStyle = color
context.lineWidth=10;
context.strokeRect(0,0, canvas.width, canvas.height);
}Step 3: Code
document.addEventListener("DOMContentLoaded", function() {
Game()
});
function drawBorder(color){
var canvas = document.getElementById("canvas");
var context = canvas.getContext('2d');
context.strokeStyle = color
context.strokeRect(0,0, canvas.width, canvas.height);
}
function Game (){
var interval = function() {
drawBorder('orange')
}
setTimeout(function() {
requestAnimationFrame(interval);
}, 240);
};
interval();
}
-if you are stuck
git checkout step3Step 4: Draw a Snake
-We need a length a color and a width.
-Let's setup a pixelSize variable that we can use to draw each piece of our snake.
- Paint the snake with a length of 8 by using a for loop and painting each pixel of the snake.
-we also want to draw a small white line around each piece of the snake to make them more visible.
Step 4: Draw a Snake
function drawSnake (){
var canvas = document.getElementById("canvas");
var context = canvas.getContext('2d');
var pixelSize = canvas.width / 25
for(var i = 0; i < 8; i++) {
context.fillStyle = "orange";
context.fillRect(i*pixelSize, 0, pixelSize, pixelSize);
context.strokeStyle = "white";
context.strokeRect(i*pixelSize, 0, pixelSize, pixelSize);
}
}- test your function by calling it in your browser console.
Step 4: Continued
- now that we have this function, we need to call it each interval, along with our drawBorder function.
function Game (){
var interval = function() {
drawBorder('orange')
drawSnake();
setTimeout(function() {
requestAnimationFrame(interval);
}, 1000);
};
interval();
}
Step 4: Code
-if you are stuck:
git checkout step4function Game (){
var interval = function() {
drawBorder('orange')
drawSnake();
setTimeout(function() {
requestAnimationFrame(interval);
}, 240);
};
interval();
}
function drawSnake (){
var canvas = document.getElementById("canvas");
var context = canvas.getContext('2d');
var pixelSize = canvas.width / 25
for(var i = 0; i < 8; i++) {
context.fillStyle = "orange";
context.fillRect(i*pixelSize, 0, pixelSize, pixelSize);
context.strokeStyle = "white";
context.strokeRect(i*pixelSize, 0, pixelSize, pixelSize);
}
}Step 5: Movement!
-We need a way to keep track of the X and Y coordinates of our snake and which direction it is going.
- lets create a way to keep track of Snakes inside of our game.
var Snake = function(){
var self = this
self.direction = 'right'
self.snakeArray = []
self.length = 8;
for(var i = length; i>=0; i--) {
self.snakeArray.push({x: i, y:0});
}
}
Step 5: Continued
-now that we have a snake object let's use it in our Game.
-our snake is going to move so our drawSnake function is brittle. Let's refactor it to take a snake as an argument.
var Game = function (){
var self = this
self.snake = new Snake()
var interval = function() {
drawBorder('orange')
drawSnake(self.snake);
setTimeout(function() {
requestAnimationFrame(interval);
}, 1000);
};
interval();
}Step 5: Continued
- now that we have access to our snake
we can paint each cell in it.
function drawSnake (snake){
var canvas = document.getElementById("canvas");
var context = canvas.getContext('2d');
var pixelSize = canvas.width / 25
for(var i = 0; i < snake.snakeArray.length; i++) {
context.fillStyle = "orange";
context.fillRect(snake.snakeArray[i].x * pixelSize, snake.snakeArray[i].y * pixelSize,
pixelSize, pixelSize);
context.strokeStyle = "white";
context.strokeRect(snake.snakeArray[i].x * pixelSize, snake.snakeArray[i].y * pixelSize,
pixelSize, pixelSize);
}
}Step 5: Continued
- now that we are painting our snake dynamically we can write an updateSnake function that will change the position of the snake each interval.
-we have 4 directions to chose from, so we need a conditional to handle each case:
function updateSnake(snake){
var noseX = snake.snakeArray[0].x
var noseY= snake.snakeArray[0].y
if(snake.direction == "right") noseX++;
else if(snake.direction == "left") noseX--;
else if(snake.direction == "up") noseY--;
else if(snake.direction == "down") noseY++;
}Step 5: Continued
- we take the tail of our snake and pop it out of the array. we then put it back to the front, giving the appearance of motion on each interval.
function updateSnake(snake){
var noseX = snake.snakeArray[0].x
var noseY= snake.snakeArray[0].y
if(snake.direction == "right") noseX++;
else if(snake.direction == "left") noseX--;
else if(snake.direction == "up") noseY--;
else if(snake.direction == "down") noseY++;
var tail = snake.snakeArray.pop();
tail.x = noseX;
tail.y = noseY;
snake.snakeArray.unshift(tail);
}Step 5: Continued
- we need to now call our updateSnake function in our interval!
var Game = function (){
var self = this
self.snake = new Snake()
var interval = function() {
drawBorder('orange')
updateSnake(self.snake)
drawSnake(self.snake);
setTimeout(function() {
requestAnimationFrame(interval);
}, 240);
};
interval();
}
Step 5: Last piece
-we need to make sure to clear our canvas each interval so that we have a fresh canvas to paint on.
-since our drawBorder function happens first we can clear the canvas inside of it.
stuck? git checkout step5function drawBorder(color){
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height);
context.strokeStyle = color
context.strokeRect(0, 0, canvas.width, canvas.height);
}Step 6: Control
-we need to add controls to our snake so we can determine it's direction!
- let's assign our Game to a variable so we can access and change our snakes direction.
-add event listeners to all of the arrow keys that change the snakes direction appropriately.
Step 6: Code
document.addEventListener("DOMContentLoaded", function() {
game = new Game()
});window.addEventListener('keydown', function(key) {
key.preventDefault();
if(key.which == "37")
game.snake.direction = "left"
else if(key.which == "39")
game.snake.direction = "right"
else if(key.which == "38")
game.snake.direction = "up"
else if(key.which == "40")
game.snake.direction = "down"
});-if you get stuck:
git checkout step6Step 7: Food
-we need to write two functions, one to create a piece of food, and one to draw the food each interval.
-we need to make sure that the food is within our canvas.
Step 7: Food
function createFood(){
var pixelSize = canvas.width / 25
return food = {
x: Math.round(Math.random()*(canvas.width-pixelSize)/pixelSize),
y: Math.round(Math.random()*(canvas.height-pixelSize)/pixelSize),
};
}function drawFood(food){
var canvas = document.getElementById("canvas");
var context = canvas.getContext('2d')
var pixelSize = canvas.width / 25
context.fillStyle = "blue";
context.fillRect(food.x * pixelSize, food.y * pixelSize, pixelSize, pixelSize);
context.strokeStyle = "white";
context.strokeRect(food.x * pixelSize, food.y * pixelSize, pixelSize, pixelSize);
}Step 7: Continued
-now that we have our functions we need to use them!
var Game = function (){
var self = this
self.snake = new Snake()
self.food = createFood()
var interval = function() {
drawBorder('orange')
updateSnake(self.snake)
drawSnake(self.snake);
drawFood(self.food)
setTimeout(function() {
requestAnimationFrame(interval);
}, 120);
};
interval();
}Step 7: Code
function createFood(){
var pixelSize = canvas.width / 25
return food = {
x: Math.round(Math.random()*(canvas.width-pixelSize)/pixelSize),
y: Math.round(Math.random()*(canvas.height-pixelSize)/pixelSize),
};
}
function drawFood(food){
var canvas = document.getElementById("canvas");
var context = canvas.getContext('2d')
var pixelSize = canvas.width / 25
context.fillStyle = "blue";
context.fillRect(food.x * pixelSize, food.y * pixelSize, pixelSize, pixelSize);
context.strokeStyle = "white";
context.strokeRect(food.x * pixelSize, food.y * pixelSize, pixelSize, pixelSize);
}
-if you get stuck:
git checkout step7
Step 8: Collisions
-Now that we have food we need to do something when we run into it.
-We will also check to make sure our snake isn't running out of bounds or into itself here.
-console.log('off map') to check if collisions are working!
- add + 1 for off the map right and down.
- this accounts for us measuring from top left of our snake head.
function checkCollision(snake, food){
var canvas = document.getElementById("canvas");
var pixelSize = canvas.width / 25
/// if we hit our food!
if(snake.snakeArray[0].x === food.x && snake.snakeArray[0].y === food.y){
}
/// off the map left
if(snake.snakeArray[0].x < 0 ){
}
/// off the map up
if(snake.snakeArray[0].y < 0 ){
}
/// off the map down
if(snake.snakeArray[0].y + 1> 600/pixelSize ){
}
/// off the map right
if(snake.snakeArray[0].x + 1> 600/pixelSize ){
}
/// if we hit our own snake body
for(var i = 1; i < snake.snakeArray.length; i++){
if(snake.snakeArray[i].x == snake.snakeArray[0].x
&& snake.snakeArray[i].y == snake.snakeArray[i].y){
}
}
}Step 8: Continued
- now that we are checking for collisions we can call it in our interval function.
var Game = function (){
var self = this
self.snake = new Snake()
self.food = createFood()
var interval = function() {
drawBorder('orange');
updateSnake(self.snake);
drawSnake(self.snake);
drawFood(self.food);
checkCollision(self.snake, self.food)
setTimeout(function() {
requestAnimationFrame(interval);
}, 240);
};
interval();
}-if you get stuck:
git checkout step8
Step 9: Handling Collisions
-now that we are checking for collisions we need to do stuff when they occur.
-food is easy, we need to create a new piece of food and increase our score!
-add a score to our game.
-update our drawBorder function to also draw a score.
-increase score when we eat food!
var Game = function (){
var self = this
self.snake = new Snake()
self.food = createFood()
self.score = 0;
var interval = function() {
drawBorder('orange', self.score);
updateSnake(self.snake);
drawSnake(self.snake);
drawFood(self.food);
checkCollision(self.snake, self.food)
setTimeout(function() {
requestAnimationFrame(interval);
}, 240);
};
interval();
} if(snake.snakeArray[0].x === food.x && snake.snakeArray[0].y === food.y){
game.food = createFood()
game.score++
var tail = {}
tail.x = game.snake.snakeArray[0].x
tail.y = game.snake.snakeArray[0].y
snake.snakeArray.unshift(tail);
}function drawBorder(color, score){
var canvas = document.getElementById("canvas");
var context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height);
context.font = "30px Arial";
context.fillText(score, 0, 30)
context.strokeStyle = color
context.strokeRect(0,0, canvas.width, canvas.height);
}-Now we just need to add draw our score on the canvas.
Step 9: Handling Collisions
-now we need to handle what happens when we go off the map or hit another snake.
- let's just use location.reload(); to refresh our page.
function checkCollision(snake, food){
var canvas = document.getElementById("canvas");
var pixelSize = canvas.width / 25
/// if we hit our food!
if(snake.snakeArray[0].x === food.x && snake.snakeArray[0].y === food.y){
game.food = createFood()
game.score++
var tail = {}
tail.x = game.snake.snakeArray[0].x
tail.y = game.snake.snakeArray[0].y
snake.snakeArray.unshift(tail);
}
/// off the map left
if(snake.snakeArray[0].x < 0 ){
location.reload();
}
/// off the map up
if(snake.snakeArray[0].y < 0 ){
location.reload();
}
/// off the map down
if(snake.snakeArray[0].y > 600/pixelSize ){
location.reload();
}
/// off the map right
if(snake.snakeArray[0].x > 600/pixelSize ){
location.reload();
}
/// if we hit our own snake body
for(var i = 2; i < snake.snakeArray.length; i++){
if(snake.snakeArray[i].x == snake.snakeArray[0].x && snake.snakeArray[i].y == snake.snakeArray[0].y){
location.reload();
}
}
}Step 9: Code
- if you are stuck:
git checkout step9
Step 10: Interval
-now that our game is working, let's add the last set of rules.
-each time we consume food, we want the interval speed of the game to increase.
-add a new score property and set it to 240 to begin.
Step 10: Interval
var Game = function (){
var self = this
self.snake = new Snake()
self.food = createFood()
self.score = 0;
self.speed = 240;
var interval = function() {
drawBorder('orange', self.score);
updateSnake(self.snake);
drawSnake(self.snake);
drawFood(self.food);
checkCollision(self.snake, self.food)
setTimeout(function() {
requestAnimationFrame(interval);
}, self.speed);
};
interval();
}Step 10: Interval
-now we just need to update our game speed when we consume food.
-let's also limit it to 30ms so it is still somewhat playable.
Step 10: Interval
if(snake.snakeArray[0].x === food.x && snake.snakeArray[0].y === food.y){
game.food = createFood()
game.score++
if(game.time > 30){
game.time = game.time - 15
}
var tail = {}
tail.x = game.snake.snakeArray[0].x
tail.y = game.snake.snakeArray[0].y
snake.snakeArray.unshift(tail);
}Step 11: Computer Player
-lets add another snake that is controlled by an AI.
-we need to make room in our game for another snake, and write some code to control the computer snake.
-we will give our snakes the ability to take a color so that we can see which one is the computer.
-we added the computer as a new Snake, giving it a color of blue and a Y of 10.
Step 11: updateComputer()
var Game = function (){
var self = this
self.snake = new Snake(0, "red")
self.computer = new Snake(10, "blue")
self.food = createFood()
self.score = 0;
self.speed = 240;
var interval = function() {
drawBorder('orange', self.score);
updateSnake(self.snake);
updateSnake(self.computer);
updateComputer(self.snake, self.food, self.computer)
drawSnake(self.snake);
drawSnake(self.computer);
drawFood(self.food);
checkCollision(self.snake, self.computer, self.food)
setTimeout(function() {
requestAnimationFrame(interval);
}, self.speed);
};
interval();
}
Step 11: AI Cont.
- AI's can be very complex but let's try and break down into a bunch of conditionals.
- the next slide is the AI code that determines what direction to go towards the food.
function updateComputer(snake, food, computer){
if (food.x === computer.snakeArray[0].x) {
if (food.y > computer.snakeArray[0].y) {
if (isSafe(snake, computer, 'down')) computer.direction = 'down';
} else {
if (isSafe(snake, computer, 'up')) computer.direction = 'up';
}
}
if (food.y === computer.snakeArray[0].y) {
if (food.x > computer.snakeArray[0].x) {
if (isSafe(snake, computer, 'right')) computer.direction = 'right';
} else {
if (isSafe(snake, computer, 'left')) computer.direction = 'left';
}
}
if (food.y > computer.snakeArray[0].y) {
if (isSafe(snake, computer, 'down')) computer.direction = 'down';
} else if (food.y < computer.snakeArray[0].y) {
if (isSafe(snake, computer, 'up')) computer.direction = 'up';
}
if (food.x > computer.snakeArray[0].x) {
if (isSafe(snake, computer, 'right')) computer.direction = 'right';
} else if (food.x < computer.snakeArray[0].x) {
if (isSafe(snake, computer, 'left')) computer.direction = 'left';
}
}Step 11: isSafe
- this next slide is the code that determines if the picked direction is somewhat safe.
function isSafe(snake, computer, dir){
var snakeCopy = deepCopy(snake.snakeArray);
var compCopy = deepCopy(computer.snakeArray);
switch (dir) {
case 'left':
for (var i = 0; i < snakeCopy.length/4; i++) {
compCopy[0].x--;
if ( checkBodyCollision(compCopy[0], compCopy) || checkBodyCollision(compCopy[0], snakeCopy)) {
return false;
}
}
return true;
case 'right':
for (var i = 0; i < compCopy.length/4; i++) {
compCopy[0].x++;
if (checkBodyCollision(compCopy[0], compCopy) || checkBodyCollision(compCopy[0], snakeCopy)) {
return false;
}
}
return true;
case 'up':
for (var i = 0; i < compCopy.length/4; i++) {
compCopy[0].y--;
if (checkBodyCollision(compCopy[0], compCopy) || checkBodyCollision(compCopy[0], snakeCopy)) {
return false;
}
}
return true;
case 'down':
for (var i = 0; i < compCopy.length/4; i++) {
compCopy[0].y++;
if (checkBodyCollision(compCopy[0], compCopy) || checkBodyCollision(compCopy[0], snakeCopy)) {
return false;
}
}
return true;
}
}
Step 11: AI Helpers
- the functions on the next slide are used by our AI to help make decisions.
Step 11: AI Helper Code
function checkBodyCollision(head, array) {
for(var i = 1; i < array.length; i++){
if(array[i].x == head.x && array[i].y == head.y){
return true;
}
}
return false;
}
function deepCopy (arr) {
var out = [];
for (var i = 0, len = arr.length; i < len; i++) {
var item = arr[i];
var obj = {};
for (var k in item) {
obj[k] = item[k];
}
out.push(obj);
}
return out;
}
Step 11: Rework checkCollison()
-now that we have another snake on our canvas we need to account for that in our checkCollision function.
- add conditions to check for the computer leaving the map, and add conditions for the snakes hitting each other.
function checkCollision(snake, computer, food){
var canvas = document.getElementById("canvas");
var context = canvas.getContext('2d')
var pixelSize = canvas.width / 25
/// If we run into the computer.
for(i=0; i< computer.snakeArray.length; i++){
if(snake.snakeArray[0].x === computer.snakeArray[i].x && snake.snakeArray[0].y === computer.snakeArray[i].y){
alert("You lose!")
location.reload()
}
}
/// If the computer runs into us
for(i=0; i< snake.snakeArray.length; i++){
if(computer.snakeArray[0].x === snake.snakeArray[i].x && computer.snakeArray[0].y === snake.snakeArray[i].y){
context.clearRect(0, 0, canvas.width, canvas.height);
alert("You win!");
location.reload()
}
}
/// If the computer hits the food.
if(computer.snakeArray[0].x === food.x && computer.snakeArray[0].y === food.y){
game.food = createFood()
game.score--
if(game.speed > 30){
game.speed = game.speed - 15
}
var tail = {}
tail.x = computer.snakeArray[0].x
tail.y = computer.snakeArray[0].y
computer.snakeArray.unshift(tail);
}
/// if we hit our food!
if(snake.snakeArray[0].x === food.x && snake.snakeArray[0].y === food.y){
game.food = createFood()
game.score++
if(game.speed > 30){
game.speed = game.speed - 15
}
var tail = {}
tail.x = game.snake.snakeArray[0].x
tail.y = game.snake.snakeArray[0].y
snake.snakeArray.unshift(tail);
}
/// off the map left
if(snake.snakeArray[0].x < 0 ){
alert("You lose!");
location.reload();
}
/// Computer off the map left
if(computer.snakeArray[0].x < 0 ){
alert("You win!");
location.reload();
}
/// off the map up
if(snake.snakeArray[0].y < 0 ){
alert("You lose!");
location.reload();
}
/// Computer off the map up
if(computer.snakeArray[0].y < 0 ){
alert("You win!");
location.reload();
}
/// off the map down
if(snake.snakeArray[0].y + 1 > 600/pixelSize ){
alert("Computer wins!");
location.reload();
}
/// Computer off the map down
if(computer.snakeArray[0].y + 1 > 600/pixelSize ){
alert("You win!");
location.reload();
}
/// off the map right
if(snake.snakeArray[0].x + 1 > 600/pixelSize ){
alert("You lose!");
location.reload();
}
/// Computer off the map right
if(computer.snakeArray[0].x + 1 > 600/pixelSize ){
alert("You win!");
location.reload();
}
/// if we hit our own snake body
for(var i = 2; i < snake.snakeArray.length; i++){
if(snake.snakeArray[i].x == snake.snakeArray[0].x && snake.snakeArray[i].y == snake.snakeArray[0].y){
alert("You lose!");
location.reload();
}
}
/// if computer hits it's own body
for(var i = 2; i < computer.snakeArray.length; i++){
if(computer.snakeArray[i].x == computer.snakeArray[0].x && computer.snakeArray[i].y == computer.snakeArray[0].y){
alert("You win!");
location.reload();
}
}
}Step 11: Code:
git checkout step11- if you are stuck:
Step 12: Refactor
- have fun ;)
Game Libraries
- https://html5gameengine.com/
- http://phaser.io/
- https://www.scirra.com/ (Construct 2)
- http://threejs.org/
Next Steps
- write an AI to play Snake
- refactor this code!
- build some other games.
- utilize some of the libraries mentioned.
- build a multiplayer game with websockets.
Thank you!
- twitter: @zbunde
- github: https://github.com/zbunde
Resources
Dots and Boxes
https://github.com/KierstonHill83/Dots-and-Boxes-Game
Tank Arena
https://github.com/yusefmarra/Tank-Arena
http://tank-arena.herokuapp.com/
Tetris
http://blackstc.github.io/tetris/
https://github.com/blackstc/tetris
Agar.io Clone
https://github.com/keithhopkins/node-agario-clone
https://megario.herokuapp.com/
Quattro's Revenge
https://github.com/JohnnyLamb/Quatros-Revenge
Canvas Visualizations
https://github.com/Mannette/canvas-fibStuff
Starcraft
http://gloomyson.github.io/StarCraft/
JS for Games
By Zach Klabunde
JS for Games
- 726