Created
May 8, 2010 01:21
-
-
Save bradly/394216 to your computer and use it in GitHub Desktop.
Snake in Canvas
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" | |
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | |
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> | |
<head> | |
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> | |
<title>Snakezz</title> | |
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> | |
</head> | |
<body> | |
<canvas id="board" width="600" height="600"></canvas> | |
<script type="text/javascript"> | |
var ctx; | |
var snake; | |
var intervalId = 0; | |
var SPEED = 50; | |
var WIDTH = 600; | |
var HEIGHT = 600; | |
var swidth = 10; | |
var x_bound = WIDTH / swidth; | |
var y_bound = HEIGHT / swidth; | |
var playing = false; | |
function init() { | |
ctx = $('#board')[0].getContext("2d"); | |
draw_welcome_screen(); | |
$('#board').bind('click', function(){ | |
if(!playing) { | |
play(); | |
playing = true; | |
} | |
}); | |
} | |
function play() { | |
snake = new Snake(); | |
intervalId = setInterval(run, SPEED); | |
return intervalId; | |
} | |
function run() { | |
clear_board(); | |
snake.move(); | |
snake.draw(); | |
maybe_end_game(); | |
snake.food.draw(); | |
snake.eat(); | |
} | |
function maybe_end_game() { | |
if( snake.has_collision() ) { | |
draw_game_over_screen(); | |
clearInterval(intervalId); | |
playing = false; | |
} | |
} | |
function clear_board() { | |
ctx.clearRect(0, 0, WIDTH, HEIGHT); | |
ctx.fillStyle = "#dddddd"; | |
ctx.fillRect(0,0,WIDTH,HEIGHT); | |
ctx.fill(); | |
} | |
function Food () { | |
this.place = function() { | |
this.x = Math.floor(Math.random()*(x_bound)) | |
this.y = Math.floor(Math.random()*(y_bound)) | |
} | |
this.draw = function() { | |
ctx.fillStyle = "#dd0000"; | |
ctx.fillRect(this.x*swidth+1, this.y*swidth+1, swidth-1, swidth-1); | |
ctx.fill(); | |
} | |
this.place(); | |
} | |
function Piece (x, y) { | |
this.x = x; | |
this.y = y; | |
this.draw = function() { | |
ctx.fillStyle = "#444555"; | |
ctx.fillRect(this.x*swidth+1, this.y*swidth+1, swidth-1, swidth-1); | |
ctx.fill(); | |
} | |
this.is_out_of_bounds = function() { | |
if(this.x < 0 || this.y < 0 || this.x >= x_bound || this.y >= y_bound) { | |
return true | |
} | |
return false | |
} | |
} | |
function Snake () { | |
this.direction = "left"; | |
this.parts = Array(5); | |
this.food = new Food(); | |
for (i=0; i < this.parts.length; i++) { | |
this.parts[i] = new Piece(i+30, 30); | |
} | |
this.move_head = function() { | |
if (this.direction == 'left') { | |
this.parts[0].x-=1; | |
} else if (this.direction == 'right') { | |
this.parts[0].x+=1; | |
} else if (this.direction == 'up') { | |
this.parts[0].y-=1; | |
} else if (this.direction == 'down') { | |
this.parts[0].y+=1; | |
} | |
} | |
this.eat = function() { | |
if( this.parts[0].x - this.food.x == 0 && this.parts[0].y - this.food.y == 0 ) { | |
this.grow(); | |
this.food.place(); | |
} | |
} | |
this.has_collision = function() { | |
for (i=0; i < this.parts.length; i++) { | |
if( this.parts[i].is_out_of_bounds() ) { | |
return true | |
} | |
for (j=(i+1); j < this.parts.length; j++) { | |
if(this.parts[i].x - this.parts[j].x == 0 && this.parts[i].y - this.parts[j].y == 0) { | |
return true | |
} | |
} | |
} | |
return false; | |
} | |
this.move = function() { | |
var prev_x; | |
var prev_y; | |
for (i=0; i < this.parts.length; i++) { | |
if( i == 0 ) { | |
prev_x = this.parts[i].x; | |
prev_y = this.parts[i].y; | |
this.move_head(); | |
} else { | |
current_x = this.parts[i].x; | |
current_y = this.parts[i].y; | |
this.parts[i].x = prev_x; | |
this.parts[i].y = prev_y; | |
prev_x = current_x; | |
prev_y = current_y; | |
} | |
} | |
} | |
this.grow = function() { | |
var x = this.parts[this.parts.length-1].x; | |
var y = this.parts[this.parts.length-1].y; | |
if (this.direction == 'left') { | |
x+=1; | |
} | |
else if (this.direction == 'right') { | |
x-=1; | |
} | |
else if (this.direction == 'up') { | |
y-=1; | |
} | |
else if (this.direction == 'down') { | |
y+=1; | |
} | |
this.parts.push( new Piece(x,y) ); | |
} | |
this.draw = function() { | |
for (i=0; i < this.parts.length; i++) { | |
this.parts[i].draw(); | |
} | |
} | |
} | |
function draw_welcome_screen() { | |
clear_board(); | |
ctx.fillStyle = '#00f'; | |
ctx.font = 'italic 30px sans-serif'; | |
ctx.fillText ('Snakezz!', 215, 220); | |
ctx.fillStyle = '#000'; | |
ctx.font = '14px sans-serif'; | |
ctx.fillText ('Click to play', 240, 250); | |
} | |
function draw_game_over_screen() { | |
clear_board(); | |
ctx.fillStyle = '#00f'; | |
ctx.font = 'italic 30px sans-serif'; | |
ctx.fillText ('Game over!', 215, 220); | |
ctx.fillStyle = '#000'; | |
ctx.font = 'bold 14px sans-serif'; | |
ctx.fillText ('Snake length: ' + snake.parts.length, 240, 250); | |
ctx.font = '14px sans-serif'; | |
ctx.fillText ('click to play again', 238, 300); | |
} | |
function onKeyUp(e) { | |
if (e.keyCode == 39 && snake.direction != 'left') { | |
snake.direction = 'right'; | |
} else if (e.keyCode == 37 && snake.direction != 'right') { | |
snake.direction = 'left'; | |
} else if (e.keyCode == 38 && snake.direction != 'down') { | |
snake.direction = 'up'; | |
} else if (e.keyCode == 40 && snake.direction != 'up') { | |
snake.direction = 'down'; | |
} | |
} | |
init(); | |
$(document).keydown(onKeyUp); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment