教程:向匹配游戏 WinForms 应用中添加引用变量和计时器控件

在这四个教程系列中,你将构建一个匹配游戏,玩家在其中匹配隐藏的图标对。

匹配游戏程序需要跟踪玩家选择了哪些标签控件。 在玩家选择第一个标签后,该程序应显示图标。 在选择第二个标签后,该程序应短暂显示两个图标。 然后隐藏这两个图标。

程序通过引用变量跟踪第一次和第二次分别选择的标签控件。 计时器隐藏图标并控制显示图标的时间长度

  • 添加标签引用。
  • 添加计时器。

必备条件

本教程基于前面的教程,即创建匹配游戏应用程序向匹配游戏中添加图标。 请先完成这些教程的学习。

添加标签引用

本部分将向代码添加两个引用变量。 它们跟踪或引用标签对象。

  1. 通过使用下面的代码向窗体中添加标签引用。

    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 代码片段。

Programming language control for Microsoft Learn

这些语句不会导致窗体中显示标签控件,因为没有 new 关键字。 当程序启动时,firstClickedsecondClicked 都设置为 null(对于 C#)或 Nothing(对于 Visual Basic)。

  1. 修改 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;
            }
        }
    }
    

  1. 保存并运行程序。 选择其中一个标签控件,它的图标将显示。 选择下一个标签控件,发现没有任何反应。

    Screenshot shows the Matching Game showing one icon.

    只有选择的第一个图标会出现。 其他图标是不可见的。

该程序已跟踪玩家选择的第一个标签。 引用 firstClicked 不是 C# 中的 null 或 Visual Basic 中的 Nothing。 当 if 语句发现 firstClicked 不等于 nullNothing 时,会运行这些语句。

添加计时器

匹配游戏应用使用 Timer 控件。 计时器等待后,触发一个称为“Tick”的事件。 计时器可以启动操作或定期重复操作。

在程序中,计时器允许玩家选择两个图标。 如果图标不匹配,则在短暂时间后再次隐藏这两个图标。

  1. 选择“工具箱”选项卡,在“组件”类别中,双击“计时器”组件或将其拖到窗体中。 该计时器图标名为“timer1”,显示在窗体下的空间中。

    Screenshot shows the timer icon below the form.

  2. 选择“Timer1”图标以选中该计时器。 在“属性”窗口中,选择“属性”按钮以查看属性。

  3. 将“间隔”属性设置为“750”,即 750 毫秒。

    “间隔”属性将通知计时器两个时钟周期之间的等待时长,或何时触发 Tick 事件。 在玩家选择第二个标签后,程序调用 Start() 方法启动计时器。

  4. 选择计时器控件图标,然后按 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() 方法确保计时器没有运行。
  • 它使用两个引用变量 firstClickedsecondClicked,使得玩家选择的两个标签的图标再次不可见。
  • 它将 firstClickedsecondClicked 引用变量重置为 null(C# 中)或 Nothing(Visual Basic 中)。
  1. 转至代码编辑器,将代码添加到 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 事件处理程序会隐藏这两个图标,并重置 firstClickedsecondClicked 引用变量。 窗体准备就绪供玩家选择另一对图标。

注意

如果你复制和粘贴 label1_Click() 代码块,而不是手动输入代码,请确保替换现有的 label1_Click() 代码。 否则,你将得到重复的代码块。

  1. 保存并运行程序。 选择一个正方形,图标将变得可见。 选择另一个正方形。 图标会短暂显示,然后两个图标都消失。

程序现在跟踪你选择的第一个和第二个图标。 它使用计时器在使图标消失之前暂停。

后续步骤

请继续阅读下一篇教程,了解如何完成匹配游戏。