网页游戏“贪食蛇”简析
2008-09-12 19:35
120 查看
在很早学 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 的方格竟然需要几分钟。基本不能采用此方法。改进建议:采用图片,既美观,速度也快。
改进建议:
- 增加速度控制功能;
- 美化界面,增加蛇头、蛇身和蛇尾形状。美化地图;
- 增加声音;
- 增加换肤功能;
- 修正:长度等于或大于2节的蛇体,按倒退键时结束游戏的错误;
功能:蛇吃食物有三种情况:走到的地方有食物;走到的地方没有食物;走到的地方是墙壁。吃到食物后,蛇的身体会变长;碰到墙壁后 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 的方格竟然需要几分钟。基本不能采用此方法。改进建议:采用图片,既美观,速度也快。
改进建议:
- 增加速度控制功能;
- 美化界面,增加蛇头、蛇身和蛇尾形状。美化地图;
- 增加声音;
- 增加换肤功能;
- 修正:长度等于或大于2节的蛇体,按倒退键时结束游戏的错误;
<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>…</div>表示蛇身,通过调用本函数,可以累加到若干个<div>…</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>
相关文章推荐
- 网页游戏“贪食蛇”简析
- 网页游戏“贪食蛇”简析
- 转载于"网眼"---网页游戏“贪食蛇”简析
- Flash网页游戏辅助工具制作简析
- Flash网页游戏辅助工具制作简析
- 网页游戏“贪食蛇”改进(1)
- \t\tFlash网页游戏辅助工具制作简析
- 网页游戏“贪食蛇”改进(2-代码)
- Flash网页游戏辅助工具制作简析
- javascript网页游戏--贪食蛇代码
- Flash网页游戏辅助工具制作简析
- Flash网页游戏辅助工具制作简析
- 网页游戏“贪食蛇”改进
- JavaScript强化教程 - 六步实现贪食蛇
- WebRTC中peerconnectclient&server 简析【转】
- 【HTTP】另类的POST头数据 RFC1867协议格式简析
- JavaScript强化教程 - 六步实现贪食蛇
- (1)RIL简析(高通)——RIL如何启动及初始化
- 分布式系统的事务处理简析
- linux目录结构简析