Тверской государственный университет
Опубликован: 13.09.2006 | Доступ: свободный | Студентов: 2721 / 260 | Оценка: 4.03 / 3.74 | Длительность: 19:48:00
Специальности: Программист, Менеджер
Лекция 6:

Офисное программирование. Специфика и примеры

Проектирование интерфейса

Моя цель состоит в проектировании интерфейса нашей игры. Поскольку стратегическое решение уже принято, действие игры будет разворачиваться в диалоговом окне - форме VBA, то и начинать нужно с создания формы. Вот краткий отчет о моих действиях:

  1. Создание формы - образа объекта Река. Итак, я начал с того, что нажал ALT +F11 и попал в среду Редактора VBA. В меню Insert я выбрал пункт UserForm, получил заготовку формы и приступил к заданию ее свойств. Первым делом я подобрал подходящие размеры формы. Это можно делать руками, но, в тех случаях, когда желательно задать точные, целочисленные значения, можно задать значения свойств Height и Width. Я изменил имя формы, назвав ее WGCForm, и дал заголовок "Wolf, Goat and Cabbage". Главное, я изменил свойство BackColor, выбрав из палитры цвет, подходящий для речной глади. Теперь форма стала похожей на реку. Еще одно серьезное изменение свойств состояло в том, что форму я сделал немодальной, изменив свойство ShowModal. Форма VBA является, как известно, обычным диалоговым окном. Всякое такое окно может быть модальным или немодальным. Из модальных окон нельзя выйти, не закончив диалога. Если же форму сделать немодальной, то это важное свойство формы позволит выходить из нее, не завершив диалога, зани маться другими делами, а потом возвращаться в форму. В частности, это позволяет во время игры при необходимости читать документ Word или создавать его, как это делаю я, имея форму перед глазами.
  2. Создание основных объектов и их размещение. На следующем шаге я разместил на форме 8 одинаковых элементов управления объектов класса Image из стандартной панели инструментов ToolBox. Осталось придать им подходящий внешний вид:
    • Два объекта представляют два берега реки. Я назвал их, задав свойство Name, соответственно LeftBank и RightBank и разместил по краям реки. Никакие картинки с этими объектами можно не связывать, достаточно выбрать подходящий цвет фона и размеры.
    • У левого берега реки я поместил объект, который получил имя Boat, и связал с ним соответствующую картинку лодки. Еще один объект Shark с картинкой акулы я разместил в реке. Он введен больше для антуража и как будущий возможный герой при расширении игры. Вместе с тем он будет играть и некоторую полезную роль, позволяя в любой момент начать игру с начала.
    • Четыре объекта размещены на левом берегу реки это наши герои: человек, волк коза и капуста. Конечно, для этих элементов необходимо задать свойство Picture так, чтобы соответствующая картинка соответствовала образу объекта. Благо с этим теперь особых проблем нет, так как галерея ClipArt, поставляемая с Office 2000, содержит тысячи различных картинок. Проблема состоит лишь в том, чтобы из этого изобилия выбрать подходящую картинку. Напомню, что поиск в галерее ClipArt возможен по ключевому слову. Задайте, например, "goats" для поиска картинки с изображением козы, учитывая, что при задании ключевого слова лучше использовать множественное число. Итак, я нашел картинки, подогнал их под выбранные размеры Image-элементов, установив подходящее значение свойства PictureSizeMode. Мои объекты получили соответствующие имена: Man, Wolf, Goat and Cabbage.

Обратите внимание, порядок размещения Image-элементов имеет значение, поскольку при их частичном совмещении один из них (более поздний) перекрывает другой. Поскольку такая ситуация будет иметь место, когда герои игры собираются в лодке, то целесообразно вначале на форме разместить лодку, а изображение человека разместить последним. Результат моих действий показан на предыдущем рисунке. При некотором навыке, когда картинки под рукой, все действие по формированию интерфейса занимает 10 -15 минут. У меня на это ушло больше времени, так как из-за отсутствия способностей к рисованию проектирование интерфейса это не самая сильная моя сторона. И здесь как раз тот самый случай, когда такие задачи должен решать специалист - дизайнер, а не программист.

