タイムラグについて

解決


岩田  2009-03-22 10:04:22  No: 141710  IP: [192.*.*.*]

VB2008です
1から10までの数を入力して,
あっていれば「当たり」はずれたときは「残念」と表示する
プログラムです。
文字を入力し、Xの値が出てから2秒くらいたったから「当たり」などの
表示をさせたいのですが、それらが同時にでてしまいます。
どのようにしたらタイムラグを発生させることができるのかな?

 Randomize()
        Dim X As Integer

        X = Int(Rnd() * 10) + 1

        Dim pn As Integer
        pn = InputBox("1〜10までの数を入力してください")
        
        Select pn
            Case Is < 0
                MessageBox.Show("1〜10までの数を入力してください")
            Case Is > 10
                MessageBox.Show("1〜10までの数を入力してください")
            Case Is = X

                Label1.Text = X.ToString()
                Label2.Text = pn.ToString()
                Threading.Thread.Sleep(3000)

                MessageBox.Show("当たり")
            Case Else

                Label1.Text = X.ToString()
                Label2.Text = pn.ToString()
                Threading.Thread.Sleep(3000)

                MessageBox.Show("残念")
        End Select

編集 削除
魔界の仮面弁士  2009-03-22 10:47:33  No: 141711  IP: [192.*.*.*]

> 文字を入力し、Xの値が出てから2秒くらいたったから「当たり」などの
> 表示をさせたいのですが、それらが同時にでてしまいます。

一覧の処理を、ひとつの Sub プロシージャの中で行っているからかと。

「入力させる処理」と「表示させる処理」とは、別のタイミングで
行わせたい処理なのですから、それらは 2 つの処理に分けてください。


> どのようにしたらタイムラグを発生させることができるのかな?

Timer コントロールを使ってみてください。

「文字を入力させる処理」を行った後、Timer を起動するようにします。
そして、Timer の Tick イベントの処理では、当たりなどの表示を
行った後、その Timer を停止させてやれば OK です。


Timer の使い方については、下記を参考にしてみてください。
http://www.microsoft.com/Japan/msdn/archive/student/challenge/chap4_vb/default.aspx

編集 削除
岩田  2009-03-22 12:46:08  No: 141712  IP: [192.*.*.*]

う〜ん。これではおかしなことになってしまうのですが


  Dim X As Integer

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Randomize()


        X = Int(Rnd() * 10) + 1

        Dim pn As Integer
        pn = InputBox("1〜10までの数を入力してください")
        
        Select pn
            Case Is < 0
                MessageBox.Show("1〜10までの数を入力してください")
            Case Is > 10
                MessageBox.Show("1〜10までの数を入力してください")
            Case Is = X

                Label1.Text = pn.ToString()
                
               
                Timer1.Start()

                

            Case Else

                Label1.Text = pn.ToString()




               
                Timer2.Start()
                


        End Select






    End Sub

     
    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick

        Label2.Text = X.ToString()

        MessageBox.Show("当たり")
        Timer1.Stop()
    End Sub

    Private Sub Timer2_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer2.Tick
        Label2.Text = X.ToString()

        MessageBox.Show("残念")
        Timer2.Stop()

    End Sub
End Class

編集 削除
岩田  2009-03-22 13:23:20  No: 141713  IP: [192.*.*.*]

Public Class Form1
    Dim X As Integer

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Randomize()
こんな感じでいいのでしょうか?

        X = Int(Rnd() * 10) + 1

        Dim pn As Integer
        pn = InputBox("1〜10までの数を入力してください")
        
        Select pn
            Case Is < 0
                MessageBox.Show("1〜10までの数を入力してください")
            Case Is > 10
                MessageBox.Show("1〜10までの数を入力してください")
            Case Is = X

                Label1.Text = pn.ToString()

                Timer1.Start()

                

            Case Else

                Label1.Text = pn.ToString()

                Timer2.Start()
                


        End Select






    End Sub

       
    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        
