1、第10章 贪吃蛇10.1 游戏说明10.2 准备工作10.3 游戏主体10.4 完善游戏10.1 游游 戏戏 说说 明明随着手机普及率的提高,有一个小游戏为很多人所认识,那就是本章要学习的贪吃蛇游戏。贪吃蛇游戏的原理是:通过上下左右的方向按钮控制小蛇去接触食物,一旦接触到食物后,就意味着小蛇吃掉了食物,每吃一次食物增加相应分数,小蛇也长长一截,并且重新投放食物,而小蛇碰到四面墙壁或碰到自己均意味着小蛇死亡。下面,我们就用Flash来实现这个游戏。10.2 准准 备备 工工 作作10.2.1 游戏制作游戏制作1制作背景制作背景(1)运行Flash,新建一个550400像素的动画文件。(2)单击图
2、层1的第1帧以选中。选择矩形工具,在属性面板中设置笔触颜色为“无”,填充颜色为“深蓝”,在舞台上绘制一个矩形。(3)在工具箱中换用选择工具。单击矩形以选中,在属性面板中确保小锁打开,将矩形的宽和高都设置为“400”,x和y都设置为“0”。(4)用矩形工具,在属性面板中设置笔触颜色为“无”,填充颜色为“浅蓝”,在舞台上离开上一矩形的位置绘制一个浅蓝色矩形。(5)在工具箱中换用选择工具。单击矩形以选中,在属性面板中确保小锁打开,将矩形的宽设置为“150”,高设置为“400”,x设置为“400”,y设置为“0”。效果见图10-1。图10-1(6)双击图层1,改名为“backgound”,并单击该层小
3、锁对应的黑点以锁定图层。这一层就作为背景层。2制作边框制作边框(1)新建图层,双击图层,改名为“border”。(2)保持border图层的第1帧被选中,选中矩形工具,在属性面板中设置填充颜色为“白到黑的渐变”(见图10-2),绘制矩形。图10-2(3)使用选择工具选中矩形,并在属性面板中设置宽为“12”,“高”为“400”,x为“388”,y为“0”。效果见图10-3。图10-3(4)保持矩形被选中,按Ctrl+C键进行复制,按Ctrl+V键进行粘贴。(5)选择菜单命令窗口变形或按Ctrl+T键打开变形面板,在变形面板中选择“旋转”“180度”(见图10-4)。图10-4(6)保持矩形被选中
4、,在属性面板中设置x为“0”,y为“0”。(7)按Ctrl+V键再次粘贴剪贴板中的矩形,在变形面板中设置“旋转”“90度”。(8)保持矩形被选中,在属性面板中设置x为“0”,y为“388”。此时效果如图10-5所示。图10-5(9)选择椭圆工具,设置笔触颜色为“无”,填充颜色为“径向渐变”(见图10-6),再按住Shift键在舞台上绘制正圆小球。图10-6(10)保持小球被选中,换用选择工具,在属性面板中设置宽和高均为“20”,x为“0”,y为“0”。(11)保持小球被选中,按Ctrl+C键进行复制,按Ctrl+V键进行粘贴,在属性面板中设置x为“380”,y为“0”。(12)按Ctrl+V键
5、再次粘贴剪贴板中的内容,在属性面板中设置x为“0”,y为“380”。(13)按Ctrl+V键再次粘贴剪贴板中的内容,在属性面板中设置x为“380”,y为“380”。效果如图10-7所示。图10-7(14)使用放大镜工具或时间轴上方的下拉列表,将视图放大到800%。(15)用选择工具选择小球外围的三角形部分,按Delete键删除。如不能准确选择,可尝试轻微移动小球,以得到可行的三角区域(见图10-8)。图10-8(16)使用放大镜工具的缩小功能或从主时间轴上方的下拉列表处设置图的显示比例为50%。(17)分别选择上、下、左、右四条边,按F8键转换为影片剪辑,分别命名为“Top_mc”、“Bott
6、om_mc”、“Left_mc”、“Right_mc”。(18)单击“border”图层对应小锁的黑点,锁定图层。3制作蛇头制作蛇头(1)新建一个层,命名为“snake”。(2)保持“snake”图层的第1帧被选中的状态,选择椭圆工具,在属性面板中设置笔触颜色为“无”,设置填充颜色为“红到黑的径向渐变”(见图10-9),按住Shift键在舞台上绘制正圆小球。图10-9(3)换选择工具,选中小球,在属性面板中将小球的宽、高均设置为“20”。(4)保持小球被选中的状态,按F8键,在弹出的转换为元件对话框中选择类型为“影片剪辑”,把名字设置为“head_mc”。(5)当前舞台上的实例是“head”,
7、我们在属性面板中,把它的实例名称也设置为“head”。4编写控制小球在舞台中移动的代码编写控制小球在舞台中移动的代码(1)新建层,命名为“action”。(2)选中“action”层的第1帧,按F9键调出动作面板,在其中输入以下代码:_root.onEnterFrame=function()if(Key.isDown(Key.LEFT)head._x-=10;if(Key.isDown(Key.RIGHT)head._x+=10;if(Key.isDown(Key.UP)head._y-=10;if(Key.isDown(Key.DOWN)head._y+=10;(3)按F9键,关闭动作面板。
8、(4)按Ctrl+Enter键运行动画,并查看效果。5限制小球的移动范围限制小球的移动范围选中“action”层的第1帧,按F9键打开动作面板,修改下列相关语句:if(Key.isDown(Key.LEFT)head._x-=10;if(head._x368 head._x=36;if(Key.isDown(Key.UP)head._y-=10;if(head._y368)head._y=368;6制作食物、蛇身制作食物、蛇身(1)在工具箱中找到矩形工具,按住矩形工具下方的小箭头不放,在弹出的选项中选择“多角星形工具”。(2)在属性面板中单击选项按钮,出现工具设置对话框。在工具设置对话框中设置
9、样式为“多边形”,边数为“5”,星形顶点大小为“0.5”,单击确定按钮,见图10-10。图10-10(3)在属性面板中设置笔触颜色为“无”,填充颜色为金黄色,并在舞台外绘制一金黄色六边形。(4)使用选择工具选中六边形,在属性面板中设置六边形的宽和高均为“20”。(5)保持六边形被选中的状态,按F8键将它转换为影片剪辑,并将此元件命名为“food_mc”。(6)在属性面板中将其在舞台上的实例名称也设置为“food”。(7)换用矩形工具,在属性面板中设置笔触颜色为“无”,填充颜色为红色,然后在舞台外绘制一个矩形。(8)换用选择工具,选中刚画好的矩形,在属性面板中设置宽、高均为“20”。(9)在保持
10、矩形被选中的状态下,按F8键将它转换为影片剪辑,并将它命名为“shen_mc”,将它在舞台上的实例名称也设置为“shen”。(10)按Ctrl+L键打开库面板,用鼠标右健单击“shen”元件,在弹出的菜单中选择链接,打开链接属性面板(见图10-11),在链接属性面板中,勾选“为ActionScript导出”,勾选时,“在第一帧导出”项也自动被勾选。在标识符一栏中,输入标识符“shen”。单击确定完成外部链接名的设置。图10-1110.2.2 重点与难点详解重点与难点详解本例中使用了Flash中的按键对象Key,这个对象不需要经过new来创建。在我们编写游戏时,可以用这个对象来判断键盘上是否按下
11、了某个键,如果是按下了某个特定键,Action Script可以做相应处理。Key按键对象可以用Key.isDown(按键代码)函数来判断某个按键是否被按下。Flash中,也设定了一些常用按键名用于此函数,省去了记住按键代码的麻烦。如本例中,Key.isDown(Key.LEFT)是判断左箭头键是否被按下,用Key.isDown(37)也可以起到相同的效果。很明显,前一种写法对编程人员来说要友好得多。表10-1和表10-2是Flash中设定的一些按键名及它们所对应的按键代码。表表10-1 按键名及其对应的代码按键名及其对应的代码表表10-2 常用按键对应的代码常用按键对应的代码 作业与练习作业
12、与练习根据上述步骤,制作初步游戏内容。挑战与提高挑战与提高试改变舞台大小、框的大小,保证仍可以自由移动小球并不超出框外。10.3 游游 戏戏 主主 体体10.3.1 游戏制作游戏制作1制作得分显示制作得分显示(1)新建一个层,并将此层命名为“text”。(2)选择文本工具,在属性面板中选择文本类型为“动态文本”,在舞台上的浅蓝色区域点击绘制一个动态文本框,将其对应的变量设置为“fenShu”。(3)换用选择工具,在属性面板中将文本框的字体设置为“宋体”,字体大小设置为“24点”,文本(填充)颜色为亮蓝色,对齐方式为“居中对齐”。(4)选择文本工具,在属性面板中选择文本类型为“静态文本”,文本(
13、填充)颜色为金黄色,在舞台上上述动态文本的上方单击,并输入“总分”。(5)使用选择工具,在两个文本框外拖动选框,选中两个文本框。(6)打开对齐面板,在对齐面板中选择“水平中齐”。(7)调整文本到恰当位置(见图10-12)。图10-122编写相关代码编写相关代码(1)初始化各变量。单击action层的第1帧以选中,按F9键调出动作面板,在面板中原Action Script代码前添加如下语句:fenshu=0;/分数n=0;/蛇身个数speed=7;/速度,越小越快i=1;/第几步dx=10;/x方向的移动距离dy=0;/y方向的移动距离(2)在上一步所编写语句的下方,编写随机放置食物的函数并调用
14、此函数一次:function weizhi()food._x=random(366)+12;food._y=random(366)+12;weizhi();(3)键盘指挥蛇走动的方向,蛇自动走动,吃了食物后,身体长长一段。具体代码如下:_root.onEnterFrame=function()_global.shenti=eval(shen+n);shenti.onEnterFrame=function()var qianyi=_rootshen+(Number(this._name.slice(4)-1);/取得前一个身体的位置 if(i=speed)genx=qianyi._x;geny=
15、qianyi._y;this._x=genx;this._y=geny shen1._x=suix;/第一个身体取得蛇头的位置 shen1._y=suiy;i+=1;if(i=speed)suix=head._x;suiy=head._y;if(ispeed)/改变蛇头的位置 i=1;head._x+=dx;head._y+=dy;if(Key.isDown(Key.LEFT)/判断按键,改变蛇头方向 if(dx=20)dx=20;else dx=-20;dy=0;else if(Key.isDown(Key.RIGHT)if(dx=-20)dx=-20;else dx=20;dy=0;els
16、e if(Key.isDown(Key.UP)if(dy=20)dy=20;else dy=-20;dx=0;else if(Key.isDown(Key.DOWN)if(dy=-20)dy=-20;else dy=20;dx=0;if(head.hitTest(food)/碰撞检测 weizhi();fenshu+=10;n+=1;shen.duplicateMovieClip(shen+n,n);10.3.2 重点与难点详解重点与难点详解“_root.onEnterFrame”语句我们已经在前几章中接触过了,它是指每个帧的时间单位执行一次其中的语句。在本例中,每个时间单位所执行的语句是比较
17、复杂的,下面逐一进行说明。首先是“_global.shenti=eval(shen+n);”,在这个语句中,我们设置了一个全局变量shenti,让它的值等于当前第n段身体。同时,使用了eval()函数,这个函数的作用是按括号里的名称访问变量、属性、对象或影片剪辑。如果括号里的是变量名或属性名,则返回变量或属性的值;如果括号里的是对象名或影片剪辑名,则返回指向它的引用;如果无法找到名称所指的元素,则返回 undefined。hitTest()方法的调用格式是:被检测影片剪辑实例名.hitTest(目标影片剪辑实例名)。它的作用是检测被检测影片剪辑是否碰上了目标影片剪辑。其实,用food.hit
18、Test(head)也是可以进行检测的,但是,由于我们并不打算再编写food的onEnterFrame事件,因而没有onEnterFrame事件,语句只能执行一次,起不了不断判断蛇头是否与食物碰撞的作用,在此不作这样的调用。作业与练习作业与练习按本例步骤,完成本例的制作。挑战与提高挑战与提高1是否能够让小蛇的速度随着分数的增加而逐渐加快?2是否能让小蛇不超过边框,且一旦接触边框后即死亡?提示与解答提示与解答1在上述语法详解中已经看到,小蛇的速度是由speed变量控制的。现在speed变量是恒定不变的。我们可以在上述函数中增加一段判断,当总分超过一个数值的时候,speed减1,再超过更大的一个数
19、值的时候,speed再减1。由于speed指的是帧数,当speed减到1的时候,就不能再快了。现在,我们的小蛇最多可以有7挡速度。如果我们想有更多速度挡,单纯增加speed值的话,那么刚开始的速度有可能会太慢而无法忍受。大家能否想到好的解决办法呢?2至于让小蛇不超过边框,一旦接触边框后死亡,思路是:把四个边框设为影片剪辑,然后做碰撞检测,如果碰上了话,小蛇就死亡。具体的实现将在下一节中讨论。10.4 完完 善善 游游 戏戏10.4.1 游戏制作游戏制作1确定边界名称确定边界名称(1)打开上节完成的Flash源文件。(2)点击“border”层对应的小锁,以解开本层的锁定,使本层成为可编辑的状态
20、。(3)使用选择工具分别选择四个边界元件,在属性面板中将它们分别命名为“rightborder”、“leftborder”、“topborder”、“bottomborder”。(4)点击border层对应小锁的黑点,重新锁定本层。2编写相关代码编写相关代码(1)单击action层的第1帧以选中,按F9键调出动作面板,在上一节碰撞检测的语句后加入下列对边框的碰撞检测语句:if(head.hitTest(rightborder)dead();if(head.hitTest(leftborder)dead();if(head.hitTest(topborder)dead();if(head.hit
21、Test(bottomborder)dead();function dead()trace(Im dead);(2)按 Ctrl+Enter 键运行动画以查看效果。(3)在动作面板中,改写碰撞后执行的函数 dead():function dead()delete _root.onEnterFrame;unloadMovie(food);unloadMovie(head);unloadMovie(shen);_root.onEnterFrame=function()m+=1;unloadMovie(shen+m);(4)在此帧Action Script开始处,初始化变量的语句段后,增加一句“m=
22、0;”,对m进行初始化。(5)按Ctrl+Enter键运行动画以查看效果。(6)通过上面的步骤,贪吃蛇游戏已经基本完成。但根据贪吃蛇游戏规则,如果蛇头碰到自己的身体,也是应该死亡。所以,我们再次调出动作面板,输入以下语句检测蛇头和蛇身是否碰撞:for(t=3;tn;t+)if(head.hitTest(eval(shen+t)dead();10.4.2 重点与难点详解重点与难点详解trace语句的格式是:trace(表达式)。它的作用是当swf文件在Flash中测试时,可以将表达式的值在输出面板中输出。这个语句是一个测试用的语句。trace语句括号中的表达式,可以是一个字符串,用来显示需要的提
23、示信息;它也可以是一个变量,如我们可以在最后一段的for语句中使用trace(t)来显示t变化的情况;它还可以是一个复杂的表达式,让我们可以看出表达式的取值情况,如“trace(head.hitTest(eval(“shen”+i)”。trace语句是一个特殊的语句,只用于测试过程而不会在最终的动画成品中出现。所以,可以在发布动画的时候,选择“省略trace动作”来把这些语句从最终的动画中省去,见图10-13。图10-13 作业与练习作业与练习1按本例步骤完成贪吃蛇游戏。2试在运行过程中,查看本例中不同变量的取值变化情况。挑战与提高挑战与提高1在小蛇的运动过程中,有时会出现需要急转弯的情况,如
24、图10-14所示,这时,小蛇会死亡。请问这是为什么?如何修改动画以避免这种情况的发生?2是否可以设置重玩按钮,当小蛇死亡后可以重新开始?3是否可以让小蛇有三条命?图10-14 提示与解答提示与解答1会出现这样的情况,是因为蛇头和身体是一样宽的,这样,在急转弯的时候,蛇头和身体恰好碰到,这样,按我们的条件,小蛇就死掉了。有一个简单的解决办法,就是把蛇头的宽度改小两个像素,高度也改小两个像素,蛇头影片剪辑中,小球的位置设置x为1,y也为1,即可避免这个问题。但这样一来,后面生成的蛇的身体就有一点点重叠,而蛇头与身体有一点点距离。如果更仔细的话,就要修改蛇头的每步步长和身体的步长,这个问题应该如何解决呢?2设置重玩按钮时,可以在现在的基础上增加一帧,在小蛇死亡后,除清除相关的影片剪辑外,再跳转到下一帧;在下一帧放置重玩按钮,且重玩按钮添加Action Script语句,以单击该按钮后回到第一帧中。3要让小蛇有三条命,我们可增加一个变量来记录小蛇剩余的生命数,并在每次调用死亡函数时,判断小蛇是否还有生命数,如果已经没有生命数了,游戏结束;如果还有生命数,则不要清除蛇头、蛇身、食物,也不要删除onEnterFrame函数,而是把蛇头放到初始的位置,并把各种变量清零。大家不妨试试。