教程:向匹配游戏 WinForms 应用中添加引用变量和计时器控件
在这四个教程系列中,你将构建一个匹配游戏,玩家在其中匹配隐藏的图标对。
匹配游戏程序需要跟踪玩家选择了哪些标签控件。 在玩家选择第一个标签后,该程序应显示图标。 在选择第二个标签后,该程序应短暂显示两个图标。 然后隐藏这两个图标。
程序通过引用变量跟踪第一次和第二次分别选择的标签控件。 计时器隐藏图标并控制显示图标的时间长度
- 添加标签引用。
- 添加计时器。
必备条件
本教程基于前面的教程,即创建匹配游戏应用程序和向匹配游戏中添加图标。 请先完成这些教程的学习。
添加标签引用
本部分将向代码添加两个引用变量。 它们跟踪或引用标签对象。
通过使用下面的代码向窗体中添加标签引用。
public partial class Form1 : Form { // firstClicked points to the first Label control // that the player clicks, but it will be null // if the player hasn't clicked a label yet Label firstClicked = null; // secondClicked points to the second Label control // that the player clicks Label secondClicked = null;
重要
使用此页右上角的编程语言控件查看 C# 代码片段或 Visual Basic 代码片段。
这些语句不会导致窗体中显示标签控件,因为没有 new
关键字。
当程序启动时,firstClicked
和 secondClicked
都设置为 null
(对于 C#)或 Nothing
(对于 Visual Basic)。
修改 Click 事件处理程序,以使用新的
firstClicked
引用变量。 移除label1_Click()
事件处理程序方法中的最后一个语句 (clickedLabel.ForeColor = Color.Black;
),并将它替换为下面的if
语句。/// <summary> /// Every label's Click event is handled by this event handler /// </summary> /// <param name="sender">The label that was clicked</param> /// <param name="e"></param> private void label1_Click(object sender, EventArgs e) { Label clickedLabel = sender as Label; if (clickedLabel != null) { // If the clicked label is black, the player clicked // an icon that's already been revealed -- // ignore the click if (clickedLabel.ForeColor == Color.Black) return; // If firstClicked is null, this is the first icon // in the pair that the player clicked, // so set firstClicked to the label that the player // clicked, change its color to black, and return if (firstClicked == null) { firstClicked = clickedLabel; firstClicked.ForeColor = Color.Black; return; } } }
保存并运行程序。 选择其中一个标签控件,它的图标将显示。 选择下一个标签控件,发现没有任何反应。
只有选择的第一个图标会出现。 其他图标是不可见的。
该程序已跟踪玩家选择的第一个标签。
引用 firstClicked
不是 C# 中的 null
或 Visual Basic 中的 Nothing
。
当 if
语句发现 firstClicked
不等于 null
或 Nothing
时,会运行这些语句。
添加计时器
匹配游戏应用使用 Timer 控件。 计时器等待后,触发一个称为“Tick”的事件。 计时器可以启动操作或定期重复操作。
在程序中,计时器允许玩家选择两个图标。 如果图标不匹配,则在短暂时间后再次隐藏这两个图标。
选择“工具箱”选项卡,在“组件”类别中,双击“计时器”组件或将其拖到窗体中。 该计时器图标名为“timer1”,显示在窗体下的空间中。
选择“Timer1”图标以选中该计时器。 在“属性”窗口中,选择“属性”按钮以查看属性。
将“间隔”属性设置为“750”,即 750 毫秒。
“间隔”属性将通知计时器两个时钟周期之间的等待时长,或何时触发 Tick 事件。 在玩家选择第二个标签后,程序调用 Start() 方法启动计时器。
选择计时器控件图标,然后按 Enter,或双击计时器。 IDE 添加空的 Tick 事件处理程序。 将代码替换为以下代码。
/// <summary> /// This timer is started when the player clicks /// two icons that don't match, /// so it counts three quarters of a second /// and then turns itself off and hides both icons /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void timer1_Tick(object sender, EventArgs e) { // Stop the timer timer1.Stop(); // Hide both icons firstClicked.ForeColor = firstClicked.BackColor; secondClicked.ForeColor = secondClicked.BackColor; // Reset firstClicked and secondClicked // so the next time a label is // clicked, the program knows it's the first click firstClicked = null; secondClicked = null; }
Tick 事件处理程序将执行三项操作:
- 通过调用 Stop() 方法确保计时器没有运行。
- 它使用两个引用变量
firstClicked
和secondClicked
,使得玩家选择的两个标签的图标再次不可见。 - 它将
firstClicked
和secondClicked
引用变量重置为null
(C# 中)或Nothing
(Visual Basic 中)。
转至代码编辑器,将代码添加到
label1_Click()
事件处理程序方法的顶部和底部。 此代码将检查计时器是否已启用,设置secondClicked
引用变量,并启动计时器。label1_Click()
事件处理程序方法现在如下所示:/// <summary> /// Every label's Click event is handled by this event handler /// </summary> /// <param name="sender">The label that was clicked</param> /// <param name="e"></param> private void label1_Click(object sender, EventArgs e) { // The timer is only on after two non-matching // icons have been shown to the player, // so ignore any clicks if the timer is running if (timer1.Enabled == true) return; Label clickedLabel = sender as Label; if (clickedLabel != null) { // If the clicked label is black, the player clicked // an icon that's already been revealed -- // ignore the click if (clickedLabel.ForeColor == Color.Black) return; // If firstClicked is null, this is the first icon // in the pair that the player clicked, // so set firstClicked to the label that the player // clicked, change its color to black, and return if (firstClicked == null) { firstClicked = clickedLabel; firstClicked.ForeColor = Color.Black; return; } // If the player gets this far, the timer isn't // running and firstClicked isn't null, // so this must be the second icon the player clicked // Set its color to black secondClicked = clickedLabel; secondClicked.ForeColor = Color.Black; // If the player gets this far, the player // clicked two different icons, so start the // timer (which will wait three quarters of // a second, and then hide the icons) timer1.Start(); } }
- 该方法顶部的代码通过检查 Enabled 属性的值来检查计时器是否已启动。 如果玩家选择第一个和第二个标签控件,且计时器启动,则选择第三个控件将不会执行任何操作。
- 该方法底部的代码将
secondClicked
引用变量设置为跟踪第二个标签控件。 然后将该标签的图标颜色设置为黑色以使其可见。 然后,它在单触发模式下启动计时器,以便在等待 750 毫秒后触发单个 Tick。 计时器的 Tick 事件处理程序会隐藏这两个图标,并重置firstClicked
和secondClicked
引用变量。 窗体准备就绪供玩家选择另一对图标。
注意
如果你复制和粘贴 label1_Click()
代码块,而不是手动输入代码,请确保替换现有的 label1_Click()
代码。
否则,你将得到重复的代码块。
- 保存并运行程序。 选择一个正方形,图标将变得可见。 选择另一个正方形。 图标会短暂显示,然后两个图标都消失。
程序现在跟踪你选择的第一个和第二个图标。 它使用计时器在使图标消失之前暂停。
后续步骤
请继续阅读下一篇教程,了解如何完成匹配游戏。