Snake game

go play

by Daniel Hall

HTML

<div class="stage" tabindex="0">
    <div class="play">play</div>
</div>

CSS

html {
    font-family: Arial, Helvetica, sans-serif;
}

:focus, :active {
    outline: 0;
    border: 0;
}

div.stage {
    font-size: 5px;
    width: 50em;
    height: 50em;
    position: fixed;
    top: 50%;
    left: 50%;
    margin: -25em 0 0 -25em;
    border: 1px solid #666;
    background-color: #eee;
    overflow: hidden;
    box-shadow: 0 0 2px rgba(0, 0, 0, .5);
}

div.end, div.play {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    background-color: #f00;
    z-index: 10;
    text-align: center;
    font-size: 5em;
    line-height: 9.5em;
    color: #eee;
    text-shadow: 1px 1px 1px #333;
    cursor: pointer;
    pointer-events: none;
}

div.play {
    background-color: #00a53c;
}

div.snake > div, div.food {
    width: 1em;
    height: 1em;
    position: absolute;
    top: 0;
    left: 0;
    background-color: #333;
}

JavaScript

var stage = $('div.stage');
var x, y, trail, dir, move, toid, snake, food, time, score;

var up = function() {

    y--;
};

var right = function() {

    x++;
};

var down = function() {

    y++;
};

var left = function() {

    x--;
};

var moves = {
    38: up,
    39: right,
    40: down,
    37: left,
};

var init = function() {
    
    clearTimeout(toid);
    
    snake = stage
        .html('<div class="snake"></div>')
        .children();
    
    time = 100;
    score = 0;
    x = 0;
    y = 0;
    trail = [];
    dir = 40;
    move = moves[dir];
    
    var i;
    for(i = 0; i < 5; i++) {
        
        trail.push([x, y - i]);
    }
    
    feed();
};

stage
.keydown(function(event) {
    
    if(moves.hasOwnProperty(event.keyCode) && dir % 2 !== event.keyCode % 2) {
        
        event.preventDefault();
        event.stopPropagation();
        
        dir = event.keyCode;
        move = moves[dir];
    }
})
.click(function() {

    init();
    render();
});

var square = function(x, y, type) {

    type = type || '';
    
    return '<div class="' + type + '" style="top:' + y + 'em;left:' + x + 'em;"></div>';
};

var end = function() {
    
    clearTimeout(toid);
    stage.html('<div class="end">' + score + ' points</div>');
}

var check = function() {
    
    if(x === food[0] && y === food[1]) {
        
        time = Math.max(10, time - 5);
        trail.unshift(food);
        feed();
        score++;
    }

    if(y >= 50 || x >= 50 || y < 0 || x < 0) {
        
        end();
        
    } else {
    
        var i;
        for(i = 2; i < trail.length; i++) {
            
            if(trail[i][0] === x && trail[i][1] === y) {
                
                end();
                break;
            }
        }
    }
};

var render = function() {
    
    move();
    check();
    
    var i;
    var total = trail.length;
    var last = total - 1;
    
    for(i = last; i > 0; i--) {
        
        trail[i] = trail[i - 1].slice();
...