[英]Having a problem with my Reaction Time test in C# (Windows Forms)
作為 C# 的新手,我從 1 月份才真正開始使用這種語言進行編碼。 對於我的課程作業,我必須創建一個包含反應時間測試的程序。 我花了大約一周的時間才完全理解代碼應該如何工作,這是我迄今為止所做的:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Timers;
using System.Threading;
using System.Diagnostics;
namespace WonderWallsApplication
{
public partial class ReactionTimeTestForm : Form
{
Random random = new Random();
Stopwatch stopwatch = new Stopwatch();
int TimesTested = 0;
int ReactionTime1 = 0;
int ReactionTime2 = 0;
int ReactionTime3 = 0;
bool ButtonPressed = false;
int ReactionTime { get; set; }
public ReactionTimeTestForm()
{
InitializeComponent();
btnReactionButton.BackColor = Color.Red;
}
private void button1_Click(object sender, EventArgs e)
{
}
public void button1_Click_1(object sender, EventArgs e)
{
if (TimesTested == 0)
{
ReactionTest();
if (ButtonPressed == true)
{
ReactionTime1 = ReactionTime;
TimesTested = TimesTested + 1;
ButtonPressed = false;
}
else
{
}
}
else if (TimesTested == 1)
{
ReactionTest();
if (ButtonPressed == true)
{
ReactionTime2 = ReactionTime;
TimesTested = TimesTested + 1;
ButtonPressed = false;
}
else
{
}
}
else if (TimesTested == 2)
{
ReactionTest();
if (ButtonPressed == true)
{
ReactionTime3 = ReactionTime;
TimesTested = TimesTested + 1;
ButtonPressed = false;
}
else
{
}
}
else if (TimesTested == 3)
{
MessageBox.Show("Your times were: " + Convert.ToString(ReactionTime1) + ", " + Convert.ToString(ReactionTime2) + ", " + Convert.ToString(ReactionTime3));
}
else
{
}
}
public void btnReactionButton_Click(object sender, EventArgs e)
{
stopwatch.Stop();
btnReactionButton.BackColor = Color.Red;
btnReactionButton.Text = "Your time was " + stopwatch.ElapsedMilliseconds+ "ms milliseconds";
ReactionTime = Convert.ToInt32(stopwatch.ElapsedMilliseconds);
ButtonPressed = true;
}
public void ReactionTest()
{
stopwatch.Reset();
btnReactionButton.Text = "3";
Task.Delay(1000).Wait();
btnReactionButton.Text = "2";
Task.Delay(1000).Wait();
btnReactionButton.Text = "1";
Task.Delay(1000).Wait();
btnReactionButton.Text = "0";
Task.Delay(1000).Wait();
btnReactionButton.Text = "Press this button when it turns green";
Task.Delay(random.Next(3000, 10000)).Wait();
btnReactionButton.Visible = true;
stopwatch.Start();
btnReactionButton.BackColor = Color.Green;
btnReactionButton.Text = "Click Now!";
}
}
}
我的問題是,當我運行我的代碼時,它運行了 4 次反應時間測試而不是 3 次。 它確實記錄了所有 3 個 FIRST 值,但出於某種原因,我寫了一些可能會導致它再次運行的內容。 調試程序,我覺得和第一次有關系,會記錄時間,但不會算按一次。 老實說,我不知道如何解決這個問題。 希望你們中的一個可以。 我對測試時間的每個 if 語句進行了更改,以添加測試時間。 例如:
if (TimesTested == 0)
{
ReactionTest();
TimesTested = TimesTested + 1;
if (ButtonPressed == true)
{
ReactionTime1 = ReactionTime;
ButtonPressed = false;
}
else
{
}
}
但這只是它執行了 3 次測試,但它輸出“你的時間是 0,x,x”。 X 只是記錄的反應速度的數字。
我努力遵循你的邏輯。 這是您的代碼的更簡單版本:
Random random = new Random();
Stopwatch stopwatch = new Stopwatch();
List<long> timesTested = new List<long>();
private void buttonStart_Click(object sender, EventArgs e) {
stopwatch.Reset();
for (int i = 4; i > 0; --i) {
btnReactionButton.Text = i.ToString();
Task.Delay(500).Wait();
btnReactionButton.Invalidate();
}
btnReactionButton.Text = "Press this button when it turns green";
Task.Delay(random.Next(3000, 5000)).Wait();
stopwatch.Start();
btnReactionButton.BackColor = Color.Green;
btnReactionButton.Text = "Click Now!";
}
private void btnReactionButton_Click(object sender, EventArgs e) {
if (stopwatch.IsRunning) {
stopwatch.Stop();
timesTested.Add(stopwatch.ElapsedMilliseconds);
btnReactionButton.BackColor = Color.Red;
btnReactionButton.Text = string.Format("Your time was {0} milliseconds",
timesTested[timesTested.Count - 1]);
if (timesTested.Count == 3) {
MessageBox.Show("Your times were: " + String.Join(", ", timesTested.ToArray()));
}
}
}
不過,您的程序確實存在重大缺陷。 用戶可以在停止按鈕變為綠色之前單擊停止按鈕,當按鈕變為綠色時,它將記錄較早的鼠標單擊。 您應該隱藏按鈕或禁用它,直到反應准備就緒。
ReactionTest()
方法在按鈕背景變為綠色並且標簽變為“立即單擊!”后立即返回。 在第一次檢查ButtonPressed
標志之前,在第一次ReactionTest()
調用之后,用戶沒有機會單擊按鈕 - 因為檢查發生而無需等待(對於用戶輸入)。 所以你是對的,第一次點擊沒有被計算在內。 這就是為什么允許另外 3 次嘗試的原因。
簡單的解決方案是將大部分代碼從button1_Click_1()
到btnReactionButton_Click()
並將async/await
添加到ReactionTest()
以防止它阻塞 UI 並將btnReactionButton
單擊事件排隊,這在ReactionTest()
時會錯誤地計為有效點擊ReactionTest()
返回。 ButtonPressed
標志是不必要的。
public void button1_Click_1(object sender, EventArgs e)
{
if (TimesTested < 3)
{
ReactionTest();
}
else
{
MessageBox.Show("Your times were: " + Convert.ToString(ReactionTime1) + ", " + Convert.ToString(ReactionTime2) + ", " + Convert.ToString(ReactionTime3));
}
}
public void btnReactionButton_Click(object sender, EventArgs e)
{
btnReactionButton.Enabled = false;
stopwatch.Stop();
btnReactionButton.BackColor = Color.Red;
btnReactionButton.Text = "Your time was " + stopwatch.ElapsedMilliseconds + "ms milliseconds";
ReactionTime = Convert.ToInt32(stopwatch.ElapsedMilliseconds);
if (TimesTested == 0)
{
ReactionTime1 = ReactionTime;
TimesTested = TimesTested + 1;
}
else if (TimesTested == 1)
{
ReactionTime2 = ReactionTime;
TimesTested = TimesTested + 1;
}
else if (TimesTested == 2)
{
ReactionTime3 = ReactionTime;
TimesTested = TimesTested + 1;
}
}
public async void ReactionTest()
{
stopwatch.Reset();
btnReactionButton.Text = "3";
await Task.Delay(1000);
btnReactionButton.Text = "2";
await Task.Delay(1000);
btnReactionButton.Text = "1";
await Task.Delay(1000);
btnReactionButton.Text = "0";
await Task.Delay(1000);
btnReactionButton.Text = "Press this button when it turns green";
await Task.Delay(random.Next(3000, 10000));
btnReactionButton.Visible = true;
stopwatch.Start();
btnReactionButton.BackColor = Color.Green;
btnReactionButton.Text = "Click Now!";
btnReactionButton.Enabled = true;
}
根據@LarsTech 給出的提示,我在適當的時候添加了禁用按鈕。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.