タイムラグについて

解決


岩田  2009-03-22 19:04:22  No: 141710

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 19:47:33  No: 141711

> 文字を入力し、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 21:46:08  No: 141712

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

  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 22:23:20  No: 141713

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 22:39:03  No: 141714

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

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 23:52:35  No: 141715

大前提として、こういうときに「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-23 02:38:10  No: 141716

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


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加