次の方法で共有


チュートリアル: 数学クイズ WinForms アプリにタイマーを追加する

この 4 つのチュートリアルシリーズでは、数学クイズを作成します。 クイズには、クイズの受験者が指定された時間内に答えようとする 4 つのランダムな数学問題が含まれています。

クイズでは Timer コントロールを使用します。 このコントロールの背後にあるコードは、経過時間を追跡し、クイズの受け取り側の回答を確認します。

この 3 番目のチュートリアルでは、次の方法を学習します。

  • タイマー コントロールを追加します。
  • タイマーのイベント ハンドラーを追加します。
  • ユーザーの回答を確認し、メッセージを表示し、正しい回答を入力するコードを記述します。

前提 条件

このチュートリアルは、計算クイズ WinForms アプリを作成するから始まる、前のチュートリアルに基づいています。 これらのチュートリアルを完了していない場合は、まず通してやってみてください。

カウントダウン タイマーを追加する

クイズ中の時間を追跡するには、タイマー コンポーネントを使用します。 また、残りの時間を格納する変数も必要です。

  1. 前のチュートリアルで変数 宣言したのと同じ方法で、timeLeft という名前の整数変数を追加します。 他の宣言の直後に、timeLeft 宣言を配置します。 コードは次のサンプルのようになります。

    public partial class Form1 : Form
    {
        // Create a Random object called randomizer 
        // to generate random numbers.
        Random randomizer = new Random();
    
        // These integer variables store the numbers 
        // for the addition problem. 
        int addend1;
        int addend2;
    
        // These integer variables store the numbers 
        // for the subtraction problem. 
        int minuend;
        int subtrahend;
    
        // These integer variables store the numbers 
        // for the multiplication problem. 
        int multiplicand;
        int multiplier;
    
        // These integer variables store the numbers 
        // for the division problem. 
        int dividend;
        int divisor;
    
        // This integer variable keeps track of the 
        // remaining time.
        int timeLeft;
    

  1. Windows フォーム デザイナーで、ツールボックス の [コンポーネント] カテゴリからフォームに Timer コントロールを移動します。 コントロールは、デザイン ウィンドウの下部にある灰色の領域に表示されます。

  2. フォームで、追加した timer1 アイコンを選択し、その Interval プロパティを 1000に設定します。 この間隔はミリ秒単位であるため、値が 1000 の場合、タイマーは 1 秒ごとに Tick イベントを発生させます。

回答を確認する

タイマーは 1 秒ごとに Tick イベントを発生させるので、Tick イベント ハンドラーで経過時間を確認するのが理にかなっています。 また、そのイベント ハンドラーで回答を確認することも実用的です。 時間がなくなった場合、または回答が正しい場合は、クイズが終了します。

そのイベント ハンドラーを記述する前に、CheckTheAnswer() というメソッドを追加して、数学の問題に対する回答が正しいかどうかを判断します。 このメソッドは、StartTheQuiz()などの他のメソッドと一緒に配置する必要があります。 コードは次のサンプルのようになります。

/// <summary>
/// Check the answers to see if the user got everything right.
/// </summary>
/// <returns>True if the answer's correct, false otherwise.</returns>
private bool CheckTheAnswer()
{
    if ((addend1 + addend2 == sum.Value)
        && (minuend - subtrahend == difference.Value)
        && (multiplicand * multiplier == product.Value)
        && (dividend / divisor == quotient.Value))
        return true;
    else
        return false;
}

このメソッドは、数学の問題に対する回答を決定し、結果を NumericUpDown コントロールの値と比較します。 このコードでは、次の操作を行います。

  • Visual Basic バージョンでは、通常の Sub キーワードではなく Function キーワードが使用されます。このメソッドは値を返します。

  • キーボードを使用して乗算記号 (×) と除算記号 (÷) を簡単に入力することはできません。そのため、C# と Visual Basic では乗算にアスタリスク (*) を、除算にはスラッシュ (/) を使用します。

  • C# では、&&logical and 演算子です。 Visual Basic では、同等の演算子は AndAlsological and 演算子を使用して、複数の条件が true かどうかを確認します。 この場合、値がすべて正しい場合、メソッドは trueの値を返します。 それ以外の場合、メソッドは falseの値を返します。

  • if ステートメントは、NumericUpDown コントロールの Value プロパティを使用して、コントロールの現在の値にアクセスします。 次のセクションでは、同じプロパティを使用して、各コントロールに正しい回答を表示します。

タイマーにイベント ハンドラーを追加する

これで回答を確認する方法が得たので、Tick イベント ハンドラーのコードを記述できます。 このコードは、タイマーが Tick イベントを発生した後、1 秒ごとに実行されます。 このイベント ハンドラーは、CheckTheAnswer()を呼び出してクイズの受け取り側の回答を確認します。 また、クイズで経過した時間も確認します。

  1. フォームで、Timer コントロールをダブルクリックするか、またはコントロールを選択してから[Enter]を押します。 これらのアクションは、Tick イベント ハンドラーを追加します。 コード エディターが表示され、Tick ハンドラーのメソッドが表示されます。

    C# では、イベント ハンドラーをフックするコード行が Form1.Designer.cs コード ファイルに追加されます。

    timer1.Tick += new EventHandler(timer1_Tick);
    

    (Visual Basic の場合、その行は必要ありませんが、イベント ハンドラーには同じことを行う handles Timer1.Tick が含まれています)。

  2. 新しいイベント ハンドラー メソッドに次のステートメントを追加します。

    private void timer1_Tick(object sender, EventArgs e)
    {
        if (CheckTheAnswer())
        {
            // If CheckTheAnswer() returns true, then the user 
            // got the answer right. Stop the timer  
            // and show a MessageBox.
            timer1.Stop();
            MessageBox.Show("You got all the answers right!",
                            "Congratulations!");
            startButton.Enabled = true;
        }
        else if (timeLeft > 0)
        {
            // If CheckTheAnswer() returns false, keep counting
            // down. Decrease the time left by one second and 
            // display the new time left by updating the 
            // Time Left label.
            timeLeft = timeLeft - 1;
            timeLabel.Text = timeLeft + " seconds";
        }
        else
        {
            // If the user ran out of time, stop the timer, show
            // a MessageBox, and fill in the answers.
            timer1.Stop();
            timeLabel.Text = "Time's up!";
            MessageBox.Show("You didn't finish in time.", "Sorry!");
            sum.Value = addend1 + addend2;
            difference.Value = minuend - subtrahend;
            product.Value = multiplicand * multiplier;
            quotient.Value = dividend / divisor;
            startButton.Enabled = true;
        }
    }
    

クイズの 1 秒ごとに、このメソッドが実行されます。 コードは、最初に、CheckTheAnswer() が返す値を確認します。

  • すべての回答が正しい場合、その値は trueされ、クイズは終了します。

    • タイマーが停止します。
    • お祝いのメッセージが表示されます。
    • startButton コントロールの Enabled プロパティは、クイズの受験者が別のクイズを開始できるように true に設定されます。
  • CheckTheAnswer()falseを返す場合、コードは timeLeft の値をチェックします。

    • この変数が 0 より大きい場合、タイマーは timeLeft から 1減算します。 また、timeLabel コントロールの Text プロパティを更新して、残りの秒数をクイズの受け取り人に表示します。
    • 時間が残っていない場合、タイマーは停止し、timeLabel テキストが 時間切れ! に変更されます。クイズが終わったことをメッセージボックスで知らせ、回答が表示されます。 スタート ボタンが再び使用可能になります。

タイマーを開始する

クイズの開始時にタイマーを開始するには、次の例に示すように、StartTheQuiz() メソッドの末尾に 3 行を追加します。

/// <summary>
/// Start the quiz by filling in all of the problem 
/// values and starting the timer. 
/// </summary>
public void StartTheQuiz()
{
    // Fill in the addition problem.
    // Generate two random numbers to add.
    // Store the values in the variables 'addend1' and 'addend2'.
    addend1 = randomizer.Next(51);
    addend2 = randomizer.Next(51);

    // Convert the two randomly generated numbers
    // into strings so that they can be displayed
    // in the label controls.
    plusLeftLabel.Text = addend1.ToString();
    plusRightLabel.Text = addend2.ToString();

    // 'sum' is the name of the NumericUpDown control.
    // This step makes sure its value is zero before
    // adding any values to it.
    sum.Value = 0;

    // Fill in the subtraction problem.
    minuend = randomizer.Next(1, 101);
    subtrahend = randomizer.Next(1, minuend);
    minusLeftLabel.Text = minuend.ToString();
    minusRightLabel.Text = subtrahend.ToString();
    difference.Value = 0;

    // Fill in the multiplication problem.
    multiplicand = randomizer.Next(2, 11);
    multiplier = randomizer.Next(2, 11);
    timesLeftLabel.Text = multiplicand.ToString();
    timesRightLabel.Text = multiplier.ToString();
    product.Value = 0;

    // Fill in the division problem.
    divisor = randomizer.Next(2, 11);
    int temporaryQuotient = randomizer.Next(2, 11);
    dividend = divisor * temporaryQuotient;
    dividedLeftLabel.Text = dividend.ToString();
    dividedRightLabel.Text = divisor.ToString();
    quotient.Value = 0;

    // Start the timer.
    timeLeft = 30;
    timeLabel.Text = "30 seconds"; 
    timer1.Start();
}

クイズが開始されると、このコードは timeLeft 変数を 30 に設定し、timeLabel コントロールの Text プロパティを 30 秒に設定します。 次に、Timer コントロールの Start() メソッドがカウントダウンを開始します。

アプリを実行する

  1. プログラムを保存して実行します。

  2. [Start the quiz] を選択します。 タイマーがカウントダウンを開始します。 時間がなくなると、クイズが終了し、回答が表示されます。

  3. 別のクイズを開始し、数学の問題に対する正しい答えを提供します。 制限時間内に正しく応答すると、メッセージ ボックスが開き、開始ボタンが使用可能になり、タイマーが停止します。

    残り 19 秒で完了したクイズを示すスクリーンショット。[テストの開始] ボタンが表示されます。

次の手順

次のチュートリアルに進み、数学クイズをカスタマイズする方法を学習してください。