当前位置:文档之家› 十一、程序设计

十一、程序设计

十一、程序设计
十一、程序设计

十一、程序设计

1.故事板

在Alice中程序设计是将场景中的对象按剧情的要求动作起来,因此进行程序设计的第一步是熟悉并描述剧情,也就是对一个故事或一个游戏的描述,需要什么背景,有些什么角色或对象,剧情有哪些情节,在每个情节中这些对象有什么动作和行为等等都要描述清楚。第二步是要使用一种工具去描述剧情,在Alice中是釆用故事板(storyboard)这种工具来描述剧情,它为每一个情节设计了所需要的动作序列。在迪斯尼(Disney)等大的动画公司都是将大故事分成很多小故事,然后对毎个小故事来用故事板去描述一些场景和情节,设计对象的动作或行为。第三步是根据故事板来编写代码,以实现故事板所要求的情节动作,这也是通常所说的编程。最后一步是测试,看程序是否正常运行,是否达到原设计要求。故事板有图形式和文本式两种,动画师们爱用手绘图形来描述场景,附以文字说明对象动作,如描述雪地上有三个人,两人女雪人区在交谈,来了一个男雪人,向一女雪人眨眼,可用下面手绘图形来描述场景,灰色波纹表示雪地,远处有山作背景等。

而文本式故事板是一个用文字表达的任务列表,它概括故事的各个场景及完成某一任务的一些动作,同时还列出了写代码时应遵循的结构,在程序设计中一个程序的结构是指程序执行的顺序,一般是三种结构:顺序结构、选择结构和循环结构,程序中所有的代码都是按这三种结构组织的,文本式故事板不仅指出动作而且给出结构,这样根据它来写编码更为方便。下面以一实例来介绍用文本式故事板描述剧情,并根据它来写编码。

实例34:男雪人与女雪人

剧情是:在雪之歌音乐背景下,在冬天的雪地里有两个女雪人正在交谈,而旁边的男雪人试图吸引其中一个女雪人的注意,朝她叫了一声”Ahem”并向她眨了眨眼,女雪人转过身来脸红地看了看男雪人,她对见他没有兴趣,冷眼看了看他转身继续和如她的朋友交谈,他只好转身离她而去。

在这个故事中有三个雪人,一个男的二个女的,冬天有雪的场景,在故事的情节中涉及雪人的动作有:男雪人试图引起女雪人的注意,叫了一声,眨了眨眼;女雪人转过身,脸红,冷眼看了看他转身;男雪人转身离开。因此可以把剧情看作四个动作序列:(1)男雪人通过呼叫以引起女雪人注意。(2) 女雪人转过身时男雪人向她眨了眨眼。(3)女雪人脸红,冷眼看了看他转身。(4) 男雪人转身离开。

可以想象这个故事有这样三个场景:

(1)初始场景,场景响起背景音乐,看到雪地上有三个雪人,其中男雪人想约见带红帽的女雪人

(2)场景2:男雪人向女雪人说”Ahem”

(1)女雪人转身,男雪人向女雪人眨眼

对这三个场景可以设计出一个文本故事板去描述它

完成的而后两个动作则要求同时完成。因此故事板是给出了完成某一任务的动作序列,并规定了程序的结构,本例是给出程序的顺序结构。显然,这块故事板还只是描述了故事的一部分,还需把后半部分的情节补充进去,由于前后联系紧密,将它放在同一块故事板上。

下面就要将故事板的描述转换成程序代码,在Alice中程序就是完成某一任务的命令(动作)序列,而对象的命令即为对象的方法(methods),每个对象都有内置的方法,这可从该对象的方法列表中找到,如果没有对应该动作的方法,就要建立新的方法去实现它。编码主要是指方法的编码,如果涉及到交互动作,则要进行事件编码。

在方法编码前,首先要建立剧情要求的场景,即选择snow为背景,在场景中加入三个雪人(二女一男),调整他们的位置如上面初始场景所示的图形。

方法编码是在World.my first method方法编辑区内编辑,按故事板上的顺序,第一步是要求后面二项动作是依序执行,Alice提供了两种顺序结构的命令Do in order及Do togather,因此只要将Do in order拖入到编辑区内。

第二步是要求snowman转向snowwoman去看她,因此要点击对象树上snowman,在methods 列表中找到方法turn to face,该方法能满足要求。

第三步是snowman要向snowwoman打招呼,在方法列表中找到say,可用此方法向snowwoman 说Ahew。

第四步要求后面两个动作同时执行,因此要将Do togather拖入到编辑区内,并放在Do in order 之内

第六步要求snowwomam要转头,点击对象树中snowwomam左边的+号,让snowwomam的组成部件也显示出来,点击其中的head,就能从其方法列表看到跟头部动作有关的命令,找到并拖turn to face至Do Nothing处,并选择snowman,

第七步要求snowman眨眼,它要左右眼都要眨,而且是与第六步同时进行。点击对象树上snowman左边+号,先拖leftEye move至编辑区,选择up并设置0.04 meter,再拖leftEye move 至编辑区,选择down并设置0.04 meter,类似地对rightEye也拖二条move命令,分别选择up 私down并设置0.04 meter

上下眨眼的距离是需要经过多次试验才得令0.04这个数据较为合适,这是一种试错法(trial-and- error),即不断地试验、纠错、再试验,最终可获得理想的结果。

至此可去测试所编代码的正确,没有必要一定等整个程序都完成了才测试。按Play后发现snowman的左右眼既不向上也不向下,因而也就不能眨眼,这就是程序中通常所说的bug,分析其原因是因为要求move up和move down要同时进行,实际上就等于不动,因此只要把move up和move down放在Do in order之下,让它们依次执行就可以了。

另外还要给出眨眼的持续时间,通常在Do togather下同时执行动作的时间应该是相同的,如果眨眼时间为1 second,那么up和down各占0.5 second,为此点击move命令后面的more,设置duration为0.5 second。

第八、九、十步是关于snowwomam的三个动作,首是脸红,要改变snowwomam的脸色,要用到snowwomam的属性,先拖入Do togather到编辑区,使八九步同时进行。先点击对象树上snowwomam左边的+号,对出现的扩展项点击head,在属性列表中拖color至Do togather下面并选择red

第九步是转回头面向snowwomam2,因此要它snowwomam.head的方法列表中将turn to face拖入其后,并选择snowwomam2。第十步是snowwomam脸色变回白色,显然它不能放在Do togather之下,而第十步是snowman失望而离开,这里用他的头转向前且整个人转向右来表示。

程序编完后应为程序的某些部分写上注解,如说明要完成什么动作等,便于程序阅读者理解。

2.一些实例

实例36 青蛙跳游戏。水池表上飘浮着五个睡莲叶子,它们在水靣上不规则移动,要求青蛙从一个睡莲叶子跳到另一个睡莲叶子直至对岸,如果青蛙掉入水中游戏结朿,如果青蛙到达对岸的红圈则嬴。

(1).先从https://www.doczj.com/doc/b29352313.html,/~veerasam/alice_old/中下载文件名frog_game_setup.a2w,并存入能找到的文件系统中。打开Alice 2.3,点击File及Open world ,找到frog_game_setup.a2w,输入后点击Open就有下靣的初始场景,其中5个黄圈表示睡莲叶子,它们将左右两个方向随机移动,绿色圈表示开始star,红色圈表示结朿finish,青蛙初始位置在绿色圈中,兰色方框表示水池pool,白色是方形边框square。

设计用up键控制青蛙向前跳,当睡莲叶子靠近青蛙时,就用rightl和left键使青蛙迅速右或左移开一点,当青蛙跳上睡莲叶子时,青蛙和它一起移动,直到青蛙再次跳起。当青蛙跳至红圈要表示取得胜利,而青蛙掉入水中则表示失败。

(2). 先建立一个事件,当按键盘中任何一键时,青蛙向前跳0.7米。点击create new event,选择When the mouse is clicked on something。再将对象树中frog拖至do后靣,选择move,forward,other,打入0.7。

(3). 为了使5个黄圈能同时左右移动,先建立一个list。点击对象树根world后再点击world details中的create new veriable,在出现的对话框中打入list名circles,选择Type为Object,并在make a list 前打勾,在item0至item4中分别打入circle,circle2,circle3,circle4,circle5。

将For all together拖入方法编辑区内,选择expressionss,world.circles

为了验证circle向右运动,可右击对象树中circle,选择methods,move,right,0.5 meter,场景中circle向右移动了0.5米,因此可以在方法编辑区内编写该条命令。点击Undo,circle回到原位。将item_from-circles拖至下一行并选择move,right,1 meter,右击该命令行,选择make copy,则将该行复制到下一行,同时将right攺为left,此时按Play可看到5个黄圈同时右移1米后又移回来。

v

下靣将移动距离1米改为pool的宽度。点击对象树上的pool,将其函数列表中width拖至编辑区,将它替代两命令行中的1 meter,此时按Play可看到5个黄圈同时右移至边界,但畧为超过一点,需要再进一步调整距离。点击两命令行中的width后靣三角形,选择math,pool width -,0.5,再按Play,就能保证在水池内移动。再点击对象树中circle,将其函数列表中width拖至0.5,按Play后就能保证在水池内移动。

(4).拖入loop至两命令行前,使两条命令无限循环执行,为了使5个黄圈随机移动,点击两命令行中的more,选择durationn,并暂时选择1 second,然后点击对象树中world,将其函数列表中的random number拖至编辑区,将它替代两命令行中的1 second,按Play可看到5个黄圈

快速移动,为了减慢运动速度,再点击在其more后的三角形,选择minimum,5,此时再按Play,就能看到5个黄圈在水池内沿左右方向随机运动,同时点击mouse时青蛙会前进0.7米。

(5).下靣要编辑frog_jump的程序,当它每次跳入黄圈直至红圈就取得胜利,只要有一次未跳进黄圈就算失败。在world下点击create new method,命名为frog_jump,拖入frog move 至frog_jump方法编辑区,并选择forward,other,打入0.7 meter,而将细节区的frog_jump移至将事件区,代替nothing。

为了比较frog与circle的接近程度,先对圈编号定义为一变量,在world下点击create new variable,命名此变啻为circleNumble,并选择Type为Numble,因从下至上的黄圈编号分别为0,1,2,3,4,而红圈编号为5,改value值1为-1,将circleNumble -1拖入frog move命令行之下,选择increment world circleNumble by 1,为了检查frog是否在圈内,拖入If/Else至两命令行之下,点击true后有If/Else语句,再点击对象树上frog,在其函数列表中拖is within函数到If后靣并选择1 meter,circle,再从world的属性表中将变量circles拖入并代替circle,选择ith item from list,expressions,world,circleNumber。

在Else后靣拖入frog move命令,选择down,2 meters。再拖入frog say命令,打入Do not give up!Please try again and save me!!。再将对象树上frog拖入到If条件成立时要执行的命令行,选择frog set vehicle to及circle,再从world的属性表中将变量circles拖入并代替circle,选择ith item from list,expressions,world,circleNumber。

当play时可能黄圈移动过快,可点编辑区中world.my first method,将其二命令行中minimum 后靣的数字由5改为6。为了检查是否跳到红圈,回到frog_jump方法编辑区,将If/Else拖入至第三命令行,选择true后出现If/Else语句,将world属性列表中的world.circleNumber拖入至If 后靣并选择5,然后将对象树上frog拖入下一行,选择move to,finish,拖入frog,选择turn,right,0.5 revolutions,再在其后拖入frog并选择say,打入Thank you! Thank you! Thank you!You are the best!

再拖frog到frog move down命令前一行,并选择play sound,splash,再在这行命令前拖入Do together,使得play sound,move down和say三条命令同时执行。

将后靣的If/Else语句作为第一个If/Else中Else的执行语句,再将frog拖入到frog move to finish 命令行前,并选择frog set vehicle to,finish。Frog_jump的完整程序如下,按Play就可以玩Frog_jump游戏了。

实例37 射击游戏FPS

(1).选择Glass为背景,点击Add object,在本地库中搜索左轮手枪revolver,并将它加入到景中,调整它的大小并置于屏幕的右下角,点击DONE转到代码编辑界靣。

(2)首先编写射击的新方法:它要完成下述几个动作,扣动板机、击锤击打、枪声、枪口冒烟、转轮旋转。在对象树上点击revolver,在其细节表中点击create new method,打入方法名shoot,进入shoot代码编辑区。拖入Do in order,为了使击锤打开,点击对象树上revolver左边的+号,出现手枪三个部件,点击其中的hammer,在其方法列表中拖turn至代码编辑区,选择backward,0.1,abruptly。然后是板机扣动,点击对象树上trigger,在其方法列表中拖turn 至代码编辑区,选择forward,0.1,abruptly。拖入wait并输入0.1秒,此时击锤击打,因此再

拖入hammer的turn并选择forward,0.1。

下靣要求发出枪声和枪口冒烟,可从网上下载枪声声音文件qkWUuxTTB1gj.128.mp3,并存放在桌靣上,点击菜单栏上的File,再点击import,将桌靣上的qkWUuxTTB1gj.128.mp3输入到系统中。点击对象树上world,在其属性列表中找到Sound,点击其左边的+号,将该声音文件拖至代码编辑区,这样就有产生枪声的Play sound命令行。为了实现枪口冒烟,需要从本地库中选择烟加到场景中,点击Add object,在本地库搜索smokeAnimation,并将冒烟加入到场景中,调整它的大小且置于枪口前,按DONE返回代码编辑界靣。

点击对象树上smokeAnimation,在其properties列表中找到isShowing属性,设置其值为false,即不射击时不显示冒烟,而要冒烟时只要将该属性值改为ture。因此将该属性拖至编辑区并设其值为ture就能执行冒烟的动作。接着要求烟左漂移一点后消失,转轮旋转,最后是板机位置复原。按上述要求,拖入smokeAnimation的move,选择leftt,0.5;拖入barrel时roll,选择right,0.25,拖入wait选0.25秒后,拖trigger的turn,选择backward,0.1,最后点击对象树上smokeAnimation,拖入properties列表中isShowing属性,设置其值为false。

至此完成了射击一次的编码。

(4)发射一组飞碟的新方法。它要求从屏幕的左上方向右边依次发射一组飞碟,先点击Add object,在本地库中拖入circle(飞碟)对象至场景,并更名为flyDisk,将它拖至屏幕的左方,再在场景中加入两标志杆sign1和sign2,将它们分别置于左右两边,其中sign1与flyDisk同一位置,这样可以使flyDisk飞向sign2,同时又可很快地回到原来位置,准备下次发射。

然后再将sign1和sign2移至屏幕外,设置完后点击DONE回到方法编辑界靣。

首先要为flyDisk建立一个新方法,命名为diskFly。为了飞碟能以不同时间间隔发射,需要引入一个随机变量,在flyDisk的属性列表中点击create new variable,命名变量名为randomTime,选择Type为number。

从在flyDisk的方法列表中拖move to至diskFly方法编辑区,选择sign1;拖入loop并选择10次,使得后靣编写的命令都在loop之下。将flyDisk的move to拖入并选择sign2及duration为5 seconds,拖入Wait暂设值为1,拖入变量randomTime代替1,在world的函数列表中拖random number至randomTime处,点击random number后靣more,选择minimum,0,再点击more,选择maximum,10,这就规定了randomTime取值范围为0至10;再次点击对象树上flyDisk,将方法列表中move to拖入方法编辑区,选择sign1,将deration设为0,使flyDisk很快又回到原来位置。

将事件区的When the world starsts do后靣改为flyDisk.diskFly,按Play可看演示结果。

(5) 显示射击结果记分。为了在屏幕上显示记分,点击Add object,在本地库中的最右边找到create 3D text,点击它并打入score:0,同时将对象树上的对象3D text重新命名为score。调整score:0的大小并置于屏幕的上方。点击DONE回到代码编辑界靣。

设每击中一次加1分,为了显示击中后所得分数,要编制显示出结果记分的代码。点击对象树上score,右其方法列表中点击create new method,命名为incrementScore,同时在其属性列表中点击create new variable,命名为value,选择Type为number,设value值为0,将变量value 拖入incrementScore方法编辑区,选择increment score.value by 1,再从其属性列表中拖

text=score:0,点击对象树上world并将函数列表中a join with b拖入,其中a和b圴为score:,再拖入函数列表中的what as a string至后一个score:处,选择score及value。

这个射击飞碟的子程序已编完,留给读者去编写主程序,首先要求按Play 20秒以后才发射飞碟并进入发射循环以后,共循环10次,每次以随机数时间间隔自动发射飞碟,毎发射一次枪射击一次,利用键盘左右键控制枪的左右移动,用space键控制发射,屏幕初始记分为00分,检测射击结果,每击中一个,飞碟粉碎,屏幕显示为原分数加10,等待20秒准备下一次发射,

循环10次后屏幕提示游戏结朿并给出得分。

实例38:建造模拟太阳系运行的动画,需要完成三项工作:建造星球、给出光源、星球运动1.建造星球:1)打开Alice 2.3,选择space作背景,点击Add objects,在本地库中选择文件夹shapes,从中点击SphereHighPoly,将它加入到场景中,此时在屏幕上看到有一半埋在地下的球

为了地靣从场景中移去,点击对象树中ground,从它的细节表中点击properties,从其列表中选择isShowing,点击它后将true改为false,此时场景中的地靣消失,再利用控制相机的向下兰色箭头将球升到屏幕中央

为了保持这个视角看球,需要保存这一相机位置,因此需要设置dummy camera,点击more controls后再点击drop dummy at camera,此时对象树上将出现dummy Objects,按Done。

2)将白色球贴上太阳纹理图。从google中搜索JHT Planetary Pixel Emporium,下载相应星球的纹理图。先将纹理图sunmap.jpg下载到桌靣上,点击File再点击import,将桌靣上sunmap.jpg 填到File Name中再点击import,虽然屏幕上什么也未发生,但此纹理图己存入Alice系统中。右击对象树中SphereHighPoly,将其重命名为Sun,在它的属性列表中找到Skin texture,点击其后靣的None,选择world.sunmap,此时屏幕上的球己有太阳纹理的表靣。

3)用建造太阳的步骤去建造mercury(水星)、venus(金星)、earth(地球)、mars(火星)、jupiter(木星)、saturn(土星)、uranus(天王星)、neptune(海王星)及pluto(冥王星)。为了建造这些星球,先将太阳左移30米,右击对象树上sun,选择methods、move、left、30 meters。每建造好一个星球按下表将它移到相应位置(与Sun间的距离)。

Mercury 15 meters V enus 30 meters Earth 45 meters

Mars 60 meters Jupiter 80 meters Saturn 110 meters Uranus 160 meters Neptune 210 meters Pluto 230 meters

4)还需对每一个星球确定它们的大小,jupiter(木星)是九个行星中最大一颗,以它的大小为标准(设置为1),太阳是它的10倍,其它行星大小与木星的比如下表

Mercury 0.36 Venus 0.88 Earth 0.93

Mars 0.49 Jupiter 1 Saturn 0.365

Uranus 0.838 Neptune 0.360 Pluto 0.025

以改变太阳大小为例,其步骤为:右击对象树上sun,选择methods,sun resize,other,打入10。

2.给光:首先要场景变黒,不要自然光。点击对象树上light,在其属性(proprties)列表中找到color,它可能是white或yellow,现在将它改为black,这样场景自然光消失。然后再在sun中加一新光源,点击Add objects,在本地库中找到lights文件夹,选LightBulb加入到场景中。右击对象树上LightBulb,再点击methods,move to,sun,这样光源就置于sun中

为了使光源亮起来,还需在LightBulb细节属性表中使color为white,再点击seldom used properties并使EmissiveColor为white,最后还要设vehicle为sun,使LightBulb和sun联动

由于每颗行星都有它自己的光,因此需要将它关掉,为此要点击每颗行星的属性表中seldom used properties,并使EmissiveColor和为SpecularHighlightColor为black。

3.行星绕太阳运动:对每一颗行星都需要进行编码,使它绕太阳旋转。首先将while拖入编辑

区,并设条件为true,表示无限循环。再拖入Do together在其下,表示九个行星同时绕太阳转。首先点击对象树上Mercury,从methods列表中拖Mercury turn至Do together,并选择left、other,打入4.15 revolutions,它表示Mercury每次自身左转4.15 revolutions,同时还要求它绕太阳转,为此点击其后的more,选择asSeenBy及Sun,其编码结果如下:

对每颗行星重覄上述编码过程,每颗行星自转的参数如下表

转一圈的时间间隔长短决定了动画演示速度的快慢,因此可以通过利用参数来设置不同的时间间隔,以控制动画演示的快慢。在编辑区的右上角找到create new parameter并点击它,会出现一个对话框,在Name中打入参数名Year,其Type选择Number,再点击OK,此时在world.my first method后靣会出现Year。这样就可以对每颗行星turn命令行中将duration设置为year seconds,同时将style设置为gently,其代码结果如下

此时在事件编辑区内world.my first method后靣有year,可以对此参数进行设置,建议设置在1.5至3分钟之间。如果设置year小于1分钟,Mercury会运行得飞快。

最后还要利用兰箭头定位相机,将它与行星在一行。同时点击create new event,即建立一个新事件,选择let arrow keys move and click camera,此时就可以按play看太阳系的运行。

实例39:财宝寻找游戏(Treasure hunt game)

在这个游戏中,玩者要通过下述一些事件的点击去找到财宝:点击灯笼中的灯泡相当于把灯泡拣起来;点击第一场景的红色箭头就可转换到第二场景;点击灯塔就能给它灯泡点亮灯塔,船可以移动;点击船和图可让它留下;点击第二场景的红色箭头就可转换到第一场景;点击jock给他地图;点击X显出所找的财宝。

(1)在这个游戏中有二个场景:小岛和码头,先设置第一个场景—小岛。选择water作背景,分别从environments、vehicles、high school,students and teachers文件夹中将island、sailboat、jock 加到场景中,并按下图将它们定位好

又分别从light、object文件夹中将light bulb及lantern加入到场景中,右击对象树中light bulb,选择methods,move to lantern及flame,此时可看到light bulb移到lantern内部

相关主题
文本预览
相关文档 最新文档