Высадка пассажиров из лодки на берег
Эта операция представляет процесс, обратный процессу посадки в лодку. Опять-таки, я реализовал две возможных стратегии. После того, как лодка причалила к берегу, одним щелчком по берегу можно высадить всех пассажиров из лодки. Вторая стратегия соответствует интуитивному поведению, когда пассажиров, не обязательно всех, можно высаживать по одному путем простого их перетаскивания на берег. Рассмотрим вначале более простую стратегию, реализованную в обработчиках событий Click для двух объектов LeftBank и RightBank:
Private Sub LeftBank_Click() 'Все пассажиры из лодки высаживаются на левый берег ONLeftBank ("All") End Sub Private Sub RightBank_Click() 'Все пассажиры из лодки высаживаются на правый берег OnRightBank ("All") End Sub
Листинг 6.11.
(html, txt)
Сами обработчики являются простыми, поскольку вся обработка спрятана в вызываемых процедурах стандартного модуля, которым в качестве параметра передается слово "All", указывающее на необходимость высадки на берег всех пассажиров. Эта же процедура будет использоваться и во второй стратегии, когда пассажиры высаживаются по одному. Давайте перейдем к ее рассмотрению. Для самих перетаскиваемых объектов обработчики события MouseMove, запускающие перетаскивание объекта, уже написаны. Мы рассматривали их, когда речь шла о перемещении объектов с берега в лодку. Теперь изменилась цель перетаскивания из лодки на берег, левый или правый в зависимости от того, куда причалила лодка. Поэтому нам надо лишь рассмотреть обработчики событий для целевых объектов LeftBank и RightBank. Напомним, эти объекты являются целевыми и при причаливании лодки к берегу. Вот тексты этих обработчиков:
Листинг 6.12.
(html, txt)
Все программистские сложности спрятаны в процедурах стандартного модуля OnLeftBank и OnRightBank. Именно в них предусмотрен разбор случаев, то ли лодка причалила к берегу, то ли человек, то ли какой-либо из его спутников высаживается на берег. Здесь же предусмотрена проверка того, на какой берег в данный момент возможна высадка или причаливание.
Листинг 6.13.
(html, txt)
Private Sub LeftBank_BeforeDropOrPaste(ByVal Cancel As MSForms.ReturnBoolean, ByVal Action As MSForms.fmAction, ByVal Data As MSForms.DataObject, ByVal X As Single, ByVal Y As Single, ByVal Effect As MSForms.ReturnEffect, ByVal Shift As Integer) 'Достигнута цель перетаскиваемого объекта.Объект можно опустить в точку назначения. Cancel = True Effect = fmDropEffectCopy 'Пассажир высаживается на левый берег или лодка причаливает к нему ONLeftBank (Data.GetText) End Sub Private Sub RightBank_BeforeDragOver(ByVal Cancel As MSForms.ReturnBoolean, ByVal Data As MSForms.DataObject, ByVal X As Single, ByVal Y As Single, ByVal DragState As MSForms.fmDragState, ByVal Effect As MSForms.ReturnEffect, ByVal Shift As Integer) 'Достигнута цель перетаскиваемого объекта.Изменяется внешний вид курсора. Cancel = True Effect = fmDropEffectCopy
End Sub
Private Sub RightBank_BeforeDropOrPaste(ByVal Cancel As MSForms.ReturnBoolean, ByVal Action As MSForms.fmAction, ByVal Data As MSForms.DataObject, ByVal X As Single, ByVal Y As Single, ByVal Effect As MSForms.ReturnEffect, ByVal Shift As Integer) 'Достигнута цель перетаскиваемого объекта.Объект можно опустить в точку назначения. Cancel = True Effect = fmDropEffectCopy 'Пассажир высаживается на правый берег или лодка причаливает к нему OnRightBank (Data.GetText) End Sub
Листинг 6.12.
Все программистские сложности спрятаны в процедурах стандартного модуля OnLeftBank и OnRightBank. Именно в них предусмотрен разбор случаев, то ли лодка причалила к берегу, то ли человек, то ли какой-либо из его спутников высаживается на берег. Здесь же предусмотрена проверка того, на какой берег в данный момент возможна высадка или причаливание.
Public Sub ONLeftBank(Who As String) If StateOfBoat = "LeftBank" Then 'пассажиров из лодки можно высадить на левый берег With WGCForm If ((Who = "All") Or (Who = "Man")) And (StateOfMan = "InBoat") Then 'можно высадить человека .Man.Top = .LeftBank.Top + 15: .Man.Left = .LeftBank.Left + 10 StateOfMan = "LeftBank" CountInBoat = CountInBoat - 1 End If If ((Who = "All") Or (Who = "Wolf")) And (StateOfWolf = "InBoat") Then 'можно высадить волка .Wolf.Top = .LeftBank.Top + 80: .Wolf.Left = .LeftBank.Left + 10 StateOfWolf = "LeftBank" CountInBoat = CountInBoat - 1 End If If ((Who = "All") Or (Who = "Goat")) And (StateOfGoat = "InBoat") Then 'можно высадить козу .Goat.Top = .LeftBank.Top + 140: .Goat.Left = .LeftBank.Left + 10 StateOfGoat = "LeftBank" CountInBoat = CountInBoat - 1 End If If ((Who = "All") Or (Who = "Cabbage")) And (StateOfCabbage = "InBoat") Then 'можно высадить капусту .Cabbage.Top = .LeftBank.Top + 200: .Cabbage.Left = .LeftBank.Left + 10 StateOfCabbage = "LeftBank" CountInBoat = CountInBoat - 1 End If End With ElseIf (Who = "Boat") Then 'Лодка переезжает на левый берег Crossing End If TestingState End Sub
Public Sub OnRightBank( Who As String) If StateOfBoat = "RightBank" Then 'пассажиров из лодки можно высадить на правый берег With WGCForm If ((Who = "All") Or (Who = "Man")) And (StateOfMan = "InBoat") Then 'можно высадить человека .Man.Top = .RightBank.Top + 15: .Man.Left = .RightBank.Left + 10 StateOfMan = "RightBank" CountInBoat = CountInBoat - 1 End If If ((Who = "All") Or (Who = "Wolf")) And (StateOfWolf = "InBoat") Then 'можно высадить волка .Wolf.Top = .RightBank.Top + 80: .Wolf.Left = .RightBank.Left + 10 StateOfWolf = "RightBank" CountInBoat = CountInBoat - 1 End If If ((Who = "All") Or (Who = "Goat")) And (StateOfGoat = "InBoat") Then 'можно высадить козу .Goat.Top = .RightBank.Top + 140: .Goat.Left = .RightBank.Left + 10 StateOfGoat = "RightBank" CountInBoat = CountInBoat - 1 End If If ((Who = "All") Or (Who = "Cabbage")) And (StateOfCabbage = "InBoat") Then 'можно высадить капусту .Cabbage.Top = .RightBank.Top + 200: .Cabbage.Left = .RightBank.Left + 10 StateOfCabbage = "RightBank" CountInBoat = CountInBoat - 1 End If End With ElseIf (Who = "Boat") Then 'Лодка переезжает на правый берег Crossing End If TestingState End Sub
Листинг 6.13.