分享
 
 
 

JAVASCRIPT 贪吃蛇

王朝html/css/js·作者佚名  2008-09-17
窄屏简体版  字體: |||超大  

在很早学 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]

}

//显示地图内格子

function ShowGrid()

{

for(r=0; r<Rows; r++) //行

{

t = r*Num;

for(c=0; c<Cells; c++) //列

{

l = c*Num;

MainMap.innerHTML += '<table style="position:absolute;left:'+ l +';top:'+ t +';width:'+Num+';height:'+Num+';" cellpadding=0 cellspacing=0><tr><td align=center valign=middle class=grid>O</td></tr><table>'

}

}

}

//创建蛇的初始位置,赋予初始值'S'

function CreateSnake()

{

//<div>表示蛇身,通过调用本函数,可以累加到若干个,蛇身变长

//注意 y 和 x 是“蛇”<div> 的自定义属性。一直保存着蛇尾(!)的当前位置

//初始时,蛇头、蛇尾是同一个位置

MainMap.innerHTML += '<div x='+Sx+' y='+Sy+' style=position:absolute;left:'+Sx*Num+';top:'+Sy*Num+';width:'+Num+';height:'+Num+';overflow:hidden class=Snake></div>'

Map[Sy][Sx]='S' //Snake首字母

}

//创建食物的位置,赋予初始值'F'

//食物的初始位置不能与蛇的初始位置相同,只能在空地放置食物。

//若随机产生的2位置相同,则递归执行,直到不相同为止

function CreatFood()

{

Fx = parseInt(Math.random()*Cells)

Fy = parseInt(Math.random()*Rows)

if(Map[Fy][Fx]=='0') //如果是空地

{

MainMap.innerHTML += '<span style=position:absolute;left:'+Fx*Num+';top:'+Fy*Num+';width:'+Num+';height:'+Num+';overflow:hidden class=Food></span>'

Map[Fy][Fx]='F' //Food首字母

}

else

CreatFood() //递归

}

//主移动--判断蛇头前面的是什么

function Move()

{

Sx += GoX //自动行走,Map[Sy][Sx]为当前位置

Sy += GoY

if(Sy<0||Sy>=Rows) //碰墙,重新开始

Move1()

else

{

SnakeFront = Map[Sy][Sx]

if(SnakeFront=='0') //蛇前是空地

Move2()

else

{

if(SnakeFront=='F') //蛇前面是食物

Move3()

else

Move1()

}

}

}

//重新开始

function Move1()

{

if(confirm("Game Over,重新开始?"))

window.location.reload()

}

var Times=200

//蛇行走到的当前位置是空地时

function Move2()

{

Map[AllDiv[0].y][AllDiv[0].x]='0' //蛇走开后,把原位置设置为'0',表示是空地

AllDiv[0].removeNode(true) //把蛇数组当前元素删除,在下面的 CreateSnake()语句重新生成

CreateSnake() //在新的位置生成蛇的<div>

setTimeout('Move()',Times) //再次移动

}

//蛇行走到的当前位置是食物时

function Move3()

{

CreateSnake() //蛇数组当前元素不删除,<div>累加一次,蛇长长一节

AllSpan[0].removeNode(true) //把食物数组当前元素删除,在下面的 CreatFood()语句重新生成

CreatFood() //再次随机生成食物

setTimeout('Move()',Times) //再次移动

}

//蛇越行越快

function oTimes()

{

Times -= 5

if(Times>5)

setTimeout('oTimes()', SpeedUp)

}

document.onkeydown=KeyDown

//方向

function KeyDown()

{

Key=event.keyCode

switch(Key){

case 37:

Dir(-1,0);break //左方向键

case 39:

Dir(1,0);break //右方向键

case 38:

Dir(0,-1);break //上方向键

case 40:

Dir(0,1);break} //下方向键

return false

}

var Star=0

function Dir(x,y)

{

GoX=x

GoY=y

if(Star==0)

{

oTimes()

Star=1

Move()

}

}

//页面打开时运行

onload = CreateMap; //注意无"()",不是 CreateMap()

//在<body>中调用的语法是:<BODY onload="CreateMap()">,必须加"()"

</SCRIPT>

<BODY>

<div id="help">

红色方块表示蛇,绿色方块表示食物。按方向键开始。<br>

</div>

</BODY>

</HTML>

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有