我正在试图让一个线程同时移动两个图片框,但这不会发生,第一个开始移动然后当第二个开始时。我不知道如何让它们同时移动。
以下是代码:
Imports System.Threading
Public Class Form1
Private picuser As New PictureBox()
Private y As Integer
Private thread1 As Thread
Private thread2 As Thread
Private thread3 As Thread
Private thread4 As Thread
Public Sub enemy1()
picUser = New System.Windows.Forms.PictureBox()
picUser.Visible = True
picUser.Size = New System.Drawing.Size(32, 32)
picuser.Location = New System.Drawing.Point(100, 100)
picuser.BackColor = Color.Purple
Dim e As New AddControlEventArgs(picuser)
' Create EventHandler
Dim ehnd As New EventHandler(AddressOf AddControl)
' Invoke EventHandler with EventArgs (don't need sender as of now)
thread1 = New Thread(Sub() Me.Invoke(ehnd, Nothing, e))
thread1.Start()
End Sub
Public Sub enemy2()
picuser = New System.Windows.Forms.PictureBox()
picuser.Visible = True
picuser.Size = New System.Drawing.Size(32, 32)
picuser.Location = New System.Drawing.Point(150, 100)
picuser.BackColor = Color.Red
Dim e As New AddControlEventArgs(picuser)
' Create EventHandler
Dim ehnd As New EventHandler(AddressOf AddControl)
' Invoke EventHandler with EventArgs (don't need sender as of now)
thread2 = New Thread(Sub() Me.Invoke(ehnd, Nothing, e))
thread2.Start()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
thread3 = New Thread(AddressOf enemy1)
thread4 = New Thread(AddressOf enemy2)
thread3.Start()
thread4.Start()
End Sub
Private Sub mover(ByVal x As PictureBox)
For z = 0 To 10
x.Location = New Point(x.Location.X, x.Location.Y + 10)
Threading.Thread.Sleep(100)
Me.Refresh()
Next
End Sub
Public Class AddControlEventArgs : Inherits EventArgs
Public Sub New(p_control As Control)
m_control = p_control
End Sub
Private m_control As Control
Public ReadOnly Property Control As Control
Get
Return m_control
End Get
End Property
End Class
Private Sub AddControl(sender As Object, e As EventArgs)
' Cast EventArgs to your custom EventArgs
Dim ec As AddControlEventArgs = DirectCast(e, AddControlEventArgs)
Me.Controls.Add(ec.Control)
Call mover(ec.Control)
End Sub
End Class
答案 0 :(得分:2)
只有在要执行大量计算时才要在游戏中使用多线程,并且要在不同的CPU核心上进行分发。否则只需使用游戏循环。根据当前游戏时间计算游戏的实际状态和对象的位置。然后更新UI并重复这两个步骤,直到用户停止游戏。
使用多线程来更新UI不会起作用,因为一次只有一个线程可以访问UI。更确切地说,只有UI线程(应用程序启动的线程)可以执行此操作。因此,其他线程必须调用Invoke
才能让UI线程更新UI。
人工智能和物理模拟等复杂计算可能仍需要多线程。在这里,我看到两种可能性:
游戏循环在每个游戏循环中启动多个线程并等待它们全部完成,然后继续更新UI。
线程独立运行并持续更新游戏状态。游戏循环重复读取游戏状态并相应地更新UI。在这里,您需要在访问时锁定游戏状态(公共资源)。保持锁定时间短,即做大量工作,然后锁定,更新,解锁并继续计算。将游戏状态分成几个可以单独锁定的逻辑部分可能是个好主意。这减少了锁定冲突的可能性。必须访问多个资源的所有线程必须以相同的顺序访问它们。这有助于避免死锁。