Шаг 2 – обработка нажатия мыши




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

Как это сделать?

Щелкнем по пустому месту формы, перейдем на вкладку Events инспектора, и создадим приведенный ниже обработчик события OnMouseDown:

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

var SendObj, ListObj: TShape; i, j: integer; R, SendRect, ListRect: TRect;

begin

if not(Sender is TShape) then Exit; //Очень важная строка!

SendObj:=Sender as TShape;

SendRect:=SendObj.BoundsRect;

with List do begin

i:=-1;

repeat

inc(i);

ListObj:=Items[i];

until ListObj=SendObj;

for j:=i+1 to Count-1 do begin

ListObj:=Items[j];

ListRect:=ListObj.BoundsRect;

IntersectRect(R, SendRect, ListRect);

if not IsRectEmpty(R) then exit;

end;

SendObj.Free;

Delete(i);

if Count=0 then begin

Timer1.Enabled:=False;

ShowMessage(' УРА! ПОБЕДА! ');

end;

end;

end;

Кроме того, необходимо будет в конец созданной нами ранее процедуры Timer1Timer добавить строки, выделенные жирным шрифтом:

…………………………….

// определяем обработчик нажатия кнопки мыши

AObj.OnMouseDown:=Form1.OnMouseDown;

// добавляем созданную фигуру в список

List.Add(AObj);

Timer1.Tag:=Timer1.Tag+1;

end;

Запустите проект на выполнение, и Вы сможете уже поиграть в созданную Вами игру!

Разбор полетов

Однако теперь, конечно, необходимо разобраться в тексте созданной нами программы.

Процедура Form1.OnMouseDown вызывается той полоской, над которой находится курсор мыши в момент нажатия кнопки.

Мы щелкнули по пустому месту формы, и начал работать обработчик события OnMouseDown.

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

Во-первых, как метод OnMouseDown узнает, какая полоска его вызвала? Его первым параметром является Sender -указатель на объект, вызвавший метод. Однако тип указателя есть TObject, поэтому сначала его нужно привести к типу TShape. Для этого в Delphi предусмотрен оператор as. Пусть, например, переменная SendObject объявлена как TShape. Тогда присваивание SendObj:=Sender as TShape; устанавливает указатель SendObj на объект типа TShape, над которым произошло отслеживаемое событие.

Во-вторых, требуется "достать" из списка List только те полоски, которые могли перекрыть исходную. Такую возможность имеют полоски, которые были включены список после исходной. Для поиска исходной полоски в списке используется цикл:

repeat

inc(i);

ListObj:=Items[i];

until ListObj=SendObj;

Здесь переменная ListObj также имеет тип TShape.

В-третьих, необходимо проверить, пересекаются ли полоски из второй части списка с исходной на самом деле. Поскольку размеры и положение полосок нам известны, то задача сводится к проверке нескольких неравенств. Однако намного проще воспользоваться готовыми функциями, предназначенными для работы с типом TRect — прямоугольной областью экрана.

Тип TRect представляет собой запись с вариантами: прямоугольник может задаваться четырьмя целыми числами — Left, Top, Right, Bottom — или двумя записями типа TPoint:

type

TPoint = record

X: Longint; У: Longint;

end;

TRect = record

case integer of

0: (Left, Top, Right, Bottom:Integer);

1: (TopLeft, BottomRight: TPoint);

end;

Область, занимаемая визуальным компонентом на экране, хранится в свойстве BoundsRect в виде записи типа TRect. Пересечение прямоугольников выполняет функция IntersectRect, объединение — функция UnionRect, проверку " прямоугольник пуст " — функция IsRectEmpty, проверку на совпадение — функция EqualRect и т.д. Использование этих функций делает программу более короткой и наглядной.

Обратим также внимание на «очень важную строку» в начале процедуры OnMouseDown:

if not(Sender is TShape) then Exit; //Очень важная строка!

Попробуйте закомментировать эту строку, запустите проект и щелкните по свободному от панели месту окна.

На экране появится приведенное ниже страшное сообщение:

Что произошло?

Да попросту в данном случае «посылателем» (параметр Sender) является уже не объект TShape, а сама форма. И в дальнейших операторах мы начинаем работать с формой, как с объектом TShape, что и приводит к ошибке (исключительной ситуации).

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

На рисунке показан внешний вид окна.

Заголовок содержит имя файла проекта, в клиентской части располага­ются выводимый текст и кнопка " ОК ".

В целях повышения сложности игры для первых 5-10 по­лосок установите малый интер­вал времени срабатывания тай­мера, а только потом увеличьте его.

Содержание отчета:

5. Наименование, тема, цель работы.

6. Содержание задания 3.

7. Таблица идентификаторов к игре «Полоски».

8. Краткий алгоритм решения.

9. Результат выполнения и выводы.

Контрольные вопросы:

7. Что такое конструктор и деструктор?

8. Описание конструктора.

9. Описание деструктора.

10. Как обратиться к элементу с помощью конструктора?

11. Алгоритмы работы конструктора и деструктора.

12. Метод Free. Дайте пояснение ключевых слов – inherited, public, virtual, override.

13. Какие объекты вы использовали в программе? Дайте описание полей, свойств и методов.

 



Поделиться:




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

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


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