Skip to content

Instantly share code, notes, and snippets.

@bradly
Created May 8, 2010 01:21
Show Gist options
  • Save bradly/394216 to your computer and use it in GitHub Desktop.
Save bradly/394216 to your computer and use it in GitHub Desktop.
Snake in Canvas
<!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