4

我是 OOP 和 C# 的初学者。

我正在使用 Windows 窗体开发问答游戏。我的问题与两个类有关,形式游戏逻辑。我有一个带有经典 Froms 控件的基本 UI。看一看。

界面布局

我想要实现的是,当玩家按下任何答案按钮时,它会用红色或绿色突出显示按下的按钮,具体取决于答案是对还是错。更改颜色后,我希望程序等待一段时间,然后转到下一个问题。

问题是,我不知道如何正确实现这一目标。我不知道如何使用线程以及 Form 应用程序如何与线程相关。我应该使用线程睡眠、定时器还是异步?

我将向您展示应该处理此问题的游戏逻辑类中的方法。

public static void Play(char answer) //Method gets a char representing a palyer answer
    {
        if (_rightAnswer == answer) //If the answer is true, the button should become green
        {
            Program.MainWindow.ChangeBtnColor(answer, System.Drawing.Color.LightGreen);
            _score++;
        }
        else //Otherwise the button becomes Red
        {
            Program.MainWindow.ChangeBtnColor(answer, System.Drawing.Color.Red);
        }

        //SLEEP HERE

        if (!(_currentIndex < _maxIndex)) //If it is the last question, show game over
        {
            Program.MainWindow.DisplayGameOver(_score);
        }
        else //If it is not the last question, load next question and dispaly it and finally change the button color to default
        {
            _currentIndex++;
            _currentQuestion = Database.ListOfQuestions.ElementAt(_currentIndex);
            _rightAnswer = _currentQuestion.RightAnswer;
            Program.MainWindow.DisplayStats(_score, _currentIndex + 1, _maxIndex + 1);
            Program.MainWindow.DisplayQuestion(_currentQuestion.Text);
            Program.MainWindow.DisplayChoices(_currentQuestion.Choices);
        }
        Program.MainWindow.ChangeBtnColor(answer, System.Drawing.SystemColors.ControlLight);
    }

我不想完全阻止 UI,但我也不希望用户在暂停期间通过按其他按钮来进行其他事件。因为这会导致应用程序运行不正常。

4

4 回答 4

3

如果程序真的很简单,并且您不想实现线程,我建议使用 Timer。单击回答按钮时只需启动您的计时器。您的计时器应该包含在一段时间后自行停止并执行其他所需操作的功能(例如选择另一个问题)。

于 2015-12-12T14:16:36.880 回答
2

一旦用户选择了答案,您就可以禁用所有按钮,这样他们就不能按其他任何东西了。

然后启动一个计时器,这样您就不会阻塞 UI。计时器基本上是一个线程,但会为您处理所有线程,因此您不必担心这方面的问题。

当计时器达到所需的延迟时,停止它并触发一个事件以选择下一个问题。

于 2015-12-12T14:17:26.147 回答
0

在 //SLEEP HERE 添加这行代码

Timer timer = new Timer(new TimerCallback(timerCb), null, 2000, 0);

2000 是毫秒,是等待时间,timerCb 是回调方法。

同样在此禁用所有按钮,以便不会生成新事件。

private void timerCb(object state)
    {
        Dispatcher.Invoke(() =>
        {
            label1.Content = "Foo!";              
        });
    }

你可以在回调中做任何你想做的事情,但是如果你做的事情会改变 UI 中的任何东西,你需要像我改变标签内容一样使用 Dispatcher。

于 2015-12-12T14:32:29.570 回答
0

由于以下原因,在 GUI 场景中暂停执行非常容易await

await Task.Delay(2000);

这不会阻止 UI。

您应该研究什么await以及如何使用它。如果您从未听说过它并且正在编写 WinForms,那么您做错了什么。

不需要计时器或线程。没有回调,没有Invoke

于 2015-12-12T14:40:25.627 回答