2015-06-27 82 views
0

我試圖模仿VB Express 2013中的「賽馬」,這暴露了我對線程如何與Windows窗體一起工作的理解上的差距。這個想法是當按下表單上的一個按鈕時,一個藍色方塊和一個紅色方塊(馬)從左到右穿過一個表單(它有一個白色背景)。運動的每個增量應該是(僞)隨機生成的,所以獲勝者應該是不可預測的。在窗體上創建多個獨立的線程

這是我用過的代碼。廣場的移動確實是隨機的,但他們一起移動,而不是獨立的,所以比賽總是一條平行線。如果我只在其中一個線程程序中包含隨機化,它表現得更像是一場比賽,但勝者通常是可預測的。有人能告訴我我錯過了什麼嗎?感謝預期。

Public Class Form1 

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

     Dim t1 As System.Threading.Thread 
     Dim t2 As System.Threading.Thread 

     t1 = New System.Threading.Thread(AddressOf RedHorse) 
     t2 = New System.Threading.Thread(AddressOf BlueHorse) 

     t1.Start() 
     t2.Start() 

    End Sub 

    Public Sub RedHorse() 
     Randomize() 
     Dim G As Graphics 
     G = Me.CreateGraphics 
     Dim bRed As Brush 
     bRed = New SolidBrush(Color.Red) 
     Dim bWhite As Brush 
     bWhite = New SolidBrush(Color.White) 

     Dim x1 As Integer 
     x1 = 100 

     G.FillRectangle(bWhite, x1, 100, 50, 50) 

     Do Until x1 >= 800 
      x1 = x1 + Rnd() 
      G.FillRectangle(bRed, x1, 100, 50, 50) 
      Threading.Thread.Sleep(1) 
      G.FillRectangle(bWhite, x1, 100, 50, 50) 
     Loop 
    End Sub 

    Public Sub BlueHorse() 
     Randomize() 
     Dim G As Graphics 
     G = Me.CreateGraphics 
     Dim bBlue As Brush 
     bBlue = New SolidBrush(Color.Blue) 
     Dim bWhite As Brush 
     bWhite = New SolidBrush(Color.White) 

     Dim x2 As Integer 
     x2 = 100 

     G.FillRectangle(bWhite, x2, 200, 50, 50) 

     Do Until x2 >= 800 
      x2 = x2 + Rnd() 
      G.FillRectangle(bBlue, x2, 200, 50, 50) 
      Threading.Thread.Sleep(1) 
      G.FillRectangle(bWhite, x2, 200, 50, 50) 
     Loop 

    End Sub 

    Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown 

     Dim G As Graphics 
     G = Me.CreateGraphics 
     Dim bRed As Brush 
     bRed = New SolidBrush(Color.Red) 
     Dim bBlue As Brush 
     bBlue = New SolidBrush(Color.Blue) 

     G.FillRectangle(bRed, 100, 100, 50, 50) 
     G.FillRectangle(bBlue, 100, 200, 50, 50) 

    End Sub 
End Class 
+0

除了Randomize問題,我不認爲你可以從線程更新圖形。在線程中進行位置計算並使用計時器以計算位置更新HMI。 – Graffito

回答

0

首先不要使用隨機化,使用隨機類,閱讀這個。基本問題是線程同時啓動,然後在兩個循環之間休眠同一時間。這是您的代碼,只需進行一些更改。

Public Class Form1 

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

     'Me.Width = 1000 'testing 
     isWinner = -1 

     Dim t1 As System.Threading.Thread 
     Dim t2 As System.Threading.Thread 

     t1 = New System.Threading.Thread(AddressOf RedHorse) 
     t2 = New System.Threading.Thread(AddressOf BlueHorse) 

     t1.Start() 
     t2.Start() 

    End Sub 

    Dim prng As New Random 
    Const maxMove As Integer = 21 
    Const maxSleep As Integer = 51 
    Dim isWinner As Integer = -1 

    Public Sub RedHorse() 
     Threading.Thread.Sleep(prng.Next(maxSleep)) 
     Dim G As Graphics 
     G = Me.CreateGraphics 
     Dim bRed As Brush 
     bRed = New SolidBrush(Color.Red) 
     Dim bWhite As Brush 
     bWhite = New SolidBrush(Color.White) 

     Dim x1 As Integer 
     x1 = 100 

     G.FillRectangle(bWhite, x1, 100, 50, 50) 

     Do While x1 < 800 AndAlso isWinner < 0 
      x1 = x1 + prng.Next(maxMove) 
      G.FillRectangle(bRed, x1, 100, 50, 50) 
      Threading.Thread.Sleep(prng.Next(maxSleep)) 
      G.FillRectangle(bWhite, x1, 100, 50, 50) 
     Loop 
     'G.FillRectangle(bRed, x1, 100, 50, 50) 
     If isWinner < 0 Then 
      isWinner = 1 
     End If 
    End Sub 

    Public Sub BlueHorse() 
     Threading.Thread.Sleep(prng.Next(maxSleep)) 
     Dim G As Graphics 
     G = Me.CreateGraphics 
     Dim bBlue As Brush 
     bBlue = New SolidBrush(Color.Blue) 
     Dim bWhite As Brush 
     bWhite = New SolidBrush(Color.White) 

     Dim x2 As Integer 
     x2 = 100 

     G.FillRectangle(bWhite, x2, 200, 50, 50) 

     Do While x2 < 800 AndAlso isWinner < 0 
      x2 = x2 + prng.Next(maxMove) 
      G.FillRectangle(bBlue, x2, 200, 50, 50) 
      Threading.Thread.Sleep(prng.Next(maxSleep)) 
      G.FillRectangle(bWhite, x2, 200, 50, 50) 
     Loop 
     'G.FillRectangle(bBlue, x2, 200, 50, 50) 
     If isWinner < 0 Then 
      isWinner = 2 
     End If 
    End Sub 

    Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown 

     Dim G As Graphics 
     G = Me.CreateGraphics 
     Dim bRed As Brush 
     bRed = New SolidBrush(Color.Red) 
     Dim bBlue As Brush 
     bBlue = New SolidBrush(Color.Blue) 

     G.FillRectangle(bRed, 100, 100, 50, 50) 
     G.FillRectangle(bBlue, 100, 200, 50, 50) 
    End Sub 
End Class 
+0

感謝dbasnett爲您改進的代碼 - 它完成了我想要的工作。我發現,在Random類中,您事先已經生成了一組隨機數。從這個意義上說,每場比賽的結果都是預先規定的(但我想這是無論如何)。我仍然無法理解爲什麼我最初的嘗試不起作用;每個'馬'產生一個隨機數來控制下一步的移動。我推測這對每匹馬來說都是不同的,因爲rnd被用在不同的線程上?不過謝謝。 – Drummy