1

我正在制作一个战舰游戏,我使用按钮作为网格(播放器)。我正在使用图片框作为船,并且我正在尝试使图片框捕捉到它正在碰撞的按钮。

我已经完成了拖放和碰撞部分,但我正在努力处理按钮部分。图片框是两个按钮的大小。我尝试使用picturebox.left = button.left将图片框与按钮对齐,但它选择了两者中的错误按钮。

Dim Off As Point
Private Sub picDestroyer_MouseDown(sender As Object, e As MouseEventArgs) Handles picDestroyer.MouseDown
    Off.X = MousePosition.X - sender.Left 'Click and Drag ship
    Off.Y = MousePosition.Y - sender.Top
End Sub

Private Sub picDestroyer_MouseMove(sender As Object, e As MouseEventArgs) Handles picDestroyer.MouseMove
    If e.Button = MouseButtons.Left Then
        sender.Left = MousePosition.X - Off.X 'Click and Drag ship
        sender.Top = MousePosition.Y - Off.Y
    End If
End Sub
Private Sub picDestroyer_DoubleClick(sender As Object, e As EventArgs) Handles picDestroyer.DoubleClick
    If picDestroyer.Size = New Size(52, 21) Then 'Rotate Pic if double clicked
        picDestroyer.Size = New Size(21, 52)
    ElseIf picDestroyer.Size = New Size(21, 52) Then
        picDestroyer.Size = New Size(52, 21)
    End If
End Sub
Private Sub picDestroyer_MouseLeave(sender As Object, e As EventArgs) Handles picDestroyer.MouseLeave

    For Each button In Me.Controls
        If picDestroyer.Bounds.IntersectsWith(button.bounds) Then
            button.backcolor = Color.Red
            picDestroyer.BackColor = SystemColors.Control
        End If
        If picDestroyer.Bounds.IntersectsWith(button.bounds) And picDestroyer.Size = New Size(52, 21) Then
            picDestroyer.Top = button.top
        End If
        If picDestroyer.Bounds.IntersectsWith(button.bounds) And picDestroyer.Size = New Size(21, 52) Then
            picDestroyer.Left = button.left
        End If
    Next
4

1 回答 1

0

要获取您想要捕捉的按钮,您可以暂时禁用PictureBox并调用GetChildAtPoint()表单以在 的位置获取子控件PictureBox,指定GetChildAtPointSkip.Disabled为第二个参数,以便搜索不会包括您的禁用PictureBox但所有其他控制它上面/下面。

之后,您可以将PictureBox' 坐标设置为按钮的坐标。

还可以对您的代码进行一些改进:

  • 您可以使用该MouseUp事件而不是MouseLeave在放下图片框后立即更新它的位置。

  • 在捕捉时设置图片框的 X 和 Y 坐标(不仅仅是其中一个,Left = X, Top = Y),以便在按钮的左上角正确捕捉。

  • 在循环中迭代Me.Controls.OfType(Of Button)()而不是 just Me.Controls,因为OfType(Of TResult)获得某种类型的控件(在本例中为Buttons)。Me.Controls例如,仅迭代将包括PictureBox可能在未来引起问题的自身(也许这就是您每次都将其设置为的原因?)BackColorControl

话虽如此,这段代码应该可以工作:

If e.Button = Windows.Forms.MouseButtons.Left Then

    picDestroyer.Enabled = False 'Temporarily disable the picture box so that it isn't included in the child search.
    Dim ChildBelowDestroyer As Control = Me.GetChildAtPoint(picDestroyer.Location, GetChildAtPointSkip.Disabled) 'Look for any child control that isn't disabled.
    picDestroyer.Enabled = True 'Re-enable the picture box.

    If ChildBelowDestroyer Is Nothing OrElse _
        ChildBelowDestroyer.GetType() IsNot GetType(Button) Then
        Return 'Do not continue if no child was found below the picture box, or if the child is not a button.
    End If

    picDestroyer.Location = ChildBelowDestroyer.Location 'Snap the picture box to the button (sets the X- and Y-coordinates).

    For Each button In Me.Controls.OfType(Of Button)() 'OfType() to only look for buttons.
        If picDestroyer.Bounds.IntersectsWith(button.Bounds) Then
            button.BackColor = Color.Red
            picDestroyer.BackColor = SystemColors.Control
        End If
    Next

End If

要记住的另一件事是使用AndAlso而不是And,而OrElse不是OrIf语句中,因为AndAlsoOrElse短路的

于 2017-01-23T07:52:12.363 回答