没有可使用的实际示例代码,很难提供具体的解决方案。我不知道你有多少控制移动,是2? 10? 10,000?假设您有 10 多个控件在移动,这就是我的处理方式。
我会使用数据表来记录每个移动或可碰撞的控件的边界。控件移动后,更新数据表中的该行,查找碰撞,然后检查对象类型以确定碰撞对象的类,然后根据需要运行代码。
Public MovingControls As DataTable
Sub Main()
'Build the DataTable
MovingControls = New DataTable("ControlBounds")
MovingControls.Columns.Add("Name", GetType(String))
MovingControls.Columns.Add("x1", GetType(Integer))
MovingControls.Columns.Add("x2", GetType(Integer))
MovingControls.Columns.Add("y1", GetType(Integer))
MovingControls.Columns.Add("y2", GetType(Integer))
End Sub
'Call this only when a control/object is created
Sub MovingControlAdded(sender As Control)
Dim Row As DataRow = MovingControls.NewRow
Row("Name") = sender.Name
Dim BoundsRect As Drawing.Rectangle = sender.Bounds
Row("x1") = sender.Bounds.Left
Row("x2") = sender.Bounds.Right
Row("y1") = sender.Bounds.Bottom
Row("y2") = sender.Bounds.Top
MovingControls.Rows.Add(Row)
End Sub
'Call this only when a control/object has moved
Sub MovingControlMoved(sender As Control)
'Update the location of this Control
Dim Row() As DataRow = MovingControls.Select("Name = '" & sender.Name & "'")
'Select returns an array of Rows but there should only be 1 row for each Control
Row(0)("x1") = sender.Bounds.Left
Row(0)("x2") = sender.Bounds.Right
Row(0)("y1") = sender.Bounds.Bottom
Row(0)("y2") = sender.Bounds.Top
'Collision check
Dim CollidedRows() As DataRow = MovingControls.Select("(" & sender.Bounds.Right & " >= x1)" &
"AND (" & sender.Bounds.Left & " <= x2)" &
"AND (" & sender.Bounds.Bottom & " <= y2)" &
"AND (" & sender.Bounds.Top & " >= y1)" &
"AND (Name <> '" & sender.Name & "'")
'Determine the object type and execute necessary code
For Each CollidedRow As DataRow In CollidedRows
Dim CollidedControl As Control = Me.Controls.Item(CollidedRow("Name"))
If CollidedControl.GetType = GetType(Label) Then
'Do stuff for labels
ElseIf CollidedControl.GetType = GetType(Button) Then
'Do stuff for buttons
End If
Next
End Sub
警告:假设一次有 1 个控件在移动。如果控件 A 移入控件 B 但控件 B 同时移开,则即使避免了碰撞,此代码仍将调用碰撞。如果您有多个控件在移动,您可能希望将 MovingControlMoved 方法拆分为 2 个方法,一个用于更新表格,一个用于碰撞检查。先处理所有运动,然后处理所有碰撞。
根据复杂性,您可能希望为继承碰撞接口的可碰撞控件创建自定义类。您可以使用 System.Reflection 来调用 RunMeOnCollision。这将消除 If 语句列表。
Interface iCollidableBase
Sub RunMeOnCollision()
End Interface
Public Class CollidableLabel
Inherits Label
Implements iCollidableBase
Public Sub RunMeOnCollision() Implements iCollidableBase.RunMeOnCollision
Me.Text = "I have been collided"
End Sub
End Class
Public Class CollidableButton
Inherits Button
Implements iCollidableBase
Public Sub RunMeOnCollision() Implements iCollidableBase.RunMeOnCollision
Me.Text = "Ouch, that collision hurt!"
End Sub
End Class
同样,由于不了解此处的完整上下文,我无法针对您的代码测试我的解决方案。如果您可以发布一些其他详细信息,我可能会提供更多帮助。
-E