前阵子无聊,试着用原生态JavaScript写了写贪吃蛇。一开始写的时候因为以前写的是C,所以想的就是面对过程,于是写了一坨翔出来。。。不过还是把代码贴上来吧:
<!--HTML CODE:-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Zombie Snake</title>
<script type="text/javascript" src="ZombieSnake.js"></script>
<link rel="stylesheet" type="text/css" href="ZombieSnake.css" />
</head>
<body>
<div id="pannel"></div>
<select name="" id="snakeSpeed">
<option value="100">god damn</option>
<option value="500" selected="selected">normal people</option>
<option value="1000">just for baby</option>
</select>
<input type="button" id="snakeStart" value="start" />
</body>
</html>
/*CSS CODE:*/
#pannel table {
border-collapse: collapse;
margin-bottom: 10px;
}
#pannel td {
width: 10px;
height: 10px;
border: 1px solid black;
}
.food {
background: black;
}
.snake {
background: green;
}
.wall {
background: red;
}
//JavaScript CODE:
var gameSetting = {
Speed : 500, //speed of snake
Size : 20, //size of pannel
Len : 3, //length of snake
Func : null
};
var direction = {
left : 37,
up : 38,
right : 39,
down : 40
};
var Snake,
direct,
inside;
window.onload = function() {
createTable("pannel");
window.onkeydown = listen;
document.getElementById("snakeSpeed").onchange = function() {
gameSetting.Speed = this.value;
}
document.getElementById("snakeStart").onclick = function() {
start();
this.disabled = true;
}
}
function start() {
direct = direction.down;
Snake = new Array();
inside = cubeArray(gameSetting.Size);
createSnake();
createFood();
move();
createWall();
}
function cubeArray(m) {
var arr = new Array(m);
for (i = 0; i < m; i ++) {
arr[i] = new Array(m);
}
return arr;
}
function addObj (x, y, name) {
var obj = document.getElementById("box" + x + "_" + y);
obj.className = name;
}
function restart() {
for (var x = 0; x < gameSetting.Size; x ++)
for (var y = 0; y < gameSetting.Size; y ++) {
document.getElementById("box" + x + "_" + y).className = "";
document.getElementById("snakeStart").removeAttribute("disabled");
}
}
function createTable (pid) {
var t = [];
t.push("<table>");
for (var j = 0; j < gameSetting.Size; j ++) {
t.push("<tr id = row" + j +">");
for (var i = 0; i < gameSetting.Size; i ++) {
t.push("<td id = 'box" + i + "_" + j + "'x ='" + i + "' y ='" + j + "'></td>");
};
t.push("</tr>");
};
t.push("</table>");
var p = document.getElementById(pid);
p.innerHTML = t.join("");
};
function createWall() {
for (var i = 0; i < 20; i ++)
document.getElementById("box" + i + "_0").className = "wall";
for (var i = 0; i < 20; i ++)
document.getElementById("box" + i + "_19").className = "wall";
for (var i = 0; i < 20; i ++)
document.getElementById("box" + "0_" + i).className = "wall";
for (var i = 0; i < 20; i ++)
document.getElementById("box" + "19_" + i).className = "wall";
}
function createPoint(startX, startY, endX, endY) {
var x = Math.floor(Math.random() * (endX - startX)) + startX;
var y = Math.floor(Math.random() * (endY - startY)) + startY;
var p = [];
p[0] = x;
p[1] = y;
return p;
}
function createSnake() {
var point = createPoint(gameSetting.Len, gameSetting.Len, gameSetting.Size / 2, gameSetting.Size / 2);
for (var i = 0; i < gameSetting.Len; i ++) {
var x = point[0];
var y = point[1] - i;
Snake.push([x, y]);
addObj(x, y, "snake");
}
}
function createFood() {
var foodPoint = createPoint(1, 1, gameSetting.Size - 1, gameSetting.Size - 1);
if(document.getElementById("box" + foodPoint[0] + "_" + foodPoint[1]).className == "snake") return createFood();
addObj(foodPoint[0], foodPoint[1], "food");
inside[foodPoint[0]][foodPoint[1]] = "food";
}
function listen(e) {
e = e || event;
direct = Math.abs(e.keyCode - direct) != 2 && e.keyCode > 36 && e.keyCode < 41 ? e.keyCode : direct;
}
function move() {
if (gameSetting.Func) window.clearInterval(gameSetting.Func);
gameSetting.Func = window.setInterval(step, gameSetting.Speed);
}
function step() {
var headX = Snake[0][0],
headY = Snake[0][1],
lastX = Snake[Snake.length - 1][0],
lastY = Snake[Snake.length - 1][1];
addObj(lastX, lastY, "");
for (var i = Snake.length - 1; i > 0; i --) {
Snake[i][0] = Snake[i - 1][0];
Snake[i][1] = Snake[i - 1][1];
}
switch (direct) {
case direction.up: headY -= 1; break;
case direction.down: headY += 1; break;
case direction.left: headX -= 1; break;
case direction.right: headX += 1; break;
}
Snake[0][0] = headX;
Snake[0][1] = headY;
for (var i = 0; i < Snake.length; i ++) {
addObj(Snake[i][0], Snake[i][1], "snake");
}
//eat food
if (inside[headX][headY] == "food") {
createFood();
Snake.unshift([headX, headY]);
}
if (headX >= 19 || headX <= 0 || headY >= 19 || headY <=0 ) {
window.clearInterval(gameSetting.Func);
alert("game over! :D ");
restart();
}
}
如上所示,写的简直就是一坨翔,完全不堪入目。功能也没有怎么完善:比如说撞到自己的判断没有写,数组操作烂到了一种水平,写了一大堆函数看得头都晕了,还掺杂了一大堆的全局变量……于是看了点书后我又写了另一个版本,是面向对象的:
<!--HTML CODE:-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Snake</title>
<link rel="stylesheet" type="text/css" href="snake.css" />
</head>
<body>
<div id="game">
<div id="pannel"></div>
</div>
<div id="button">
<input type="button" id="start" value="start" />
</div>
</body>
<script type="text/javascript" src="snake.js"></script>
</html>
/*CSS CODE:*/
#pannel table {
border-collapse: collapse;
margin-bottom: 10px;
}
#pannel td {
width: 10px;
height: 10px;
border: 1px solid black;
}
.food {
background: black;
}
.snake {
background: green;
}
//JavaScript CODE:
(function () {
/*全局变量*/
var g = {
//获得or设置盒子的attribute
attr : function (x, y, att, name) {
var d = document.getElementById("box_" + x + "_" + y);
if (d && name)
d.setAttribute(att, name);
else if (d)
return d.getAttribute(att);
},
//随机创建点
create : function (start, end) {
return Math.floor(Math.random() * (end - start) + start);
},
//运动方向
direction : {
left : 37,
up : 38,
right : 39,
down : 40
},
//游戏设定
setting : {
size : 20,
speed : 500,
len : 3,
func : null,
direct : null
}
}
/*Game构造器*/
function Game () {
/*创建格子*/
this.pannel = function () {
var t = [];
t.push("<table>");
for (var i = 0; i < g.setting.size; i ++) {
t.push("<tr class = 'row' y = " + i + ">");
for (var j = 0; j < g.setting.size; j ++) {
t.push("<td id = 'box_" + j + "_" + i + "'></td>");
}
t.push("</tr>");
}
t.push("</table>");
document.getElementById("pannel").innerHTML = t.join("");
};
/*初始化游戏*/
this.init = function () {
if (g.setting.func)
window.clearInterval(g.setting.func);
var d = document.getElementById("start");
if (d)
d.disabled = false;
for (var x = 0; x < g.setting.size; x ++)
for (var y = 0; y < g.setting.size; y ++)
g.attr(x, y, "class", " ");
}
/*游戏开始*/
this.start = function () {
g.setting.direct = g.direction.down;
var snake = new Snake(), food = new Food();
food.create();
snake.create();
//蛇移动
g.setting.func = window.setInterval(snake.move, g.setting.speed);
}
/*监听键盘*/
this.listen = function (e) {
e = e || event;
g.setting.direct = Math.abs(e.keyCode - g.setting.direct) != 2 && e.keyCode > 36 && e.keyCode < 41 ? e.keyCode : g.setting.direct;
}
/*游戏结束*/
this.over = function () {
alert("game over XD!");
game.init();
};
};
/*Snake构造器*/
function Snake () {
var headX, headY, pos = [], that = this;
/*创建蛇*/
this.create = function () {
var x = g.create(g.setting.len, g.setting.size / 2),
y = g.create(g.setting.len, g.setting.size / 2);
//获得蛇的坐标
for (var i = 0; i < g.setting.len; i ++) {
y --;
pos.push([x, y]);
g.attr(x, y, "class", "snake");
}
};
/*移动*/
this.move = function () {
headX = pos[0][0];
headY = pos[0][1];
lastX = pos[pos.length - 1][0];
lastY = pos[pos.length - 1][1];
g.attr(lastX, lastY, "class", " ");
for (var i = pos.length - 1; i > 0; i --) {
pos[i][0] = pos[i - 1][0];
pos[i][1] = pos[i - 1][1];
}
switch (g.setting.direct) {
case g.direction.up : headY -= 1; break;
case g.direction.down : headY += 1; break;
case g.direction.left : headX -= 1; break;
case g.direction.right : headX += 1; break;
}
pos[0][0] = headX;
pos[0][1] = headY;
for (var i = 0; i < pos.length; i ++)
g.attr(pos[i][0], pos[i][1], "class", "snake");
var inside = g.attr(headX, headY, "inside");
//吃食物
if (inside == "food") {
lastX = pos[pos.length - 1][0];
lastY = pos[pos.length - 1][1];
if (lastX == pos[pos.length - 2][0]) {
if (lastY - pos[pos.length - 2][1] == 1)
pos.push([lastX, lastY + 1]);
else if (pos[pos.length - 2][1] - lastY == 1)
pos.push([lastX, lastY - 1]);
}
else if (lastY == pos[pos.length - 2][1]) {
if (lastX - pos[pos.length - 2][0] == 1)
pos.push([lastX + 1, lastY])
else if (pos[pos.length - 2][0] - lastX == 1)
pos.push([lastX - 1, lastY]);
}
lastX = pos[pos.length - 1][0];
lastY = pos[pos.length - 1][1];
g.attr(lastX, lastY, "class", "snake");
var food = new Food();
food.create();
};
//撞到自己或者墙,游戏结束
for (var i = 1; i < pos.length; i ++) {
if (headX == pos[i][0] && headY == pos[i][1])
game.over();
else
continue;
}
if (headX > 19 || headX < 0 || headY > 19 || headY < 0)
game.over();
};
};
/*Food构造器*/
function Food () {
var that = this;
/*创建食物*/
this.create = function () {
var x = g.create(0, g.setting.size),
y = g.create(0, g.setting.size);
//检查是否与蛇的位置重合
var c = g.attr(x, y, "class");
if (c == "snake")
return that.create();
else {
g.attr(x, y, "class", "food");
g.attr(x, y, "inside", "food");
}
};
};
var game = new Game();
game.pannel();
game.init();
document.getElementById("start").onclick = function () {
this.disabled = true;
game.start();
window.onkeydown = game.listen;
}
})()
这个版本因为写的太过匆忙,所以有些功能没有加:比如调整蛇的移动速度什么的……有空再说吧……
【END】