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

第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>
时间: 2024-08-07 08:22:44

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

零基础HTML5游戏制作教程 第5章 碰撞检测

第5章 碰撞检测 几乎所有的游戏都需要碰撞检测.比如<贪吃蛇>,你需要检测蛇的前端是不是已经碰到了它的尾巴:比如<俄罗斯方块>,你需要检查方块是不是已经碰到了底部:比如<英雄联盟>,你需要判断adc的子弹或魔法是不是已经碰到了对方. 其实要做好碰撞检测是很难的,尤其是对于3d游戏或者图形复杂的2d游戏来说. 当然,对于简单图形来说,碰撞检测还是比较容易的,本章将分别介绍圆形的碰撞检测,矩形的碰撞检测,以及逻辑碰撞检测. 一,圆形碰撞检测 圆形间碰撞检测的原理是最简单的,

零基础HTML5游戏制作教程 第2章 简单图形的绘制

第二章 简单图形的绘制 HTML5支持使用Canvas和SVG等方式在网页直接绘制图形.其中SVG适合用来绘制高质量的矢量图形,不适合用来做游戏,所以我们做游戏一般使用Canvas. 由于本教程以简单为原则,所以在初学阶段请不要把注意力分散到美工.画质等细节,我们只需要掌握矩形.多边形.圆形等简单图形的绘制,并对这些图形编程,使之具有一定的运动能力和游戏效果. (如果你偷懒,你甚至可以跳过本章中多边形和圆形的绘制,只学矩形,然后直接去看下一章.) 一,矩形的绘制 命令的格式是context.fi

零基础HTML5游戏制作教程 第4章 移动的控制

第4章 移动的控制 一,捕获键盘击键的原理 有很多种方法可以控制游戏中图形的移动,常用的有键盘控制.鼠标控制以及屏幕上的按钮控制等.其中键盘控制比较简单,比较适合初学者,我们先来讲这种方法. 其实键盘上的每一个按键,在我们按下去的时候,会向电脑中传送一个编号.比如A的编号是65,B是66.在这一章里,我们只需要记住4个键就可以了,她们是光标的上下左右键.向上的编号是38,向下是40,向左是37,向右是39. 所以键盘捕获的原理其实很简单,就是读取键盘传到电脑中的编号,然后根据这个编号来判断哪个键

零基础HTML5游戏入门教程 第1章

第一章 绪论 HTML一直是网络编程的基石,其他任何编程语言,不论是PHP.Phython.CSS还是 JavaScript,都必须以HTML为基础. 上一代的标准,HTML4.01在1999年制定之后,统治互联网长达15年,越来越跟不上飞速发展的网络的步伐,尤其是在无线互联日益普及的今天.终于,在多年的争论和妥协之后,万维网联盟(W3C)在1个月前发布了HTML新标准.让我们一起来迎接我们的新王者HTML5. HTML5对网络的提升是多方面的,本教程只关注游戏方面.其实HTML5是一个相当不错

零基础unity3d游戏开发系列目录

零基础Unity3D游戏开发系列 第一章:游戏开发与游戏引擎(一) 零基础Unity3D游戏开发系列 第一章:游戏开发与游戏引擎(二) 零基础Unity3D游戏开发系列 第二章:Unity3D概览(一)界面... 零基础Unity3D游戏开发系列 第二章:Unity3D概览(一)创建与打开项目I 零基础unity3d游戏开发系列 第二章:unity3d概览(一)创建与打开项目II 零基础Unity3D游戏开发系列 第二章:Unity3D概览(一)创建与打开项目III 零基础Unity3D游戏开发

下载云计算Docker从零基础到专家实战教程【第一季】

云计算.大数据,移动技术的快速发展,加之企业业务需求的不断变化,导致企业架构要随时更改以适合业务需求,跟上技术更新的步伐.毫无疑问,这些重担都将压在企业开发人员身上:团队之间如何高效协调,快速交付产品,快速部署应用,以及满足企业业务需求,是开发人员亟需解决的问题.Docker技术恰好可以帮助开发人员解决这些问题. 云计算Docker从零基础到专家实战教程[第一季],刚刚入手,转一注册文件,视频的确不错,可以先下载看看:http://pan.baidu.com/s/1hsO74Gk 密码:g58j

Unity网络多玩家游戏开发教程第1章Unity自带网络功能

Unity网络多玩家游戏开发教程第1章Unity自带网络功能 Unity拥有大量的第三方插件,专门提供了对网络功能的支持.但是,大部分开发者第一次接触到的还是Unity自带的网络功能,也就是大家经常说到的Unity Networking API.这些API是借助于组件NetworkView发挥作用的,而它可以简化开发者大量的网络功能编码任务.本文选自<Unity网络多玩家游戏开发教程(大学霸内部资料)> NetworkView组件 在Unity中,NetworkView组件用于处理游戏在网络上

游戏开发(一)——控制台 贪吃蛇

贪吃蛇游戏设计中主要需要注意的几点: 1:坐标的定义:定义为左上角为(0,0),向右为x正方向,向下为y正方向 2:蛇的设计, 蛇身:m_body,这里用的是链表(是之前写好的双链表),一个节点就是蛇身的一节 每节蛇身的属性包括x,y坐标:column_x,row_y,x表示在地图上的第几列,y表示在地图上的第几行 蛇有一个属性叫朝向,也就是当前在往上.下.左.右的哪个方向移动:m_forward 蛇的动作有:Turn,转向.转向有个判断,就是不能向相反的方向转,比如本来向上运动,按向下键,是无

游戏开发怎么样学能入门零基础学游戏编程

游戏编程入门级教程,讲解通俗易懂.用具体实例讲解的方式让你用最短的时间掌握游戏编程基础知识.本程序使用中文开发平台搭建之星,搭建之星采用可视化构件,不需有英文基础,开发速度极快,操作非常简单.不论你使用何种编程语言开发,本课程里的例子都是一个很好的学习例子,参考其编程思路,对快速掌握开发技术非常有益.部分内容如下:生成我方战机编程生成敌方战机编程炮弹发射编程为游戏配音游戏空间的时光控制看完就会,自动动手制作游戏.游戏编程教程资料 原文地址:http://blog.51cto.com/131720