企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
游戏是移动应用中最令人兴奋的部分,无论是玩游戏,还是做游戏。最近红极一时“愤怒的小鸟”,根据开发者Rovio公司称,第一年下载量达50万次,同时每天运行的人时数超过一百万小时。(甚至有人说要把它拍成故事片!)我们可无法保证电影的成功,但可以让您用App Inventor创建自己的游戏“瓢虫快跑”,里面的瓢虫要吃蚜虫,同时要避免被青蛙吃掉。 ![{%}](https://box.kancloud.cn/2015-08-31_55e3d82d67cd6.png) ## **应用描述** 如图5-1所示的“瓢虫快跑”应用,用户可以: * 通过倾斜设备来控制瓢虫移动; * 查看屏幕上的能量指示条,能量会随时间减少,并引起瓢虫的饥饿; * 让瓢虫追逐并吃掉蚜虫来获得能量,抵御饥饿; * 帮助瓢虫躲避青蛙,因为青蛙吃瓢虫。 ![{%}](https://box.kancloud.cn/2015-08-31_55e3d832d306d.png) **图 5-1 瓢虫快跑游戏手机截屏** ## **学习要点** 在开始探索本章之前,我们假设你已经完成了第3章MoleMash的学习,并熟悉了过程创建、随机数生成、Ifelse块以及ImageSprite、Canvas、Sound和Clock组件。 本章在复习MoleMash以及前几章内容的基础上,主要介绍以下内容: * 使用多个ImageSprite组件,并检测它们之间的碰撞; * 使用OrientationSensor(方向传感器)组件检测设备的倾斜,并用它来控制ImageSprite; * 改变ImageSprite的显示图片; * 在Canvas组件上画线; * 用Clock组件控制多个事件; * 用变量来记录数值(瓢虫的能量水平); * 创建和使用带参数的过程; * 使用and块。 ## **设计组件** 在应用中,使用一个Canvas组件作为三个ImageSprite组件的活动场地,三个ImageSprite组件分别代表瓢虫、蚜虫和青蛙,此外,还要为青蛙配一个声音组件。OrientationSensor(方向传感器)通过测量设备的倾斜来移动瓢虫,Clock组件用来改变蚜虫的运动方向。另有一个显示瓢虫能量水平的Canvas组件;一个重新启动按钮,当瓢虫饿死或被吃掉时,用来重新启动游戏。表5-1提供了本应用中使用的全部组件列表。 **表5-1 瓢虫快跑游戏中的所有组件** | 组件类型 | 面板中分组 | 命名 | 作用 | | --- | --- | --- | --- | | Canvas | Drawing and Amination | FieldCanvas | 运动场地 | | ImageSprite | Drawing and Amination | Ladybug | 用户控制的角色 | | OrientationSensor | Sensor | OrientationSensor1 | 测试手机的倾斜,控制瓢虫移动 | | Clock | User Interface | Clock1 | 决定何时改变Imagesprite的方向 | | ImageSprite | Drawing and Amination | Aphid | 蚜虫:瓢虫的捕食对象 | | ImageSprite | Drawing and Amination | Frog | 青蛙:瓢虫的捕食者 | | Canvas | Drawing and Amination | EnergyCanvas | 显示瓢虫的能量水平 | | Button | User Interface | RestartButton | 重启游戏 | | Sound | Media | Sound1 | 青蛙吃瓢虫时发出的声音 | ## **准备开始** 下载瓢虫、蚜虫、死瓢虫及青蛙的图像,此外还有青蛙的声音文件。 登陆App Inventor网站,建一个名为“LadybugChase”新项目,屏幕标题设置为“瓢虫快跑”。打开块编辑器并连接到测试设备,将下载的图片及声音文件上载(Upload file)到媒体面板。 如果使用设备而不是模拟器,你需要禁用“屏幕自动旋转”功能,否则当设备旋转时,会改变设备的显示方向。在大多数设备上,可以点击设置->显示,然后取消选中的“屏幕自动旋转”复选框即可。 ## **活动的瓢虫** 在这个“第一人称”的游戏中,瓢虫代表玩家,玩家通过倾斜手机来控制瓢虫的运动。与MoleMash不同,这里玩家被带入游戏,而不是在设备以外用手触碰。 ### **添加组件** 在前几章,我们一次性地创建了所有的组件,但这不是开发人员的习惯做法。相反,通常每次只创建一部分组件,编写相应的程序,并进行测试,然后在进入到下一部分。在本节中,我们先来创建瓢虫并控制它的运动。 * 在组件设计器中创建一个Canvas,命名为FieldCanvas,并设置其宽度为“Fill parent”,高度为300像素; * 在FieldCanvas上放置一个ImageSprite,重命为Ladybug,并设置其Picture属性为活的瓢虫图片。不必在意它的x、y属性,这取决于ImageSprite被放在画布上的位置。 也许你已经注意到,ImageSprites还有Interval、Heading以及speed属性,而这些都是在本程序中要用到的: * Interval属性:在本游戏中可以设置为10(毫秒),来设定ImageSprite自身的移动频率(而不是像MoleMash中那样,运动被MoveTo过程所控制); * Heading属性:指示ImageSprite将要移动的方向。例如:0表示向右,90表示向上,180表示向左,等等。现在就让它取默认值——向右,我们将在块编辑器中改变它; * Speed属性:指定ImageSprite在每个时间间隔内移动的距离(单位为像素)。我们将在块编辑器中设置Speed属性。 瓢虫的运动由OrientationSensor通过检测设备的倾斜程度来进行控制;Clock组件用来每隔10毫秒(每秒100次)检测一次设备的方向,并相应地改变瓢虫的Heading(方向)属性 。我们将在块编辑器中做如下设置: 1\. 添加OrientationSensor组件,它将出现在“不可见组件”区域; 2\. 添加Clock组件,它也将出现在“不可见组件”区域,并设置其TimerInterval属性为10毫秒。对照图5-2检查添加的组件。 ![{%}](https://box.kancloud.cn/2015-08-31_55e3d83359946.png) **图 5-2 在组件设计器中为动画瓢虫设置用户界面** ### **添加行为** 切换到块编辑器,创建名为UpdateLadybug的过程(procedure)及Clock1.Timer块,如图5-3所示。尝试不使用抽屉,直接输入块的名字(如“when Clock1.Timer”)来生成块。(请注意,对数字100的乘法操作使用的是星号(*),但图中看不到。)虽然可以单击右键选择添加注释,但这不是必须的。 ![{%}](https://box.kancloud.cn/2015-08-31_55e3d8347f8a9.png) **图 5-3 每隔10毫秒改变一次瓢虫的方向及速度** 在UpdateLadybug过程里用到了两个OrientationSensor最有用的属性: * Angle(角度):表示设备倾斜的方向; * Magnitude(幅度):表示设备的倾斜程度,范围从0 (不倾斜)至1(最大倾斜)。 Magnitude乘以100是告诉瓢虫,在每个时间间隔(TimerInterval)内,在某个特定的方向,移动的距离在0到100像素之间。时间间隔为之前在组件设计器中设定的10毫秒。 虽然在连接设备上可以测试瓢虫的移动,但与打包下载到设备上的运行效果相比,瓢虫的速度要么太慢,要么太快。对于安装运行的应用,如果太慢,可以增加速度;相反,则减小速度。 ## **显示能量水平** 在第二个Canvas组件上用一个红色线条来显示瓢虫的能量水平。线条高度为1个像素,宽度为瓢虫的能量值,取值范围从200(健康)到0(死)。 ### **添加组件** 在组件设计器中,在FieldCanvas下方创建一个新的Canvas组件,命名为EnergyCanvas;设置Width属性为“Fill parent”,Height属性为1个像素。 ### **创建变量:Energy** 在块编辑器中,创建一个初始值为200的变量来记录瓢虫的能量水平。(还记得吧,在第2章PaintPot中,第一次使用变量dotSize)以下是具体步骤: 1\. 在块编辑器中,拖出一个initialize global name to块,将name改为energy; 2\. 如果energy块的右侧插槽内有其他块,删掉它:选中并按Delete键或直接拖到垃圾桶; 3\. 创建一个数组块200(直接输入数字200或拖动Math抽屉中的0块),然后插入initialize global energy to块,如图5-4所示。 ![{%}](https://box.kancloud.cn/2015-08-31_55e3d83a666b2.png) **图 5-4 将变量energy初始化为200** 图5-5中显示了当鼠标悬浮在初始化变量块的“energy”文本上时,呼出了全局变量energy的“get”及“set”块; ![{%}](https://box.kancloud.cn/2015-08-31_55e3d8404c194.png) **图 5-5 从初始化变量块中获得set及get块** ### **画出能量条** 我们要在变量energy与红色线条之间建立通信,使线条长度(像素)与能量值相等。为此创建如下两个类似的组块: 1\. 在EnergyCanvas上从(0, 0)点到(energy, 0)点画一条红线,以显示当前的能量水平; 2\. 在EnergyCanvas上从(0, 0)点到(EnergyCanvas.Width, 0)点画一条白线,在画新能量水平线之前,清除当前的能量水平线。(记得前面设置EnergyCanvas.Width为“Fill parent”。) 然而,最好能创建一个过程,能用任何颜色在EnergyCanvas上画任意长度的线。为此,需要定义两个参数:length(长度)和color(颜色),当程序被调用时,我们只需要指定参数值,就像在MoleMash一章中调用random integer内置过程一样。下面是创建DrawEnergyLine过程的步骤,如图5-6所示。 1\. 进入Procedures抽屉,拖出一个to procedure块; 2\. 点击过程名(可能是“procedure” ),改为“DrawEnergyLine”; 3\. 点击过程块左上角的蓝色方块,呼出两个块:input及input x; 4\. 将input x块插入到input块内,将x修改为color; 5\. 重复步骤4:插入第二块input x并命名为“length”; 6\. 按照图5-6所示,为该过程添加的其余的块:将鼠标悬停在to DrawEnergyLine块的参数color及length文本上,获得get color及get length块;或者从Variables抽屉中直接拖出get块,插入到to DrawEnergyLine内部的块中,点击下拉菜单选择color或length。 ![{%}](https://box.kancloud.cn/2015-08-31_55e3d8409f0fd.png) **图 5-5a 为DrawEnergyLine过程添加输入(参数)** ![{%}](https://box.kancloud.cn/2015-08-31_55e3d8415180f.png) **图 5-6 定义过程DrawEnergyLine** 现在,你已经掌握了创建过程的窍门,让我们再写一个DisplayEnergy的过程,两次调用DrawEnergyLine过程:第一次用来擦除旧线(覆盖整个EnergyCanvas的白线),第二次用来显示新的能量线,如图5-7所示。 ![{%}](https://box.kancloud.cn/2015-08-31_55e3d841afcfa.png) **图 5-7 定义过程DisplayEnergy** DisplayEnergy过程由以下四行命令组成: 1\. 设定画笔颜色为白色; 2\. 画一条贯穿EnergyCanvas的横线(1个像素高); 3\. 设定画笔颜色为红色; 4\. 画一条长度等于energy值的线。 > ![](https://box.kancloud.cn/2015-08-31_55e3d842276ee.png) 提示:将若干行代码规整到一个过程中,通过调用这个过程来取代逐行地执行这些代码,这个过程被称作重构,这种强大的技术使得程序更易于维护,也更可靠。在这种情况下,如果我们想改变能量线的高度或位置,我们只需对DrawEnergyLine过程做一次修改,而不必分两次来完成这一修改。 ### **饥饿而死** 不同于前几章的应用,本游戏设定了结束环节:如果瓢虫吃不到足够的蚜虫,或者被青蛙吃掉,则游戏结束。此时我们希望瓢虫不再移动(设置Ladybug.Enabled为false),并将活瓢虫图片换成死瓢虫(将Ladybug.Picture设置为已上传的图片文件名)。GameOver过程的创建如图5-8所示。 ![{%}](https://box.kancloud.cn/2015-08-31_55e3d84289466.png) **图 5-8 定义GameOver过程** 再按图5-9所示向UpdateLadybug(由Clock.Timer每10毫秒调用一次)添加红框内的代码: * 减少瓢虫的能量(energy = energy - 1); * 显示新的能量水平(call DisplayEnergy); * 如果energy值为0则游戏结束。 > ![](https://box.kancloud.cn/2015-08-31_55e3d842dc357.png) 测试:你可以在设备上测试这段代码,并验证能量水平随时间的减少,并最终导致瓢虫死亡。重启应用可以点击“Reset Connection->AI Companion”。 ![{%}](https://box.kancloud.cn/2015-08-31_55e3d84338d36.png) **图 5-9 UpdateLadybug过程的第二个版本** ## **添加蚜虫** 下面来添加蚜虫,即让蚜虫在FieldCanvas上浮动。如果瓢虫撞上蚜虫(视同“吃”掉它),则瓢虫的能量水平升高,而蚜虫消失,且稍后会再次出现。(在用户看来,这完全是另一只蚜虫,但实际上是同一个ImageSprite组件。) ### **添加一个ImageSprite** 添加蚜虫首先要回到组件设计器,创建另一个ImageSprite,要确保它不落在瓢虫上,命名为Aphid,其属性设置如下: 1\. Picture属性:设置为已上传的蚜虫图像文件; 2\. Interval属性:设置为10,即:像瓢虫一样,每10毫秒移动一次; 3\. Speed属性:设置为2,因此蚜虫移动不会太快,以便让瓢虫能抓住它。 不必在意它的x、y属性(只要不是在瓢虫上)或title属性,这些可以在块编辑器中设置。 ### **控制蚜虫** 实验发现,蚜虫每隔50毫秒(Clock1跳动5次)改变一次方向的效果最好。可以通过创建第二个Clock组件,并设定其TimerInterval属性为50毫秒来实现这一效果。但是,我们希望能够尝试不同的技术:使用random fraction(随机分数)块,每次调用,它都将返回一个≥0但<1的随机数。创建UpdateAphid过程,并用Clock1.Timer来调用它,如图5-10所示。 ![{%}](https://box.kancloud.cn/2015-08-31_55e3d843ce221.png) **图 5-10 添加UpdateAphid过程** #### **块的作用** 定时器每次跳动(每秒100次)都将调用UpdateLadybug及UpdateAphid过程。UpdateAphid过程首先生成一个介于0到1之间的随机数,例如0.15,如果该数<0.20(在20%的时间里),蚜虫将改变方向,改变的角度为0到360之间的随机数;如果该数≥0.20(在其余80%的时间里),蚜虫方向保持不变。 ### **瓢虫吃掉蚜虫** 下一步,当他们碰撞时,让瓢虫“吃掉”蚜虫。幸运的是,App Inventor提供了ImageSprite组件之间的碰撞检测。问题是:当瓢虫与蚜虫碰撞时,会发生哪些事情?在继续阅读之前,请你停下来想想这个问题。 为了处理瓢虫与蚜虫的碰撞,创建EatAphid过程,其具体步骤如下: * 瓢虫的能量水平上升50,来模拟享受美食; * 让蚜虫消失(设置其Visible属性为false); * 让蚜虫停止移动(设置其Enabled属性为false); * 让蚜虫移动到屏幕上任意位置(这与MoleMash中移动地鼠遵循了相同的编码方式)。 请对照图5-11检查您的块。如果你还能想到发生其他事情,比如音效,可以自行添加。 ![{%}](https://box.kancloud.cn/2015-08-31_55e3d84447eb2.png) **图 5-11 创建EatAphid过程** #### **块的作用** 每次调用EatAphid,变量energy增加50,缓解了瓢虫的饥饿。然后,蚜虫的Visible及Enabled属性都被设置为false,看上去像是消失了。最后,产生随机的x、y坐标,并调用Aphid.MoveTo,这样,蚜虫会在一个新位置再次出现(否则,它一出现便会被立即吃掉)。 ### **瓢虫与蚜虫之间的碰撞检测** 图5-12显示了在瓢虫与蚜虫之间做碰撞检测的代码。 ![{%}](https://box.kancloud.cn/2015-08-31_55e3d844aa265.png) **图 5-12 检测并处理瓢虫与蚜虫之间的碰撞** #### **块的作用** 当瓢虫与另一个ImageSprite碰撞时,将调用Ladybug.CollidedWith,参数“other”指向任何与瓢虫发生相撞的ImageSprite。此时,只有蚜虫可以碰撞,但稍后会有青蛙加入进来。我们采用防御性编程方式,即在调用EatAphid之前,要确认碰撞的对象就是蚜虫;此外还要确认蚜虫可见,否则,蚜虫在被吃掉之后而重新出现之前,还会与瓢虫再次碰撞。如果缺少这项确认,隐形的蚜虫会被再次吃掉,并引起能量水平的再次增加,这会让用户感到费解。 > ![](https://box.kancloud.cn/2015-08-31_55e3d842276ee.png) 提示:防御性编程是一种避免错误的编程方式,当程序被修改时,仍然可以正常工作。在图5-12中,对other=Aphid的检查并不是绝对必要的,因为此时瓢虫可碰撞的唯一对象就是蚜虫,但检查可以防止后续程序的错误:当添加另一个ImageSprite(青蛙)时,如果忘记了修改Ladybug.CollidedWith,程序就会出错。通常来说,程序员修复bug的时间要多余写新代码的时间,所以多花一点时间尝试防御型编程是非常值得的。 ### **蚜虫的回归** 最终蚜虫要重新出现,按图5-13所示修改UpdateAphid:仅当蚜虫可见时,令其改变方向(改变一个不可见的蚜虫岂不是浪费时间。);若蚜虫不可见(如刚刚被吃掉),将有1/20(5%)的机会重新出现,或者说会被再吃掉。 ![{%}](https://box.kancloud.cn/2015-08-31_55e3d854435a4.png) **图 5-13 修改UpdateAphid使隐形蚜虫起死回生** #### **块的功能** UpdateAphid变得有些复杂,让我们仔细推敲一下: * 如果蚜虫可见(这应该是常态,除非刚刚被吃掉),UpdateAphid的行为没有变化,即有20%的几率改变方向; * 如果蚜虫不可见(刚被吃掉),则执行“else”部分。首先生成一个随机分数,如果它<0.05(在5%的时间里),蚜虫再次变得可见并且可用,即,有资格被再次吃掉。 因为Clock1.Timer每隔10毫秒调用一次UpdateAphid,而当蚜虫隐形后,只有1/20(5%)的机会恢复可见,因此蚜虫平均重现的时间是200毫秒(1/5秒)。 ## **添加重新启动按钮** 在测试蚜虫被吃的新功能时,你可能已经注意到,游戏的确需要一个重新启动按钮。(在创建应用过程中,将应用分解成小的功能模块,完成一块就测试一块,这种开发模式大有裨益。在测试过程中,经常会发现一些被忽略了事情,一边做一边测一边改,比起整个应用完成之后再回来做修改,要容易得多。)在组件设计器中,将Button组件添加在EnergyCanvas下方,改名为“ResetButton”,并设置其Text属性为“重新启动”。 在块编辑器中,创建当RestartButton被点击时的代码,如图5-14所示: 1\. 能量水平设置回200; 2\. 重新使蚜虫可见并且可用; 3\. 重新使瓢虫可用,并将其图片改为活的瓢虫(除非你想要僵尸瓢虫!)。 ![{%}](https://box.kancloud.cn/2015-08-31_55e3d854d4041.png) **图 5-14 按下“重新启动”按钮让游戏重新开始** ## **添加青蛙** 到目前为止,让瓢虫活着并不难,因此我们需要一个捕食者。就是说我们要添加一个奔向瓢虫的青蛙,如果发生碰撞,瓢虫被吃掉了,游戏结束。 ### **让青蛙追捕瓢虫** 首先回到组件设计器,在FieldCanvas上添加第三个ImageSprite组件Frog,设置其Picture属性为相应的图片,interval属性为10,Speed为1,让它的移动速度慢于其他生物。 图5-15显示了Clock1.Timer中调用了新创建的过程。 ![{%}](https://box.kancloud.cn/2015-08-31_55e3d8555b470.png) **图 5-15 让青蛙向着瓢虫移动** #### **块的功能** 现在你应该可以熟练地使用随机分数来控制事件的发生几率了,这里,青蛙有10%的机会直接直奔向瓢虫。这里用到了三角函数,但别害怕,你不必明白其中的道理!App Inventor提供了大量的数学函数,也包括三角函数。本例中使用的ATAN2(反正切)块,返回值是一个角度,该角度由一组给定的x、y值相对应。(如果你熟悉三角函数,会发现求解ATAN2时所用的y值与你所期望的y值符号正好相反,即y的减法顺序是反的,这是因为在Android的画布上,向下是y坐标的增加方向,这与标准的x-y坐标系正相反。) ### **让青蛙吃掉瓢虫** 现在需要修改碰撞代码,如果瓢虫与青蛙碰撞,能量水平以及能量线都将变为0,且游戏结束,如图5-16所示。 ![{%}](https://box.kancloud.cn/2015-08-31_55e3d855e9297.png) **图 5-16 让青蛙吃掉瓢虫** #### **块的功能** 在第一个if(瓢虫与蚜虫的碰撞检测)块的基础上,添加了第二个if块,来检测瓢虫与青蛙的碰撞。如果瓢虫和青蛙碰撞,将发生三件事情: 1\. 变量energy降为0,瓢虫失去生命力; 2\. DisplayEnergy被调用,以清除此前的能量线(并绘制新的空白线); 3\. 调用前面写过的GameOver过程,以便让瓢虫停止移动,并将图片改为死瓢虫。 ### **瓢虫回归** RestartButton.Click已经用程序将死瓢虫图片替换成了活的图片。现在,需要添加代码将瓢虫移动到任意位置。(想想看,在新游戏开始时,如果没有移动瓢虫,会发生什么?瓢虫与青蛙的位置关系如何?)图5-17显示了游戏重新启动时用来移动瓢虫的块。 ![{%}](https://box.kancloud.cn/2015-08-31_55e3d85657219.png) **图 5-17 ResetButton.Click的最终版本** #### **块的功能** 两个版本的RestartButton.Click之间,唯一的差别就是Ladybug.MoveTo块及其参数。调用了两次内置的随机整数函数,分别用于生成合法的x、y坐标。虽然没有任何设置来防止瓢虫与蚜虫、瓢虫与青蛙的位置上的重叠,但几率起到了决定性作用。 > ![](https://box.kancloud.cn/2015-08-31_55e3d842dc357.png) 测试:重新启动游戏,并确信瓢虫出现在一个新的任意位置。 ## **添加音效** 测试游戏时,你可能注意到:当蚜虫或瓢虫被吃掉时,缺少良好的反馈。要添加音效及触觉反馈,请执行以下操作: 1\. 在组件设计器中添加一个Sound组件。设置其Source属性为已上传的声音文件; 2\. 进入块编辑器,进行如下操作: * 在EatAphid过程中添加Sound1.Vibrate块,参数为100毫秒,以便在蚜虫被吃掉时,设备产生振动; * 在Ladybug.CollidedWith中调Sound1.Play,位置在调用GameOver之前,以便当青蛙吃掉瓢虫时发出叫声。 ## **改进** 下面这些想法目的是改进游戏,或者让游戏更个性化: * 目前,当游戏结束时,青蛙和蚜虫还在移动,这与其Enabled属性有关:在GameOver中将其设置为false,并在RestartButton.Click中重新设置为true; * 设置并显示一个分数,来表示瓢虫的存活时间。你可以用Label来显示一个数值,该数值在Clock1.Timer内不断递增; * 将EnergyCanvas的Height属性增加为2,以便使能量条更加明显,并在DrawEnergyLine内画两条线,一个在另一个之上。(使用一个过程,而不是复制代码先擦除再重绘能量线,这样做的另一个好处是:如果你需要修改线的粗细、颜色或位置时,只需要修改一处的代码。) * 添加背景图和更多音效来渲染气氛,比如用真声或预警声来提示瓢虫能量水平的降低; * 让游戏随时间推移而变得越来越难,如增加青蛙的速度,或降低Interval属性值; * 从技术上来说,被青蛙吃掉的瓢虫应该消失。改变游戏规则:如果瓢虫被吃,则隐形;如果是饿死,则显示死瓢虫图; * 将瓢虫、蚜虫和青蛙的图片换成更适合你个人口味的图片,如霍比特人、半兽人以及邪恶的巫师;或者是反叛星际战斗机、能源舱及帝国战机。 ## **小结** 已经有两个游戏被你收入囊中(假设你学习了MoleMash),现在你该知道如何创建自己的游戏了,这是许多新程序员或有志者的目标!具体来说,您学习了: * 可以创建多个ImageSprite组件(瓢虫,蚜虫和青蛙),并在它们之间做碰撞检测; * 用OrientationSensor可以检测设备的倾斜,而测得的值可用于控制sprite(或你能想到的任何其他对象)的移动; * 一个Clock组件可以控制多个发生频率相同(改变瓢虫和青蛙的方向),或通过使用random fraction块来控制频率不同的事件。例如,如果你想在一个周期中,有大约1/4(25%)的时间里会发生某事件,只要将它放在if块中,并设定条件为random fraction的结果<0.25即可; * 一个应用中可以使用多个Canvas组件,我们的例子中有两个,一个用于游戏场地,另一个用于变量的图形化显示(而不是用Label显示); * 用户自定义过程可以使用参数(如在DrawEnergyLine 中使用的“color”及“length”)来控制其行为,这极大地扩展了过程抽象的能力。 另一个游戏中常用的组件是Ball,与ImageSprite唯一不同的是,它的外观是一个被填充的圆形,而不是一张任意的图片。 ### **资源下载** [frog.png](http://www.17coding.net/download/5/frog.png) [ladybug.png](http://www.17coding.net/download/5/ladybug.png) [deadladybug.png](http://www.17coding.net/download/5/deadladybug.png) [aphid.png](http://www.17coding.net/download/5/aphid.png) [frog.wav](http://www.17coding.net/download/5/frog.wav) ### **英汉对照** orientation: 方向 field: 场地 ladybug: 瓢虫 aphid: 蚜虫 frog: 青蛙 energy: 能量 restart: 重新开始 chase: 追逐,奔跑 upload: 上载,上传 file: 文件 interval: 间隔 heading: 前进方向 speed: 速度 timer: 计时器 updat: 更新 angle: 角度 magnitude: 幅度 delete: 删除 procedure: 过程 input: 输入 display: 显示 enable: 使有效 reset: 重置 visible: 可见的 eat: 吃 collide: 碰撞 with: 与... else: 否则 fraction: 分数