花了一下午时间,做了一个贪食蛇游戏,设计思想如下:
游戏在一个div中展开,它是游戏的背景地图,用table来做地图中的网格,蛇的每节身体都是一个div,用一个span代表食物。
定义一个全局二维数组map,用来代表地图中的每一块,数组有3种取值,0代表空地,1代表蛇,2代表食物,也就是说map[x][y]=1的
时候表示该位置是蛇,等于0的时候表示该位置什么都没有,等于2的时候表示该位置是食物。
对于蛇的移动,以map这个数组作为参照,对于水平方向的移动,map的行标不变,列标加减,对于垂直方向的运动,列标不变,行
标加减,也就是说,如果蛇当前在map[x][y]这个位置上的话,map[x-1][y]就表示蛇向上移动了一个单位,以此类推。每次移动前,首先
判断前方的位置是什么,如果是空地,即map[new_x][new_y]=0,则移动到该位置,如果是蛇的身体,则游戏结束,如果是食物,则
吃掉食物,自身增加一节,即增加一个div。
不过只能在IE下运行,在火狐、chrome下会报错,不知为什么。
代码如下:
css
body {
font-size: 12px;
}
.info_div{
margin: 20px;
float: left;
}
.info_div span{
margin: 10px;
display: block;
}
.canvas{
border: 2px solid gray;
width: 450px;
height: 450px;
}
table{
width: 450px;
height: 450px;
border-collapse:collapse;
overflow: hidden;
}
table,tr,td{
border: 1px solid gray;
}
.snake{
background-color: red;
width: 15px;
height: 15px;
position: absolute;
}
.food{
background-color: green;
width: 11px;
height: 11px;
position: absolute;
}
js
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.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>snake</title>
<link rel="stylesheet" type="text/css" href="snake.css"/>
</head>
<body>
<div class="info_div">
<span>按上、下、左、右控制蛇移动</span>
<span>按S键暂停游戏,按方向键继续</span>
<span>按上下翻页键改变速度</span>
<span id="currentspeed">当前速度:150</span>
<span id="foodcount">所吃食物数量:0</span>
</div>
<script type="text/javascript">
var x;//定义蛇的位置
var y;
var fx;//定义食物位置
var fy;
var old_x;//先前位置
var old_y;
var map;//全局二维数组
var canvas;//背景地图div
var food;//食物span
var snake;//蛇div
var step_x;//移动参数
var step_y;
var snakeBody;//用来保存蛇的尾巴
var run;
var count = 0;
var speed = 150;
var start = true;
//创建背景地图
function createCanvas() {
canvas = document.createElement("div");
canvas.className = "canvas";
canvas.style.left = document.body.clientWidth / 2 - 225;
canvas.style.top = document.body.clientHeight / 2 + 40;
canvas.style.position = 'absolute';
document.body.appendChild(canvas);
init();
}
//初始化二维数组,将蛇,食物添加到地图上
function init() {
map = new Array();
for (var i = 0; i < 30; i++) {
map.push(new Array());
for (var j = 0; j < 30; j++) {
map[i].push(0);
}
}
x = parseInt(Math.random() * 30);
y = parseInt(Math.random() * 30);
createGrid();
createSnake();
createFood();
snakeBody = new Array();
snakeBody = canvas.getElementsByTagName("div");
}
//创建背景网格
function createGrid() {
var grid = document.createElement("table");
grid.className = "grid";
var tr;
var td;
for (var i = 0; i < 30; i++) {
tr = document.createElement("tr");
for (var j = 0; j < 30; j++) {
td = document.createElement("td");
tr.appendChild(td);
}
grid.appendChild(tr);
}
canvas.appendChild(grid);
}
//创建蛇,其中current_x,y是自定义的属性,用来保存蛇当前的位置,方便后面删除。
//每调用一次,蛇增加一节
function createSnake() {
snake = document.createElement("div");
snake.setAttribute('current_x', x);
snake.setAttribute('current_y', y);
snake.className = "snake";
snake.style.left = y * 15;
snake.style.top = x * 15;
map[x][y] = 1;
canvas.appendChild(snake);
}
//随机生成食物位置,如果和蛇的位置重复,则重新生成
function createFoodLocation() {
fx = parseInt(Math.random() * 30);
fy = parseInt(Math.random() * 30);
if (map[fx][fy] == 1) {
createFoodLocation();
}
}
//生成食物
function createFood() {
createFoodLocation();
food = document.createElement("span");
food.className = "food";
food.style.left = fy * 15 + 2;
food.style.top = fx * 15 + 2;
canvas.appendChild(food);
map[fx][fy] = 2;
}
//蛇自动前进,根据front的值来判断前方是什么,同过调用createSnake方法,达到蛇移动效果
function forward() {
x += step_x;//在map数组上的移动,根据不同的step_x,y值,生成新的x,y
y += step_y;
//如果碰到边框,游戏结束
if (x < 0 || x > 29 || y < 0 || y > 29) {
gameOver();
}
var front = map[x][y];
switch(front) {
case 0:
go();
break;
case 1:
gameOver();
break;
case 2:
eat();
break;
}
//在新位置构建蛇div,当前方是食物时,蛇自动增长一节
createSnake();
}
//游戏结束
function gameOver() {
if (confirm('Game Over,是否重新开始?')) {
reStart();
}
}
//如果前方是空地,将当前位置的蛇div删除。
function go() {
map[snakeBody[0].getAttribute('current_x')][snakeBody[0].getAttribute('current_y')] = 0;
canvas.removeChild(snakeBody[0]);
}
//如果前方是食物,删除该食物,同时在新位置生成食物
function eat() {
canvas.removeChild(food);
createFood(); ++count;
document.getElementById("foodcount").innerText = '所持食物数量:' + count;
}
//刷新页面
function reStart() {
location.reload();
}
function keyDown(e) {
if (e)
keycode = e.keyCode;
else
keycode = window.event.keyCode
switch(keycode) {
case 37://按下左键
directionMove(0, -1);
break;
case 38://按下上键
directionMove(-1, 0);
break;
case 39://按下右键
directionMove(0, 1);
break;
case 40://按下下键
directionMove(1, 0);
break;
case 33://上翻页
speedAdjust(33);
break;
case 34://下翻页
speedAdjust(34);
break;
case 83://s
stop();
break;
}
}
//开始游戏,蛇开始移动
function begin() {
if (start) {
run = window.setInterval('forward()', speed);
start = false;
}
}
//改变速度后,调用该方法,使其以新的速度移动
function reBegin() {
if (run != null) {
window.clearInterval(run);
run = window.setInterval('forward()', speed);
}
}
//游戏暂停
function stop() {
window.clearInterval(run);
start = true;
}
//控制方向
function directionMove(dx, dy) {
step_x = dx;
step_y = dy;
//判断是否反向,如果跟当前运动方向相反,则继续当前方向运动,否则保存当前方向。
if (old_x + dx == 0 && old_y + dy == 0) {
step_x = old_x;
step_y = old_y;
} else {//保存当前方向
old_x = dx;
old_y = dy;
}
begin();
}
//调节速度
function speedAdjust(key) {
if (key == 33) {
speed -= 20;
if (speed < 20) {
speed = 20;
}
} else {
speed += 20;
if (speed > 500) {
speed = 500;
}
}
reBegin();
document.getElementById("currentspeed").innerText = '当前速度:' + speed;
}
createCanvas();
//绑定键盘
document.onkeydown = keyDown;
</script>
</body>
</html>