在很早学 QuickBasic 的时候,就有一个蛇吃食物的游戏,当时是作为 Basic 的一个示例提供的。当时只顾得玩了,竟没想到要把那些高人写的代码好好分析一下。现在做 Web 开发的培训,有一个用 Javascript 写的类似的小游戏,就花了大半天好好看了一下代码,觉得写的不错。
功能:蛇吃食物有三种情况:走到的地方有食物;走到的地方没有食物;走到的地方是墙壁。吃到食物后,蛇的身体会变长;碰到墙壁后 Game Over,询问是否重新开始。
整个游戏是在一个<div>框子(地图)里展开的,蛇有地图里的一系列<div>构成,初始状态(刚刚打开页面)蛇是一个<div>框,蛇头和蛇尾是在一起的,就是这个<div>框,以后吃了食物后<div>个数会变多,蛇就会长长。食物用一个<span>框表示,初始时和蛇一样其位置是随机产生的。蛇和食物的坐标用<div>和<span>的绝对位置表示。
算法的关键是当蛇移动到新的位置后,判断前述的三种情况,做出相应的处理。而二维数组 Map 就是判断的依据。二维数组 Map通过其元素的值来表示蛇身、食物和空地。蛇身、食物和空地的值分别为''S''、''F''和''0''。
用 Javascript 编程和其他语言的一个大的区别就是键盘的控制代码不同。js是通过 Key=event.keyCode 语句获取键盘码,再在多分支 switch 结构里分别处理。看完这些代码就会对浏览器里的键盘控制有所了解了。
当然该段代码的最大价值还是让我们了解到网页游戏的大概写法,而算法其实是最重要的,把一个游戏的设想变为一堆包含许多的函数的结构化的代码,是值得我们借鉴和学习的。
代码里有我的注释,结合我的以上大概分析介绍差不多能看懂了。
题外问题:本人在调试的时候打算给原来的代码加一段方格显示功能,就写了个ShowGrid()函数,采用代码生成方格。但由于在2层循环内完成方格显示,效率十分低下,生成15*10的方格需要大约6秒。生成30*20 的方格竟然需要几分钟。基本不能采用此方法。改进建议:采用图片,既美观,速度也快。
<HTML>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>贪吃蛇</title>
</head>
<STYLE>
.Food { background-color: green;}
.Snake {background-color: red;}
.grid {border:1px solid #000}
</STYLE>
<SCRIPT langyage="javascript">
var Rows=10
var Cells=15
var Num=20 //正方形格子的边长
var BorderWidth=5
var SpeedUp=5000
//创建地图
function CreateMap()
{
BW = eval(Cells*Num + 2*BorderWidth) //宽度
BH = eval(Rows*Num + 2*BorderWidth) //高度
document.body.innerHTML+=''<div id=MainMap style=position:absolute;left:''+(document.body.clientWidth-BW)/2+'';top:''+(document.body.clientHeight-BH)/2+'';width:''+BW+'';height:''+BH+'';border-width:''+BorderWidth+'';border-style:outset;border-color:#0000ff></div>''
Map = new Array() //创建全局数组Map
for(y=0; y<Rows; y++)
{
Map[y]=new Array() //创建全局二维数组Map,初始值为''0''
for(x=0; x<Cells; x++)
Map[y][x] = ''0'' //''0''值表示“空地”
}
//ShowGrid(); //显示地图内格子
Sx = parseInt(Math.random()*Cells) //创建全局变量Sx,赋予随机数
Sy = parseInt(Math.random()*Rows) //创建全局变量Sy,赋予随机数
CreateSnake() //生成蛇 - div
CreatFood() //生成食物 - span
AllDiv = MainMap.all.tags(''DIV'') //创建全局数组AllDiv,只有一个元素AllDiv[0]。MainMap是div的ID
AllSpan = MainMap.all.tags(''SPAN'') //创建全局数组AllSpan,只有一个元素AllSpan[0]
}
//显