教程:向匹配游戏 WinForms 应用中添加图标

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

在匹配游戏中,玩家选择一个方块来查看图标,然后选择另一个方块。 如果图标互相匹配,则它们保持可见。 如果不匹配,游戏将隐藏这两个图标。 在本教程中,你将随机向标签分配图标。 将其设置为隐藏,然后在选中时显示。

在第二个教程中,你将了解如何:

  • 添加 Random 对象和图标列表。
  • 向每个标签分配一个随机图标。
  • 添加事件处理程序,用于显示标签的图标。

必备条件

此教程基于上一教程创建匹配游戏应用程序。 如果尚未学习此教程,请先完成此教程。

添加 Random 对象和图标列表

在本部分中,你要为游戏创建一组匹配的符号。 每个符号将添加到窗体上 TableLayoutPanel 中的两个随机单元格。

使用 new 语句创建两个对象。 第一个是 Random 对象,随机选择 TableLayoutPanel 中的单元格。 第二个是 List<T> 对象。 它存储随机选择的符号。

  1. 打开 Visual Studio。 MatchingGame 项目显示在“打开最近使用的文件”下。

  2. 如果使用的是 C#,请选择“Form1.cs”,如果使用的是 Visual Basic,则选择“Form1.vb”。 然后选择“查看”>“代码”。 也可以选择 F7 键或双击“Form1” 。 Visual Studio IDE 显示 Form1 的代码模块。

  3. 在现有代码中,添加以下代码。

    public partial class Form1 : Form
    {
        // Use this Random object to choose random icons for the squares
        Random random = new Random();
    
        // Each of these letters is an interesting icon
        // in the Webdings font,
        // and each icon appears twice in this list
        List<string> icons = new List<string>() 
        { 
            "!", "!", "N", "N", ",", ",", "k", "k",
            "b", "b", "v", "v", "w", "w", "z", "z"
        };
    

重要

使用此页右上角的编程语言控件查看 C# 代码片段或 Visual Basic 代码片段。

Programming language control for Microsoft Learn

如果你使用 C#,请确保将代码放在左大括号后面,紧靠类声明 (public partial class Form1 : Form) 之后。 如果你使用 Visual Basic,请将代码放在紧靠类声明 (Public Class Form1) 之后。

可以使用列表对象跟踪不同类型的项目。 列表可以包含数字、true/false 值、文本或其他对象。 在匹配游戏中,列表对象具有 16 个字符串,每个字符串对应 TableLayoutPanel 面板中的每个单元格。 每个字符串都是对应于标签中的图标的单个字母。 这些字符在 Webdings 字体中显示为公共汽车、自行车和其他符号。

注意

列表可以根据需要收缩或增长,这在此程序中非常重要。

若要详细了解列表,请参阅 List<T>。 若要查看 C# 中的示例,请参阅基本列表示例。 若要查看 Visual Basic 中的示例,请参阅使用简单集合

向每个标签分配一个随机图标

每次运行该程序时,它都会使用 AssignIconsToSquares() 方法将图标随机分配给 Label 控件。 此代码使用关键字 foreach(C# 中)或 For Each(Visual Basic 中)。

  1. 添加 AssignIconsToSquares() 方法。

    /// <summary>
    /// Assign each icon from the list of icons to a random square
    /// </summary>
    private void AssignIconsToSquares()
    {
        // The TableLayoutPanel has 16 labels,
        // and the icon list has 16 icons,
        // so an icon is pulled at random from the list
        // and added to each label
        foreach (Control control in tableLayoutPanel1.Controls)
        {
            Label iconLabel = control as Label;
            if (iconLabel != null)
            {
                int randomNumber = random.Next(icons.Count);
                iconLabel.Text = icons[randomNumber];
                // iconLabel.ForeColor = iconLabel.BackColor;
                icons.RemoveAt(randomNumber);
            }
        }
    }
    

可以在上一节中添加的代码之下输入此代码。

注意

其中有一行被故意注释掉了。 稍后在此过程中将其添加。

AssignIconsToSquares() 方法循环访问 TableLayoutPanel 中的每个标签控件。 它对每个控件运行相同的语句。 语句从列表中提取随机图标。

  • 第一行将 control 变量转换为名为“iconLabel” 的标签。
  • 第二行是 if 语句,用于检查以确保转换起作用。 如果转换起作用,则 if 语句中的语句将运行。
  • if 语句中的第一行将创建一个名为“randomNumber”的变量,该变量包含一个与图标列表中的项对应的随机数。 它使用 Random 对象的 Next() 方法。 Next 方法将返回此随机数。 此行也使用“图标” 列表的 Count 属性来确定随机数的选择范围。
  • 下一行会将图标列表项之一分配给标签的 Text 属性。
  • 下一行将隐藏这些图标。 该行已在此处注释掉,因此你可以在继续操作之前验证代码的其余部分。
  • if 语句中最后一行将从列表中删除已添加到窗体中的图标。
  1. 将调用添加到 Form1 构造函数的 AssignIconsToSquares() 方法。 此方法用图标填充游戏板。 构造函数在创建对象时进行调用。

    public Form1()
    {
        InitializeComponent();
    
        AssignIconsToSquares();
    }
    

    对于 Visual Basic,将 AssignIconsToSquares() 方法调用添加到 Form1_Load 方法。

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        AssignIconsToSquares()
    End Sub
    

    有关详细信息,请参阅构造函数(C# 编程指南)使用构造函数和析构函数

  2. 保存并运行程序。 它应该显示一个窗体,其中每个标签都分配了随机图标。

    提示

    如果窗体上的 Webdings 图标不能正确显示,请将窗体上标签的 UseCompatibleTextRendering 属性设置为 True。

  3. 关闭程序,然后重新运行。 向每个标签分配不同的图标。

    Screenshot shows the Matching Game displaying the random icons.

    你没有隐藏这些图标,所以现在可以看到。 若要向玩家隐藏图标,可以将每个标签的“ForeColor” 属性设置为与“BackColor” 属性相同的颜色。

  4. 停止程序。 删除循环内注释的代码行的注释标记。

    iconLabel.ForeColor = iconLabel.BackColor;
    

如果再次运行该程序,图标似乎已消失。 只显示蓝色背景。 图标是随机分配的,仍然存在。

向标签添加事件处理程序

在此匹配游戏中,玩家先显示一个隐藏图标,然后再显示第二个图标。 如果图标互相匹配,则它们保持可见。 否则,两个图标都会再次隐藏。

若要使游戏以这种方式工作,请添加一个 Click 事件处理程序,它将更改所选标签的颜色以与背景匹配。

  1. 在“Windows 窗体设计器”中打开窗体。 选择“Form1.cs”或“Form1.vb”,然后选择“查看”>“设计器”。

  2. 选择第一个标签控件以将其选中,然后双击它,将名为 label1 _Click() 的事件处理程序 Click 添加到代码中。

  3. 然后,按住 Ctrl 键的同时选择其他每个标签。 确保选中每个标签。

  4. 在“属性”窗口中,选择“事件”按钮,这是一个闪电形符号。 对于“Click”事件,请在框中选择“label1_Click” 。

    Screenshot shows the Properties window showing Click event.

  5. 选择 Enter 键。 IDE 将名为 label1 _Click() 的 Click 事件处理程序添加到代码中。 由于你选择了所有标签,因此处理程序会与每个标签挂钩。

  6. 填写其余代码。

    /// <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;
    
            clickedLabel.ForeColor = Color.Black;
        }
     }
    

注意

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

选择“调试”>“开始调试”以运行程序。 您应该看到一个背景为蓝色的空窗体。 选择窗体中的任意单元格。 其中一个图标应可见。 继续在窗体中选择不同位置。 当选择图标时,它们应显示。

Screenshot shows the Matching Game with a single icon visible.

后续步骤

请继续学习下一教程,了解如何使用计时器更改标签。