Привязать PictureBox к кнопкам после перетаскивания
Я делаю игру "Морской бой" и использую кнопки в качестве сетки (доски игроков). Я использую графический блок в качестве корабля, и я пытаюсь сделать так, чтобы графический блок привязывался к кнопкам, с которыми он сталкивается.
Я уже сделал часть перетаскивания и столкновения, но я борюсь с привязкой к кнопке. Картинная коробка имеет размер двух кнопок. Я попытался выровнять picture box с помощью кнопок, используя picture box.lef t = 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
1 ответ
Чтобы получить кнопку, к которой вы хотите привязать, вы можете временно отключить PictureBox
и позвонить GetChildAtPoint()
в форме, чтобы получить дочерний контроль в месте нахождения PictureBox
, указав GetChildAtPointSkip.Disabled
в качестве второго параметра, чтобы поиск не включал ваш отключенный PictureBox
но все остальные элементы управления выше / ниже.
После этого вы можете просто установить PictureBox
это координаты кнопки.
Есть также несколько улучшений, которые можно внести в ваш код:
Вы можете использовать
MouseUp
событие вместоMouseLeave
обновить положение графического блока сразу после того, как вы его уроните.Установите и X-, и Y-координаты для графического блока при привязке (не только один из них,
Left = X, Top = Y
), чтобы он был правильно зафиксирован в верхнем левом углу кнопки.В цикле перебрать
Me.Controls.OfType(Of Button)()
вместо простоMe.Controls
, посколькуOfType(Of TResult)
получит только элементы управления определенного типа (в этом случаеButton
с). Итерация только черезMe.Controls
будет, например, включатьPictureBox
само по себе, что может вызвать проблемы в будущем (возможно, именно поэтому выBackColor
вControl
каждый раз?).
Все, что сказал, этот код должен работать:
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
вместо Or
в If
Заявления с AndAlso
а также OrElse
закорочены.