Threading.Thread.Sleep(1000)

        Timer1.Stop()
        Label2.Text = X.ToString()

        MessageBox.Show("当たり")

    End Sub

    Private Sub Timer2_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer2.Tick
       
 Threading.Thread.Sleep(1000)


        Timer2.Stop()

        Label2.Text = X.ToString()

        MessageBox.Show("残念")
        
    End Sub
End Class

編集 削除
岩田  2009-03-22 13:39:03  No: 141714  IP: [192.*.*.*]

何度もすみません。これでいいのでしょうか。
いちおう考えた通りの動きはしていますが

Public Class Form1
    Dim X As Integer

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Randomize()




        X = Int(Rnd() * 10) + 1

        Dim pn As Integer
        Label1.Text = ""
        Label2.Text = ""

        pn = InputBox("1〜10までの数を入力してください")
        
        Select pn
            Case Is < 0
                MessageBox.Show("1〜10までの数を入力してください")
            Case Is > 10
                MessageBox.Show("1〜10までの数を入力してください")
            Case Is = X

                Label1.Text = pn.ToString()

                Timer1.Start()


            Case Else

                Label1.Text = pn.ToString()
                Timer2.Start()

        End Select

    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    End Sub

    
    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick

        Threading.Thread.Sleep(1000)
        Timer1.Stop()
        Label2.Text = X.ToString()
        MessageBox.Show("当たり")

    End Sub

    Private Sub Timer2_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer2.Tick

        Threading.Thread.Sleep(1000)
        Timer2.Stop()
        Label2.Text = X.ToString()
        MessageBox.Show("残念")
        
    End Sub
End Class

編集 削除
魔界の仮面弁士  2009-03-22 14:52:35  No: 141715  IP: [192.*.*.*]

大前提として、こういうときに「Sleep を使ってはいけません」。


Sleep の発動中は、あらゆる処理が完全に停止します。画面の再描画も
行われませんし、マウスやキーボードからの操作も受け付けなくなります。

OS からのメッセージも処理できなくなり、いわゆる「応答なし」の
状態となってしまうため、たとえ短時間であっても、メインスレッドから
Thread.Sleep() を呼ぶ事は避けるべきです。


今回の場合、Timer 自体が遅延実行の役目を果たしますから、
そこに Sleep を 加える必要はありません。Timer だけで十分かと。

たとえば、こんな感じですね。


Private X, pn As Integer

Sub Form1_Load(…
  Timer1.Interval = 2000  '2秒間
End Sub

Sub Button1_Click(…
  '乱数をセット
  Dim R As New Random()
  X = R.Next(1, 11)  '1 以上 11 未満の整数を返す。

  ' 画面の初期化
  Label1.Text = ""
  Label2.Text = ""

  ' 値を入力してもらう
  Dim pn As Integer
  Dim S As String = InputBox("1〜10までの数を入力してください")
  If S = "" Then
    MessageBox.Show("キャンセルされました。")
  ElseIf Integer.TryParse(S, pn) = False OrElse (pn < 0) OrElse (pn > 10) Then
    MessageBox.Show("1〜10までの数しか入力できません")
  Else
    ' 1〜10 の数が入力されたら、タイマーを起動
    Button1.Enabled = False  ' ボタンを使用禁止にして、連続して押されないようにする
    Label1.Text = pn.ToString()
    Timer1.Start()  ' タイマーを起動(2 秒後に Tick イベントが発生する)
  End If

End Sub

Sub Timer1_Tick(…
  Timer1.Stop()  ' タイマーを止める
  Label2.Text = X.ToString()
  MessageBox.Show( If(pn = X, "当たり", "残念") )
  Button1.Enabled = True  ' もう一度できるよう、ボタンを元に戻す
End Sub

編集 削除
岩田  2009-03-22 17:38:10  No: 141716  IP: [192.*.*.*]

コードまで書いていただき感謝、感謝です。
VBは、なかなか進歩しませんが、今後ともよろしくお願いします。
ありがとうございました。m(_ _)m

編集 削除