You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# WinForms:如何在初始化前操作单个Label并实现类Word Connect游戏

Word Connect类游戏开发问题解决方案

一、Label操作模块化与初始化前处理

你的代码目前存在逻辑耦合度高、OnPaint重复创建控件的问题,通过以下方式实现模块化,避免重复代码:

  1. 统一管理所有字母Label
    在Form类中添加集合字段,用来存储所有创建的字母Label,后续操作无需逐个查找控件:
List<Label> letterLabels = new List<Label>();
int[] selectedletters; // 将原来的局部变量改为类字段,方便跨方法使用
  1. 重构AddLabel方法
    让方法返回创建的Label,并自动添加到管理集合中,同时绑定点击事件为后续拼单词做准备:
private Label AddLabel(string msg, int x, int y, string labelName)
{
    Label lbl = new Label();
    lbl.Location = new Point(x, y);
    lbl.Size = new Size(50, 50);
    lbl.BackColor = Color.Transparent;
    lbl.BorderStyle = BorderStyle.FixedSingle;
    lbl.Text = msg;
    lbl.TextAlign = ContentAlignment.MiddleCenter;
    lbl.Font = new Font("Colonna MT", 12);
    lbl.Name = labelName;
    lbl.Click += LetterLabel_Click; // 绑定点击事件
    this.Controls.Add(lbl);
    letterLabels.Add(lbl);
    return lbl;
}
  1. 拆分初始化逻辑
    将原来分散在构造函数、OnPaint中的代码拆分为独立方法,避免OnPaint重复执行导致控件叠加:
public Form1()
{
    InitializeComponent();
    InitializeGame(); // 初始化游戏逻辑
}

// 统一初始化入口
private void InitializeGame()
{
    LoadWordList();
    if (wordList.Count == 0)
    {
        MessageBox.Show("单词库中没有找到5个字母的单词");
        return;
    }
    GenerateGameLetters();
    CreateLetterLabels();
}

// 加载单词列表
private void LoadWordList()
{
    wordList.Clear();
    using (StreamReader file = new StreamReader("words.txt"))
    {
        string word;
        while ((word = file.ReadLine()) != null)
        {
            if (word.Length == 5)
            {
                wordList.Add(word.ToLower()); // 统一转小写,避免大小写判断问题
            }
        }
    }
}

// 生成游戏字母与目标单词
private void GenerateGameLetters()
{
    bool vowelAdded = false;
    int[] vowels = { 0,4,8,14,20 };
    int totalLetters = 5;
    selectedletters = new int[totalLetters];

    for (int i = 0; i < totalLetters; i++)
    {
        int letternum;
        if (!vowelAdded && (i == totalLetters - 1 || rnd.Next(0, 2) == 0))
        { 
            letternum = vowels[rnd.Next(0,vowels.Length)];
            vowelAdded = true;
        }
        else
        {
            letternum = rnd.Next(0, alphabet.Length);
            if (vowelchecker(letternum))
            {
                vowelAdded = true;
            }
        }
        selectedletters[i] = letternum;
    }

    HashSet<char> selectedLettersSet = new HashSet<char>();
    foreach (int letterIndex in selectedletters)
    {
        selectedLettersSet.Add(alphabet[letterIndex][0]); 
    }

    List<string> validWords = wordList.Where(word => word.All(letter => selectedLettersSet.Contains(letter))).ToList();

    if (validWords.Count == 0)
    {
        MessageBox.Show("无法生成有效单词,请重新开始");
        return;
    }

    allCharacters.Clear();
    Array.Clear(newword, 0, newword.Length);
    for (int i = 0; i < 3; i++)
    {
        int wordnumchoose = rnd.Next(0, validWords.Count);
        newword[i] = validWords[wordnumchoose];
        allCharacters.AddRange(newword[i].ToCharArray());
    }
    characters = allCharacters.ToArray();
}

// 创建所有字母Label
private void CreateLetterLabels()
{
    // 清空旧Label,避免重复创建
    foreach (var lbl in letterLabels)
    {
        this.Controls.Remove(lbl);
    }
    letterLabels.Clear();
    labelcounter = 1;

    // 创建轮盘周围的字母Label
    int xxx = 500;
    int yyy = 375;
    int j = 1;
    for (int i = 0; i < selectedletters.Length; i++)
    {
        AddLabel(alphabet[selectedletters[i]], xxx, yyy, "label_" + labelcounter);
        labelcounter++;
       
        if (i <= 1) xxx += 100;
        if (j >= 2)
        {
            yyy += 75;
            xxx = 475; // 调整坐标避免位置错乱
            j = 0;
        }
        if (i == 2) xxx += 150;
        if (i >= 3)
        {
            xxx = 400;
            yyy = 500;
            xxx += i ==3 ? 150 : 0;
        }
        j++;
    }

    // 创建底部字母Label
    int xx = 400;
    int yy = 100;
    for (int i = 0; i < characters.Length; i++)
    {
        AddLabel(characters[i].ToString(), xx, yy, "label_" + labelcounter);
        labelcounter++;
        xx += 50;
        if (xx > 600)
        {
            yy += 100;
            xx = 400;
        }
    }
}
  1. 简化OnPaint方法
    OnPaint只负责绘制椭圆,不再创建控件:
protected override void OnPaint(PaintEventArgs e)
{
    base.OnPaint(e);
    DrawEllipseInt(e);
}

二、实现字母拼接单词功能

通过Label点击事件实现字母拼接,并验证是否为目标单词:

  1. 添加类字段记录当前拼接状态
private string currentWord = "";
// 在UI中添加一个Label(命名为lblCurrentWord)用于显示当前拼接的单词
  1. 实现Label点击事件
private void LetterLabel_Click(object sender, EventArgs e)
{
    Label clickedLabel = sender as Label;
    if (clickedLabel == null) return;

    // 拼接字母
    currentWord += clickedLabel.Text;
    lblCurrentWord.Text = currentWord;

    // 检查是否达到单词长度(5个字母)
    if (currentWord.Length == 5)
    {
        CheckCurrentWord();
    }
}

// 验证单词是否有效
private void CheckCurrentWord()
{
    string lowerWord = currentWord.ToLower();
    if (newword.Contains(lowerWord))
    {
        MessageBox.Show($"找到有效单词:{currentWord}");
        // 移除已找到的单词
        List<string> tempWords = newword.ToList();
        tempWords.Remove(lowerWord);
        newword = tempWords.ToArray();

        // 所有单词找到后触发胜利
        if (newword.Length == 0)
        {
            MessageBox.Show("恭喜!所有单词都已找到!");
            InitializeGame(); // 重新开始游戏
        }
    }
    else
    {
        MessageBox.Show("该单词无效,请重试");
    }
    // 清空当前拼接内容
    currentWord = "";
    lblCurrentWord.Text = "";
}
  1. 添加清空功能(可选)
    在UI中添加Button(命名为btnClear),点击清空当前拼接的单词:
private void btnClear_Click(object sender, EventArgs e)
{
    currentWord = "";
    lblCurrentWord.Text = "";
}

内容的提问来源于stack exchange,提问作者user29004752

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 05:02:01