Версия 3.0. Игра на пользовательской форме




 

Наша следующая задача – усовершенствовать интерфейс игры. Ячейки электронной таблицы в качестве игрового поля были первым компромиссным решением. Действие настоящей игры должно разворачиваться на пользовательской форме.

Внешний вид формы будет примерно таким.

На форме есть две обычные командные кнопки. Игровое поле может быть представлено надписями или кнопками: оба элемента управления могут отображать текст (крестик или нолик в виде букв “x” и “o”) и «ловить» щелчок мышки. Выберем кнопки.

Уточним задачу для кнопок игрового поля. Щелчок по каждой кнопке должен запускать одни и те же действия:

§ проверить, свободна ли кнопка,

§ отразить на ней символ игрока

§ зафиксировать этот ход в структуре данных.

Примерно это делает сейчас процедура Pl_hod.

Для того, чтобы это все работало, нам надо 9 событийных процедур, с минимальными отличиями в тексте, связанными с номерами кнопок. Даже если мы отладим текст для одной, а потом скопируем его 8 раз, это будет очень долго и нерационально. Надо искать другое решение.

Такое решение в VBA существует. Суть его сводится к тому, чтобы описать абстрактную «универсальную» кнопку в рамках пользовательского класса, а затем создать ее 9 экземпляров с уже заданным поведением. С этой технологией нам и предстоит познакомиться.

Сразу дадим рекомендации по организации работы. Если при работе с классом Polosa мы добавляли к проекту новые элементы (модули, процедуры и т.п.), то при переносе интерфейса на форму мы будем заменять некоторые решения. Поэтому рекомендуется создать копию проекта, чтобы сохранить решение «в электронной таблице» в законченном виде и работающем состоянии.

В дальнейшем изложении мы будем сравнивать создание нового класса с тем, как мы работали с классом Polosa.

 

Начнем работу снизу-вверх, с создания класса. Создайте модуль класса (Меню – Insert – Class Module) и присвойте ему имя kletka. Объявите две переменных (поля) класса для хранения номера клетки и знака, поставленного в этой клетке. Сделайте это с помощью Dim, чтобы закрыть доступ к этим переменным извне:

Dim nom As Integer

Dim znak As String

Теперь самое интересное. Кнопка, которая будет выполнять роль экранного образа клетки, должна также быть объявлена как объектная переменная (или поле) класса:

Public WithEvents Bttn As MSForms.CommandButton

Строка написана по известному формату:

Dim <Имя> As <Тип>

Прокомментируем эту строку по словам

Public - мы хотим, чтобы кнопка была видна извне, поэтому не Dim, а Public.

WithEvents («с событиями») – дополнительное ключевое слово, которое указывает, что элемент управления должен уметь реагировать на события

Bttn – имя объектной переменной-кнопки, сокращение от Button (кнопка) методом «без гласных»

As – ключевое слово формата Dim <Имя> As <Тип>

MSForms.CommandButton – тип переменной, указание на командную кнопку, являющуюся элементом управления форм MicroSoft.

Уточним взаимоотношения. С точки зрения ООП логическим объектом является клетка. Она имеет традиционные свойства и экранное представление. Кнопка является экранным представлением клетки, т.е. находится внутри объекта «клетка». Графически это можно представить так:

 

Клетка     номер - nom знак - znak  
  кнопка – Bttn  
     

И еще одна важная информация: внутри модуля класса kletka система воспринимает Bttn как имя кнопки (как, например, CommandButton1 в модуле формы).

Займемся разработкой класса kletka. Во-первых отметим, что клетки сами образуют структуру данных: они будут хранить информацию о написанных в них крестиках-ноликах. Эта информация должна быть доступна из других модулей, при этом переменную znak, в соответствии с принципом инкапсуляции, мы закрыли. Правильное решение (опять же в соответствии с принципом инкапсуляции) – написать две процедуры-оболочки для чтения и записи знака. Точнее, чтение будет функцией, а запись – процедурой.

Function kl_znak()

kl_znak = znak

End Function

 

Sub new_zn(zn As String)

znak = zn

Bttn.Caption = zn

End Sub

В процедуре-записи кроме помещения знака в переменную знак выводится на кнопку (свойство Caption). Обратите внимание: Bttn используется как имя кнопки (как было сказано выше).

Еще одна полезная процедура «библиотечного» типа – помещение на клетку стартового пустого значения.

Sub Start()

new_zn ""

End Sub

Теперь необходимо стандартное решение, знакомое по классу Polosa: метод-процедура create для создания объекта и установки начальных свойств.

Sub create(p_nom As Integer) Заголовок. Параметр – номер клетки (1-9)
Const dxy As Integer = 30 Константа, расстояние между кнопками на экране
Dim x As Integer, y As Integer Для координат клеток/кнопок
line_to_sq p_nom, x, y «Наша» библиотечная процедура, преобразующая «номер 1-9» (p_nom) в «координаты 1-3» (x, y). Проверьте, что она у вас есть и называется именно так.
With Bttn Начало структуры With (см. далее). Строчки внутри структуры относятся к кнопке.
.Height = dxy – 2 высота «чуть меньше» расстояния между кнопками
.Width = dxy – 2 ширина «чуть меньше» расстояния между кнопками
.Font.Bold = True шрифт жирный («жирность» - это свойство, имеющее значение True/False)
.Font.Size = 12 размер шрифта
.Left = x * dxy расстояние левого-верхнего угла кнопки от левого края формы, зависит от x-координаты клетки
.Top = y * dxy расстояние левого-верхнего угла кнопки от верхнего края формы, зависит от y-координаты клетки
End With Конец структуры With
Start Вызов метода класса, описанного выше. Напомним: он заполняет пустым значением переменную znak и свойство кнопки Caption
nom = p_nom Присвоение номера-параметра номеру – переменной класса
End Sub Конец процедуры

Прокомментируем синтаксические «новшества».

1. Инструкция Const создает константу (новый для нас объект языка). Константу можно представлять себе как переменную, значение которой не будет меняться. Можно считать, что в инструкции Const объединены объявление (как в Dim) и присвоение начального значения (по знаку равенства). В нашем примере константа dxy задает расстояние между кнопками на экране. Она нужна только в этот момент – при создании кнопок, поэтому константа объявлена как локальная, внутри процедуры. Если мы захотим изменить расстояние между кнопками, нам надо будет изменить только эту строчку программы.

2. Инструкция With – End With позволяет упростить обращение к свойствам или методам одного объекта. Строки

With Bttn

.Height = dxy - 2

End With

и

Bttn.Height = dxy - 2

будут работать абсолютно одинаково. Для одной строки мы, конечно, не будем использовать эту структуру, а вот для 6 строчек подряд выигрыш в объеме и читаемости текста очевиден. Обратите внимание, что внутри структуры With названия свойств и методов должны начинаться с точки.

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

 



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2019-08-08 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: