友情提示:380元/半年,儿童学编程,就上码丁实验室。

第3课 编写程序——处理按钮点击事件
1、流程图

注意流程图中的三个矩形框:记住第一张卡片、记住第二张卡片、忘记两张卡片,这是编写程序的关键。所谓记住或忘记,就是要用全局变量来记录已经翻开的卡片。这里我们声明两个全局变量:翻牌1及翻牌2,来保存正在翻开等待判断的两个按钮对象。在应用初始化时,设置它们的值为0 ,当第一张牌被翻开时,设
翻牌1 = 第一个被点击的按钮对象
当第二张牌被翻开时,设
翻牌2 = 第二个被点击的按钮对象
并以这两个变量为依据,判断按钮图案的异同。
2、判断两个按钮图案的异同
我们先以按钮1及按钮2为例来编写代码,如图1- 19所示。

- 根据按钮对象在按钮列表中的位置(索引值),从随机图案列表中获取按钮的正面图案,并显示该图案;
- 设置被点击按钮的启用属性值为假(考虑一下为什么,如果不这样,当再次点击该按钮时,会发生什么事情?);
- 判断它是不是第一张被翻开的卡片,如果是,将翻牌1设置为该按钮对象,否则,将翻牌2设置为该按钮对象,并判断已经翻开的两个按钮的正面图案是否相同。这里我们暂时不做进一步的处理,而是利用屏幕的标题属性来显示测试结果,即,如果按钮1与按钮2的图案相同,则屏幕的标题显示“图案相同”,否则显示“图案不同”;
- 如果已经翻开两张卡片,无论它们的正面图案是否相同,都必须重新将翻牌1及翻牌2的值设置为0。
测试结果如图1- 20所示。

3、处理两个按钮图案相同的情况
按照图1- 18的设计,当图案相同时,记住已经翻开的卡片对数。凡是需要记住的内容,都需要一个全局变量来保存它,已翻开卡片的对数一方面用于计算游戏得分,另一方面用于判断是否所有卡片都已经被翻开(等于8时)。我们将这个变量命名为翻牌对数。
当两张卡片的正面图案相同时,有三件事情需要完成:
- 为全局变量翻牌对数的值+1;
- 计算并显示游戏得分;
- 判断翻牌对数是否等于8,并依据判断结果选择执行两条路径之中的一条:
- 当翻牌对数=8时,显示“游戏结束”;或者
- 当翻牌对数<8时,显示“图案相同”。
假设每翻开一对卡片得10分,因此游戏得分 = 翻牌对数X10,我们用标签得分来显示游戏得分,具体代码如图1-21所示。

4、处理两个按钮图案不同的情况
当两张被翻开的卡片图案不同时,将它们重新扣上,即,让它们显示背面图案。为了让已经翻开的图片能够显示一定的时间,这里需要用到计时器组件,一旦判断出两个卡片图案不同,则启动计时器,经过一个计时间隔的时长后,计时器发生计时事件,在计时事件的处理程序中,将两张卡片同时扣上。我们用闪现计时器来实现这一功能。这里闪现计时器的计时间隔为500毫秒,如果需要加大游戏的难度,可以将计时间隔设置的更短。
我们在“图案不同”的分支里添加一个语句——启动闪现计时器,并编写了闪现计时器的计时事件处理程序,如图1- 22所示。

5、代码的复用——改进按钮点击事件处理程序
到目前为止,我们已经能够处理两个按钮的点击事件,我们需要将按钮1点击事件处理程序中的代码复制到其他14个按钮的点击事件处理程序中。这种说法听起来很可怕,试想,如果我们开发过程中需要修改其中的部分代码(这种事情经常会发生),那么我们要完成额外15倍的工作量,同时也增加了程序出错的风险。即便是我们能够一丝不苟地完成这些代码,但如何编写闪现计时器的计时事件处理程序呢?因此我们需要寻找一个更为简洁的代码编写方法。让我们先来观察一下已有的两个按钮的点击事件处理程序,如图1- 23所示。

创建一个带参数的过程,过程名为处理点击事件,参数名为某按钮,将按钮1的代码拖拽到新建的过程中,然后对代码进行改造,如图1- 24所示:
- 添加一个局部变量图案索引值:求某按钮在按钮列表中的位置,前面我们讲过,按钮列表与随机图案列表中的列表项是一一对应的,因此某按钮在按钮列表中的位置也是它的正面图案在随机图案列表中的位置;
- 使用“任意组件”类代码来取代原来的前两行代码——设置某按钮的图像属性为正面图案,设置某按钮的启用属性为假;
- 当被点击的两张卡片图案不同时,添加一个局部变量翻牌1图案索引值,求出第一张翻开的卡片其正面图案在随机图案列表中的位置,并使用两个局部变量(翻牌1图案索引值及图案索引值)来求得两个卡片的正面图案;
- 在按钮1及按钮2的点击事件处理程序中调用该过程,并为参数指定具体按钮。




6、代码的复用——改进闪现计时器的计时事件处理程序
与点击事件相关联的还有闪现计时器的计时事件,在图1- 23中,我们直接改写了按钮1及按钮2的图像及启用属性,现在需要将这段程序加以修改,以适用于所有的按钮。
还记得全局变量翻牌1和翻牌2中保存的是什么吗?是的,保存的正是已经被翻开的两个按钮。我们正好可以利用这两个变量,对计时程序中的前四行代码进行改写,如图1- 28所示。

7、测试
上述代码需要经过测试才能进入下一步开发。测试过程记录如下:
- 程序启动之后,16个按钮显示背面图案;✓
- 点击按钮1,按钮1显示正面图案;✓
- 点击按钮2,按钮2显示正面图案,两按钮的图案不同,但并没有闪现之后扣上;✓
- 在开发环境的编程视图中,弹出错误提示,如图1- 29所示。✘

问题有可能出在全局变量翻牌1和翻牌2的设置上。我们来分析一下程序的执行顺序,如图1- 30所示。

翻牌1 = 按钮1 翻牌2 = 按钮2
由于图案不相同,闪现计时器被启动,从这一时刻起开始计时,500毫秒之后,开始执行计时程序。而此时的按钮点击程序并没有停止,在屏幕标题显示“图案不同”之后,立即执行最后两条命令——设翻牌1及翻牌2的值为0。

为了解决这个问题,我们调整程序的流程,如图1- 31所示。与新流程对应的代码如图1- 32所示,经过测试,程序运行正常,运行结果如图1- 33所示。


我们的程序开发到这里,游戏已经具备了基本的功能,但是显然这样的游戏是毫无乐趣的,因为任何人最终都能将所有卡片翻开,而且无论如何也只能得到80分,因此我们要增加游戏的难度,并让那些记忆力超强的玩儿家能得到更高的分数。我们的方法是限制游戏时间,并用剩余时间来奖励那些高手。