用scratch编写游戏-数字华容道(不移动块法)
前边已写了两篇博客介绍用scratch编写“数字华容道”游戏的方法。在以前设计中有一个误区,认为只有通过移动带数字的块才能完成数字的重新排列。实际上采用克隆法,角色“带数字的块”有25个造型,包括24个数字(1到24)和一个空白造型。其克隆体也有25个造型,可把多个克隆体放在不同固定位置上,不必移动克隆体,通过改变克隆体的造型,也可达到数字重新排列效果。采用这一思想,可以简化程序。首先给每一个可放置克隆体的位置一个编号,叫“位置编号”,以3行3列为例,从第1行开始从左到右顺序编号1、2、3,第2行4、5、6,最后一行7、8、9。本法只需一个列表:所有位置应显示的造型。该表的项号对应“位置编号”,如项号1对应位置1,每项所存内容是该位置上的克隆体应使用的造型号,造型号从0到24,0号为空白造型。程序初始时所有位置的数字应随机摆放,即0到24这些数字随机分布在列表的每项中。
“使数字随机摆放”脚本块实现了该功能,见下图。首先增加变量:块数9或16或25,根据所选关卡,其值可以是9、16、25。下边以第1关为例说明脚本所实现的功能,此时“块数9或16或25”为9。首先删除列表以前所有数据,然后把8、7…1、0这9个数按此顺序填入到列表中。然后用随机数发生器从1到9中生成随机数作为项号,把最后一项的数据取出插入到该项号数据前边,然后删除最后一项。重复9次。在主程序发送“显示列表指定造型”消息后,每个数字块根据自己所在位置从列表取出造型号,改变造型。
程序只有两个角色:“带数字的块”和“提示”。角色“提示”有两个造型,一个造型用来提示用户如何玩游戏:单击数字移动数字块,另一造型在玩家胜利后提示:你赢了。角色“带数字块”有25个造型,一个空白造型上无任何数字,块号为0,其余24个造型上面有数字,分别从1到24,块号从1到24。见下图。
在角色“带数字的块”中建立变量:克隆体所在位置号,建立这个变量时,必须选择:仅适用于当前角色,这样每个克隆体都有一个名称为“克隆体所在位置号”变量,用来记录该克隆体所在位置号。
角色“带数字的块”的单击绿旗所执行的脚本(主程序)、“当作为克隆启动时”脚本和“选择关卡”脚本如下。由于不使用角色“带数字的块”,主程序开始将其隐藏。然后选关卡。其后执行脚本块“使数字随机摆放”。再后根据关卡不同,克隆不同数量的角色“带数字的块”克隆体。每克隆一次,“当作为克隆启动时”脚本运行,首先令“克隆体所在位置号”=N后,将N增加1为下一克隆体的“克隆体所在位置号”,显示本克隆体。最后广播“移动块到指定位置”消息,使各个克隆体移到指定位置,广播“显示列表指定造型”消息,使各个克隆体根据列表选择不同造型,这时显示的数字是随机排列的。特别指出,脚本N增加1只能放在“当作为克隆启动时”脚本中,不能放在脚本“克隆自己”之后,否则可能出错。这可能是因为不同脚本块可能在不同线程运行所引起的。
下边是三个脚本块:“由位号计算行列号”、“当接收到移动块到指定位置”和“当接收到显示列表指定造型”。由于多处用到把“克隆体所在位置号”转换为数字排列的行号和列号,因此把此功能设计为函数(脚本块)。该函数有一个参数是“位置号”,是“克隆体所在位置号”的简称。每个克隆体把自己的“克隆体所在位置号”作为参数,就能计算出自己所在行和列号。现以3行3列为例,说明其工作原理,此时行列数=3,有9个克隆体。1号位置应在1行1列,2号位置应在1行2列,3号位置应在1行3列等等。用位置号/行列数:1/3整数商(即向下取整)为0余数为1,2/3整数商为0余数为2,3/3整数商为1余数为0等等。如将整数商作为行号,余数作为列号,前两项列号正确,行号应加1;最后一项行号正确,列号为0应改为行列数(为3)。按此思路读懂该段脚本应无问题。知道了行列号,脚本块“当接收到移动块到指定位置”很容易把克隆体移到指定位置,脚本中的-90和140是1行1列的克隆体所在位置的X和Y坐标,70为各克隆体上下和左右之间间隔。在脚本块“当接收到显示列表指定造型”中,从列表中取出项号为“克隆体所在位置号”的数据就是造型号,可用它修改造型。如造型号为0,表示是空白造型,把其“克隆体所在位置号”保存到变量“显示空白的位置号”中,在脚本块“当角色被单击”中要用到此数据。
脚本块“当角色被单击”和“计算排列是否正确”如下。当某克隆体被单击时,其首先要判断是否和显示空白的克隆体相邻,判断相邻的公式为:(被单击克隆体行号-显示空白克隆体行号)的绝对值+(被单击克隆体列号-显示空白克隆体列号)的绝对值=1,如相邻,只需把列表中两个克隆体的数据互换,然后广播“显示列表指定造型”消息即可。判断数字排列是否正确,只需查看列表中的数据除去最后一项,其它项的项号是否等于其所存数据,即第1项数据为1,第2项数据为2,第3项数据为3等等。如排列正确,广播消息:你赢了。
角色“提示”的脚本如下。
运行效果图如下。