function $(id){
return document.getElementById(id);
}
var len = 3;
var speed = 10;
var directionkey = 39;
var WIDTH = 50;
var HEIGHT = 20;
window.onload = function(){
var size = document.getElementsByName("size");
for (var i = 0; i < size.length; i++) {
if (size[i].checked) {
WIDTH = parseInt(size[i].value);
}
}
var snake_obj = new snake(len, speed, directionkey, WIDTH, HEIGHT, "say");
snake_obj.initGrid("snakeWrap");
var btnStart = $("btnStart");
btnStart.onclick = function(){
btnStart.blur();
snake_obj.clearAll();
var size = document.getElementsByName("size");
for (var i = 0; i < size.length; i++) {
if (size[i].checked) {
snake_obj.WIDTH = parseInt(size[i].value);
}
}
snake_obj.initGrid("snakeWrap");
startgame(snake_obj);
btnStart.setAttribute("disabled", true);
btnStart.style.color = "#aaa";
}
window.onkeydown = function(e){
if (snake_obj.snake_pos && snake_obj.status) {
if (e.keyCode == 32) {
if (snake_obj.pause) {
snake_obj.pause = false;
snake_obj.talk("游戏重新开始啦~");
snake_obj.move();
} else{
snake_obj.pause = true;
}
}
}
var bool = (e.keyCode > 36 && e.keyCode < 41 && Math.abs(e.keyCode - snake_obj.directionkey) != 2);
snake_obj.directionkey = (bool && !snake_obj.direction_changed) ? e.keyCode:snake_obj.directionkey;
if(bool && !snake_obj.direction_changed){
snake_obj.direction_changed = true;
}
return;
}
}
function startgame(obj){
obj.initSnake();
obj.addObject("food");
obj.move();
}
function snake(l, s, d, W, H, t){
this.len = l;
this.speed = s;
this.directionkey = d;
this.WIDTH = W;
this.HEIGHT = H;
this.gridElems = multiArray(H, W);
this.carrier = multiArray(H, W);
this.snake_pos;
this.snakeTimer;
this.score = 0;
this.talk_id = t;
this.brakeTimers = [];
this.skateTimers = [];
this.direction_changed = false;
this.pause = false;
this.status = true;
this.table;
this.initGrid = function(target){
if (this.table) {
$(target).removeChild(this.table);
}
this.table = document.createElement("table");
var tbody = document.createElement("tbody");
for (var i = 0; i < this.HEIGHT; i++) {
var row = document.createElement("tr");
for (var j = 0; j < this.WIDTH; j++) {
var col = document.createElement("td");
row.appendChild(col);
this.gridElems[i][j] = col;
}
tbody.appendChild(row);
}
this.table.appendChild(tbody);
$(target).appendChild(this.table);
}
this.initSnake = function (){
this.talk("贪吃蛇游戏开始啦~");
$("score").innerHTML = this.score;
this.snake_pos = new Array();
var snake_head_dot = randdot(this.carrier, 0, this.len - 1, this.HEIGHT, Math.floor(WIDTH/2));
for (var i = 0; i < this.len; i++) {
var x = snake_head_dot[0];
var y = snake_head_dot[1] - i;
this.snake_pos.push([x, y]);
this.carrier[x][y] = "cover";
this.gridElems[x][y].className = "cover";
}
}
this.addObject = function(type){
var pos = randdot(this.carrier);
this.carrier[pos[0]][pos[1]] = type;
this.gridElems[pos[0]][pos[1]].className = type;
}
this.step = function (){
if (this.pause) {
this.talk("暂停啦,休息一下~");
window.clearInterval(this.snakeTimer);
for (var i = 0; i < this.brakeTimers.length; i++) window.clearTimeout(this.brakeTimers[i]);
for (var i = 0; i < this.skateTimers.length; i++) window.clearTimeout(this.skateTimers[i]);
return;
}
var headX = this.snake_pos[0][0];
var headY = this.snake_pos[0][1];
if (this.len >= 10 && this.brakeTimers.length <= Math.floor(this.len /2)) {
this.brakeTimers.push(window.setTimeout(function() {
this.addObject("brake").bind(this)
}, randNum(5000, 50000)));
}
if (this.skateTimers.length <= 5 || this.skateTimers.length >= 35) {
this.skateTimers.push(window.setTimeout(function() {
this.addObject("skate").bind(this)
}, randNum(5000, 50000)));
}
switch (this.directionkey){
case 37:
headY -= 1;
break;
case 38:
headX -= 1;
break;
case 39:
headY += 1;
break;
case 40:
headX += 1;
break;
}
if(headX < 0 || headX >= this.HEIGHT || headY < 0 || headY >= this.WIDTH || this.carrier[headX][headY] == "cover" || this.carrier[headX][headY] == "block" ){
this.status = false;
this.talk("你撞到东西啦~游戏结束!");
if (this.score >= parseInt($("best_score").innerHTML)) {
$("best_score").innerHTML = this.score;
}
$("btnStart").removeAttribute("disabled");
$("btnStart").style.color = "#000";
window.clearInterval(this.snakeTimer);
for (var i = 0; i < this.brakeTimers.length; i++) window.clearTimeout(this.brakeTimers[i]);
for (var i = 0; i < this.skateTimers.length; i++) window.clearTimeout(this.skateTimers[i]);
return;
}
if (this.carrier[headX][headY] == "brake" ) {
if (this.speed >= 20) {
this.speed -= 10;
this.move();
this.talk("慢一点,步子太快会扯着蛋~");
}else{
this.talk("已经很慢啦,不能再减速了~");
}
}
if (this.carrier[headX][headY] == "skate" ) {
if (this.speed <= 50) {
this.speed += 10;
this.move();
this.talk("带你飞~");
} else{
this.talk("不能再快啦~");
}
}
if(this.carrier[headX][headY] == "food"){
this.talk("吃到食物啦~");
this.score += 1;
$("score").innerHTML = this.score;
this.carrier[headX][headY] = '';
this.gridElems[headX][headY].className = "";
this.addObject("food");
if (this.len % 4 == 0 && this.speed < 60) {
this.speed += 2.5;
this.move();
this.talk("加速,加速~");
}
if (this.len % 6 == 0 && this.len < 60) {
this.addObject("block");
this.talk("增加难度啦~");
}
this.len += 1;
}else{
var tail = this.snake_pos.pop();
this.carrier[tail[0]][tail[1]] = "";
this.gridElems[tail[0]][tail[1]].className = false;
}
this.snake_pos.unshift([headX, headY]);
this.carrier[headX][headY] = "cover";
this.gridElems[headX][headY].className = "cover";
this.direction_changed = false;
}
this.move = function(){
if (this.snakeTimer) {
window.clearInterval(this.snakeTimer);
}
this.snakeTimer = window.setInterval(this.step.bind(this), Math.floor(3000 / this.speed));
}
this.talk = function(sth){
$(this.talk_id).innerHTML = sth;
}
this.clearAll = function(){
this.len = 3;
this.speed = 10;
this.directionkey = 39;
this.score = 0;
this.status = true;
this.pause = false;
for (var i = 0; i < this.HEIGHT; i++) {
for (var j = 0; j < this.WIDTH; j++) {
this.carrier[i][j] = false;
this.gridElems[i][j].className = "";
}
}
}
function randNum(start, end){
return (Math.floor(Math.random() * (end - start)) + start);
}
function randdot(carrier, startX, startY, endX, endY){
startX = startX || 0;
startY = startY || 0;
endX = endX || this.HEIGHT;
endY = endY || this.WIDTH;
var x = Math.floor(Math.random() * (endX - startX)) + startX;
var y = Math.floor(Math.random() * (endY - startY)) + startY;
var dot = [x, y];
if (carrier[x][y]) {
return randdot(carrier, startX, startY, endX, endY);
}
return dot;
}
function multiArray(m, n) {
var arr = new Array(m);
for (var i = 0; i < m; i++) {
arr[i] = new Array(n);
}
return arr;
}
}