Skip to content

Instantly share code, notes, and snippets.

@tjoskar
Created November 10, 2014 06:53
Show Gist options
  • Save tjoskar/961b38f32b8274da4629 to your computer and use it in GitHub Desktop.
Save tjoskar/961b38f32b8274da4629 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<title>Snake</title>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script src="snake.js"></script>
<style type="text/css">
.snake_piece {
position:fixed;
left:50%;
box-sizing: border-box;
-ms-box-sizing: border-box;
-moz-box-sizing: border-box;
}
#snake_snake .snake_piece {
/*background: #2ecc71;*/
}
#snake_food .snake_piece {
/*background: #e74c3c;*/
}
</style>
</head>
<body>
</body>
</html>
var Snake = function() {
var speed = 10;
var pixWidth = 10;
var pixHeight = 10;
var boxWidth = 8;
var boxHeight = 8;
var direction = 2;
var directionQueue = [];
var interval;
var snakeColors = ['1abc9c', '2ecc71', '3498db', '9b59b6', '34495e'];
var currentColor = '';
var oldColor = '';
var constructor = function() {
nextColor();
return;
};
this.run = function() {
/* Create containers */
$('body').append('<div id="snake_snake"></div><div id="snake_food"></div>');
$('head').append('<style>.snake_piece{width:'+boxWidth+'px;height:'+boxHeight+'px;}</style>');
for (i = 0; i < 3; i++) {
makePiece(0, 10+i);
}
placeFood();
interval = setInterval(update, speed);
};
var nextColor = function() {
oldColor = currentColor || 'e74c3c';
currentColor = snakeColors[Math.floor(Math.random() * snakeColors.length)];
};
var die = function() {
$('#snake_snake, #snake_food').remove();
$(document).off('.snake');
clearInterval(interval);
};
/* Create a piece of snake or food */
var makePiece = function(x, y, food) {
var food = food || false;
var marginLeft = (x - 0.5) * pixWidth;
var top = y * pixHeight;
if (food) {
return $(document.createElement('div'))
.addClass('snake_piece')
.css({
'top': top,
'margin-left': marginLeft,
'background': '#' + currentColor
})
.attr('data-x', x)
.attr('data-y', y)
.appendTo($('#snake_food'));
} else {
return $(document.createElement('div'))
.addClass('snake_piece')
.css({
'top': top,
'margin-left': marginLeft,
'background': '#' + oldColor
})
.attr('data-x', x)
.attr('data-y', y)
.appendTo($('#snake_snake'));
}
return;
};
/* Update the snake's position */
var update = function() {
var pieces = $('#snake_snake>.snake_piece');
if (pieces.length < 0) {
die();
}
decide();
var head = pieces.last();
var x = parseInt(head.attr('data-x'), 10);
var y = parseInt(head.attr('data-y'), 10);
var d;
while (typeof d == 'undefined' || (direction - d + 4) % 4 == 2) {
if (directionQueue.length > 0)
d = directionQueue.shift();
else
d = direction;
}
if (d == 0) {
y--;
} else if (d == 1) {
x++;
} else if (d == 2) {
y++;
} else if (d == 3) {
x--;
} else {
die();
return;
}
var collision = getPiece(x, y);
/* Test is food is being eaten */
if (!collision || collision.closest('#snake_food').length == 0) {
pieces.first().remove();
} else {
nextColor();
placeFood();
collision.remove();
}
/* Check for death by self-collision */
if (collision && collision.closest('#snake_snake').length > 0) {
die();
return;
}
direction = d;
makePiece(x, y);
};
/* Create a piece of food */
var placeFood = function() {
var minY = 0;
var maxY = Math.floor($(document).height()/pixHeight);
var minX = -Math.floor($(document).width()/2/pixWidth);
var maxX = -minX;
var x;
var y;
while(typeof x == 'undefined' || getPiece(x, y)) {
var y = Math.floor(Math.random()*maxY);
var x = Math.floor(Math.random()*(maxX-minX))+minX;
}
makePiece(x, y, true);
};
/* Return the piece at specific co-ordinates, or false if no piece exists */
var getPiece = function(x, y) {
var piece = $('.snake_piece[data-x='+x+'][data-y='+y+']');
return (piece.length > 0) ? piece : false;
};
var decide = function() {
var pieces = $('#snake_snake>.snake_piece');
var food = $('#snake_food>.snake_piece:first');
var head = pieces.last();
var d;
h = {};
f = {};
h.x = parseInt(head.attr('data-x'), 10);
h.y = parseInt(head.attr('data-y'), 10);
f.x = parseInt(food.attr('data-x'), 10);
f.y = parseInt(food.attr('data-y'), 10);
if (h.x > f.x) {
// Go left
d = 3;
} else if (h.x < f.x) {
// Go right
d = 1;
} else if (h.y < f.y) {
// Go down
d = 2;
} else if (h.y > f.y) {
// Go up
d = 0;
} else {
console.log('Eat');
return;
}
var r = 1;
while (!isPossible(h, d) && r++ < 4) {
d = (d+1)%4;
}
directionQueue.push(d);
};
var isPossible = function(h_o, d) {
if (Math.abs(direction - d) == 2)
return false;
var h = $.extend({}, h_o);
if (d == 0) {
h.y--;
} else if (d == 1) {
h.x++;
} else if (d == 2) {
h.y++;
} else {
h.x--;
}
var p = getPiece(h.x, h.y);
if (p && p.closest('#snake_snake').length > 0) {
return false;
}
return true;
};
constructor();
};
var snake = new Snake();
$(function() {
snake.run();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment