零基础HTML5游戏制作教程 第6章 贪吃蛇的实现及代码

来源:互联网 发布:淘宝首页的广告位费用 编辑:程序博客网 时间:2024/05/17 20:44


第6章 贪吃蛇的实现及代码

        讲了不少东西了,老讲理论的东西没劲呀,我们不如先试着做一个小游戏吧。

        作为我们的第一个游戏,当然是越简单越好。《贪吃蛇》大家应该都玩过吧?我觉得我玩过的游戏中,她应该算是最简单的一个了。好,就让我们从做《贪吃蛇》开始,享受自己做游戏的乐趣吧。

        由于这个游戏是本教程的第一个实际的游戏例子,我会讲的比较详细一些。请大家重点注意编程的思路和实现的方法,这些远比代码本身要重要。


                    

一,蛇身的制作

        蛇身由一系列方格组成,初始我们设定蛇身的长度是4,以后每吃到一次食物就增加1。

        我们需要给组成蛇身的每一节一个坐标(可以保存在数组里),并设定一个变量var lenth=4;来存放蛇身的长度。

        这样我们要画出蛇身的时候就很容易,只要用一个for循环for(i=0;i<lenth;i++)就可以根据坐标,一个一个格子地画出蛇身。

二,蛇的前进

        这个对于初学者来说,可能有一点点困难。因为在某一时间点,整个蛇的前进方向可能是不一样的。

        比如蛇头正在向下运动,而尾巴可能还在向右。

        如果你仔细观察,你会发现,蛇的下一节的移动方向,就是她的前一节原来所在的地方。

        比如蛇的第一节(也就是蛇头)正在向右移动一格,那么她的第二节,就正在移动到第一节原来所在的地方;同样,第三节正在移动到第二节原来所在的地方。

        这样就好办了,我们只要让下一节的坐标直接等于上一节当前的坐标就可以了。

function move(){for(i=(lenth-1);i>=1;i--) {worma[i]=worma[i-1];  wormb[i]=wormb[i-1]; }}

        那么还剩第一节(蛇头),因为第一节是没有上一节的,所以第一节的坐标由蛇目前前进的方向(来自玩家的键盘输入)计算得出。

三,食物的随机出现

        贪吃蛇的食物是随机出现的。比如在我做的例子里,地图的宽度是30,高度是20,那么我们可以使用random函数和floor函数来获得一个宽30高20范围内的随机坐标。

        (函数中的foodboolean用于判断当前的food是否存在,如果不存在(=0),就生成新的food,如果已经存在(=1),就不新生成了。)

function getfood(){if(foodboolean==0) {fooda=Math.floor(Math.random()*20);  foodb=Math.floor(Math.random()*30);  foodboolean=1; }

四,判断是不是咬到了自己

        如果蛇头(第一节)碰到了她自己身体的其他任意一节,那么这个时候,这2节的坐标是一样的。我们可以根据这个来判断是不是咬到自己了。

for(i=1;i<=lenth-1;i++){if ((worma[i]==worma[0])&&(wormb[i]==wormb[0]))  {crash=1;}}

五,自动前进和防止后退

        键盘有4个方向,但是贪吃蛇在前进时,只有3个方向。我们只能让她向前,或左转,或右转,而不能向后转。所以如果玩家按了和当前前进方向相反的键盘按键,我们必须防止贪吃蛇反向移动。

        方法是设定一个变量,direction,用于储存当前的移动方向。如果玩家没有新的输入,那么贪吃蛇一直沿原来的方向走;如果有新的输入,那么在判断新的方向“合法”之后,存入direction变量,取代原来的方向。

        例子中的direction变量用于储存当前移动方向,dnext变量用于储存下一个移动方向。

function fkeydown(kd){if(Math.abs(direction-kd.keyCode)!=2) {dnext=kd.keyCode;};}


六,其他的一些说明

1,由于javascript不支持二维数组,所以用了2个数组来储存贪吃蛇的当前坐标,2个数组分别储存x和y坐标。(当然,可以用1维数组模拟2维,我们下一章讲地图的时候会讲到,但是这里没必要用,直接用2个数组更简单。)

2,有的人做《贪吃蛇》的时候喜欢把整个地图做成一个2维数组,然后在每一个地图的格子内储存一些值,比如0代表这一格是空的,1代表这一格有被贪吃蛇占据,2代表这一格是食物等等。这当然也可以,但是这样会比较复杂一点,也占用比较多的内存。因为贪吃蛇是最简单的游戏,所以我们可以把她尽量简化,我们可以完全不出现地图数组,只依靠坐标来判断。我们可以按照贪吃蛇和食物的坐标,而不是地图的值,直接把它们画出来;同样,根据坐标来直接判断贪吃蛇是否吃到食物,或者是否撞到她自己。

3,我下面的程序是今天新写的,为了这个教程才写的,没有改过,也没有经过简化(其实有部分函数可以合并)。但是我觉得作为零基础教程来说,每一个函数都很简单,反而更容易理解,所以就不去简化了。程序中的主要功能,已经在上面讲过了,剩余部分很简单。

4,本程序使用了结构化的方法,没有使用面向对象的方法。以后我们在做一些较复杂的游戏时,会使用面向对象。

5,本程序经测试,可以正常使用。

转载的话,请注明出处,谢谢
CSDN博客:  http://blog.csdn.net/trackstatic/
博客园博客:http://www.cnblogs.com/phyy/   地球生活eev 
(连本段一起复制,就算是注明出处了)
下面是源程序:


<html><head><title>greedy snake from eev</title><script>var x=0;var y=0;var i=0;var a=0;var b=0;var fooda=0;var foodb=0;var foodboolean=0;var lenth=4;var timer=0;var direction=39;var dnext=39;var crash=0;var worma=new Array();var wormb=new Array();worma[0]=10;wormb[0]=1;worma[1]=9;wormb[1]=1;worma[2]=8;wormb[2]=1;worma[3]=7;wormb[3]=1;var nexta=10;var nextb=1;function getfood(){if(foodboolean==0) {fooda=Math.floor(Math.random()*20);  foodb=Math.floor(Math.random()*30);  foodboolean=1; };}function next(){direction=dnext; if (direction==37) {fleft();} else if(direction==38) {fup();} else if(direction==39) {fright();} else if(direction==40) {fdown();} }function eat(){lenth=lenth+1; move(); foodboolean=0;}function eatormove(){if((foodboolean==1)&&(nexta==fooda)&&(nextb==foodb)) {eat();} else {move();};}function move(){for(i=(lenth-1);i>=1;i--) {worma[i]=worma[i-1];  wormb[i]=wormb[i-1]; }; worma[0]=nexta; wormb[0]=nextb;}function fleft(){if(wormb[0]>=1) nextb=wormb[0]-1; else nextb=29;}function fright(){if(wormb[0]<29) nextb=wormb[0]+1; else nextb=0;}function fup(){if(worma[0]>=1) nexta=worma[0]-1; else nexta=19;}function fdown(){if(worma[0]<19) nexta=worma[0]+1; else nexta=0;}function fkeydown(kd){if(Math.abs(direction-kd.keyCode)!=2) {dnext=kd.keyCode;};}function draw(){ctx.clearRect(0,0,1200,800); for(i=0;i<=lenth-1;i++) {x=wormb[i]*40;  y=worma[i]*40;  ctx.fillStyle="red";  ctx.fillRect(x,y,40,40); } if(foodboolean==1) {ctx.fillStyle="green";  x=foodb*40;  y=fooda*40;  ctx.fillRect(x,y,40,40); } }function refresh(){timer=timer+1; for(i=1;i<=lenth-1;i++) {if ((worma[i]==worma[0])&&(wormb[i]==wormb[0]))  {crash=1;}; }  if ((timer%5==1)&&crash==0) {next();  eatormove(); }; draw();  getfood(); }</script></head><body onkeydown="fkeydown(event)"><canvas id="canvas01" width="1200" height="800" style="background-color:black"></canvas><script>var cvs=document.getElementById("canvas01");var ctx=cvs.getContext("2d");ctx.fillStyle="red";var intval=setInterval("refresh();",100);</script></body></html>







0 0
原创粉丝点击