WEB开发网
开发学院网页设计JavaScript JAVASCRIPT 贪吃蛇 阅读

JAVASCRIPT 贪吃蛇

 2008-09-16 20:01:39 来源:WEB开发网   
核心提示: 在很早学 QuickBasic 的时候,就有一个蛇吃食物的游戏,JAVASCRIPT 贪吃蛇,当时是作为 Basic 的一个示例提供的,当时只顾得玩了,必须加"()" </SCRIPT> <BODY> <div id="help">

   在很早学 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 >,必须加"()"
   </SCRIPT>

   <BODY>
   <div id="help">
   红色方块表示蛇,绿色方块表示食物。按方向键开始。<br>
   </div>
   </BODY>
   </HTML>

Tags:JAVASCRIPT 贪吃

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接