C# Winform翻牌子记忆小游戏

效果

源码

新建一个winform项目命名为Matching Game,选用.net core 6框架

并把Form1.cs代码修改为

cs 复制代码
using Timer = System.Windows.Forms.Timer;

namespace Matching_Game
{
    public partial class Form1 : Form
    {
        private const int row = 4;
        private const int col = 4;
        private TableLayoutPanel panel = new()
        {
            RowCount = row,
            ColumnCount = col,
        };
        private Label[,] labels = new Label[row, col];

        private readonly Random random = new();

        private readonly List<string> icons = new()
        {
            "!", "!", "N", "N", ",", ",", "k", "k",
            "b", "b", "v", "v", "w", "w", "z", "z"
        };

        private readonly Timer timer = new()
        {
            Interval = 750,
        };

        private Label? firstClicked = null;
        private Label? secondClicked = null;

        public Form1()
        {
            InitializeComponent();

            InitializeControls();
            timer.Tick += Timer_Tick;

            AssignIconsToSquares();

        }

        /// <summary>
        /// 窗体和它的子窗体都开启双缓冲,防止重新开始游戏时重新绘制控件闪屏
        /// </summary>
        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x02000000;
                return cp;
            }
        }

        /// <summary>
        /// 初始化控件
        /// </summary>
        public void InitializeControls()
        {
            #region initialize form
            Text = "Matching Game";
            Size = new Size(550, 550);
            StartPosition = FormStartPosition.CenterScreen;
            Controls.Clear();
            #endregion

            #region initialize panel
            panel.BackColor = Color.CornflowerBlue;
            for (int i = 0; i < row; i++)
            {
                panel.RowStyles.Add(new RowStyle(SizeType.Percent, 25));
            }
            for (int j = 0; j < col; j++)
            {
                panel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 25));
            }
            panel.Dock = DockStyle.Fill;
            panel.CellBorderStyle = TableLayoutPanelCellBorderStyle.Inset;
            panel.Padding = new Padding(0, 0, 0, 0);
            Controls.Add(panel);
            #endregion

            #region initialize labels
            for (int i = 0; i < row; i++)
            {
                for (int j = 0; j < col; j++)
                {
                    Label label = new()
                    {
                        BackColor = Color.CornflowerBlue,
                        ForeColor = Color.CornflowerBlue,
                        AutoSize = false,
                        Dock = DockStyle.Fill,
                        TextAlign = ContentAlignment.MiddleCenter,
                        Font = new Font("Webdings", 64, FontStyle.Regular),
                        //Font = new Font("Times New Roman", 48, FontStyle.Bold),
                        Margin = new Padding(0, 0, 0, 0)
                    };
                    labels[i, j] = label;
                    label.Click += Label_Click;

                    panel.Controls.Add(label);
                    panel.SetCellPosition(label, new TableLayoutPanelCellPosition(j, i));
                }
            }
            #endregion

        }

        /// <summary>
        /// 定时器任务
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Timer_Tick(object? sender, EventArgs e)
        {
            timer.Stop();

            CheckForWinner();

            if (firstClicked != null)
            {
                firstClicked.ForeColor = firstClicked.BackColor;
            }
            if (secondClicked != null)
            {
                secondClicked.ForeColor = secondClicked.BackColor;
            }

            firstClicked = null;
            secondClicked = null;

        }

        /// <summary>
        /// 标签被点击时触发
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Label_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 (timer.Enabled == true)
                return;

            if (sender is Label clickedLabel)
            {
                // 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 (firstClicked.Text == secondClicked.Text)
                {
                    firstClicked = null;
                    secondClicked = null;
                }

                // 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)
                timer.Start();
            }
        }

        /// <summary>
        /// Assign each icon from the list of icons to a random square
        /// </summary>
        private void AssignIconsToSquares()
        {
            List<string> iList = icons.ToList();
            // 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 panel.Controls)
            {
                if (control is Label iconLabel)
                {
                    int randomNumber = random.Next(iList.Count);
                    iconLabel.Text = iList[randomNumber];
                    // iconLabel.ForeColor = iconLabel.BackColor;
                    iList.RemoveAt(randomNumber);
                }
            }
        }

        /// <summary>
        /// Check every icon to see if it is matched, by 
        /// comparing its foreground color to its background color. 
        /// If all of the icons are matched, the player wins
        /// </summary>
        private void CheckForWinner()
        {
            // Go through all of the labels in the TableLayoutPanel, 
            // checking each one to see if its icon is matched
            foreach (Control control in panel.Controls)
            {
                if (control is Label iconLabel)
                {
                    if (iconLabel.ForeColor == iconLabel.BackColor)
                        return;
                }
            }

            // If the loop didn't return, it didn't find
            // any unmatched icons
            // That means the user won. Show a message and close the form
            DialogResult result = MessageBox.Show("You matched all the icons! Restart?", "Congratulations", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            if (result != DialogResult.Yes)
            {
                Close();
            }
            else
            {
                panel = new TableLayoutPanel() { RowCount = row, ColumnCount = col };
                labels = new Label[row, col];
                InitializeControls();
                AssignIconsToSquares();
            }
        }
    }
}

修改完代码后直接启动即可。

有兴趣可以到微软官网查看相关细节教程:创建匹配游戏 - Visual Studio (Windows) | Microsoft Learn

相关推荐
Ajiang28247353041 小时前
对于C++中stack和queue的认识以及priority_queue的模拟实现
开发语言·c++
幽兰的天空1 小时前
Python 中的模式匹配:深入了解 match 语句
开发语言·python
Theodore_10224 小时前
4 设计模式原则之接口隔离原则
java·开发语言·设计模式·java-ee·接口隔离原则·javaee
----云烟----6 小时前
QT中QString类的各种使用
开发语言·qt
lsx2024066 小时前
SQL SELECT 语句:基础与进阶应用
开发语言
开心工作室_kaic7 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
向宇it7 小时前
【unity小技巧】unity 什么是反射?反射的作用?反射的使用场景?反射的缺点?常用的反射操作?反射常见示例
开发语言·游戏·unity·c#·游戏引擎
武子康7 小时前
Java-06 深入浅出 MyBatis - 一对一模型 SqlMapConfig 与 Mapper 详细讲解测试
java·开发语言·数据仓库·sql·mybatis·springboot·springcloud
九鼎科技-Leo7 小时前
什么是 WPF 中的依赖属性?有什么作用?
windows·c#·.net·wpf
转世成为计算机大神8 小时前
易考八股文之Java中的设计模式?
java·开发语言·设计模式