Теперь, когда проектирование интерфейса закончено, можно приступать ко второй, более интересной части нашей задачи, собственно к программированию нашей игры.

Программирование игры

На этом этапе нам придется решить целый ряд небольших задач, возникающих по ходу игры. Вот перечисление некоторых этапов, позволяющее структурировать игру и наши действия по ее реализации:

  • Введение программных объектов и их инициализация.
  • Посадка пассажиров в лодку.
  • Высадка на берег
  • Переправа через реку.
  • Тестирование ситуаций.
  • Организация диалогов

Будем следовать этой схеме при описании реализации игры.

Программные объекты и их инициализация

При проектировании интерфейса были введены образы объектов, с которыми может взаимодействовать конечный пользователь. Теперь пришла пора ввести сами объекты. Обычно это одна из самых серьезных задач, требующая, как правило, введения собственных классов, тщательного продумывания свойств, методов и событий, которыми должны обладать объекты класса. Мы же можем обойтись без особых сложностей, поскольку у нас довольно простая задача. Наши объекты, подчиняясь игроку, выполняют лишь некоторые перемещения, число которых ограниченно. Задача программы следить лишь за тем, чтобы эти перемещения соответствовали небольшому числу правил. Заметьте, что это игра человека с самим собой, а не игра человека с компьютером. Нам нет необходимости в реализации какой-либо стратегии игры за компьютер, нам нужно лишь следить за выполнением правил. Мы вообще можем и не уметь решать эту задачу, это должен делать играющий, а не программист, реализующий условия для игры. Такие игры устроены просто и, например, написать сетевой вариант программы игры в шахматы, в которой черными и белыми играют два игрока, также просто, как и нашу игру.

Для реализации игры достаточно ввести 5 переменных, следящих за состоянием перемещаемых объектов: человека, волка, козы, капусты и лодки. Каждый из них может находиться в трех состояниях, быть на левом берегу, правом берегу или в лодке (у объекта Boat всего два состояния). Еще одна переменная будет следить за числом пассажиров в лодке. Вот описания из раздела Declarations стандартного модуля с именем WGCModule, который я создал первым делом:

Option Explicit
'Состояния наших объектов - человека, волка, козы, капусты и лодки
Public StateOfMan As String
Public StateOfWolf As String
Public StateOfGoat As String
Public StateOfCabbage As String
Public StateOfBoat As String
Public CountInBoat As Byte	'Число пассажиров в лодке
Public WidthOfRiver	'Ширина реки, используемая при переправе
Листинг 6.1.

Приведем теперь процедуру InitialStates, которая задает начальные установки для наших переменных и визуальных объектов:

Public Sub InitialStates()
	'Задаем начальные состояния объектов и их образов
	StateOfMan = "LeftBank"
	StateOfWolf = "LeftBank"
	StateOfGoat = "LeftBank"
	StateOfCabbage = "LeftBank"
	StateOfBoat = "LeftBank"
	CountInBoat = 0
	
	With WGCForm
		.Man.Top = .LeftBank.Top + 15: .Man.Left = .LeftBank.Left + 10
		.Man.Visible = True
		.Wolf.Top = .LeftBank.Top + 80: .Wolf.Left = .LeftBank.Left + 10
		.Wolf.Visible = True
		.Goat.Top = .LeftBank.Top + 140: .Goat.Left = .LeftBank.Left + 10
		.Goat.Visible = True
		.Cabbage.Top = .LeftBank.Top + 200: .Cabbage.Left = .LeftBank.Left + 10
		.Cabbage.Visible = True
		
		.Boat.Top = .LeftBank.Top + 130: .Boat.Left = .LeftBank.Left + _ .LeftBank.Width
		.Boat.Visible = True
		WidthOfRiver = .Width - .LeftBank.Width - .RightBank.Width _
			- .Boat.Width
	End With
	

End Sub
Листинг 6.2.

Процедура InitialStates будет вызываться в ответ на такие события, как инициализация или активация нашей формы:

Private Sub UserForm_Activate()
	InitialStates
End Sub

Private Sub UserForm_Initialize()
	InitialStates
End Sub
Листинг 6.3.