Методические указания к курсу программирования для студентов физического факультета Сравнительное объектно-ориентированное проектирование icon

Методические указания к курсу программирования для студентов физического факультета Сравнительное объектно-ориентированное проектирование


Смотрите также:
Объектно-ориентированное программирование...
Программа дисциплины Объектно-ориентированное программирование Рекомендуется для направления...
Примерная рабочая программа по курсу “Объектно-ориентированное программирование” Факультет...
Программа дисциплины " объектно-ориентированное программирование" Рекомендуется умц кгту им. А...
Учебно-методический комплекс для студентов заочного обучения специальности Прикладная...
Разработка электронного учебного пособия по курсу “ Объектно-ориентированное программирование в...
Методическое пособие может быть рекомендовано для студентов...
Методические указания по выполнению курсовой работы Для студентов иэутс...
Учебный курс: объектно-ориентированное программировани е в среде delphi...
Программа дисциплины объектно-ориентированное программирование дпп. В...
Программа вступительного экзамена по специальности 05. 13. 18 Математическое моделирование...
Методические указания к курсовой работе по дисциплине «Объектно-ориентированное...



Загрузка...
страницы:   1   2   3   4
скачать


Министерство образования и науки Российской Федерации

Федеральное агентство по образованию


Государственное образовательное учреждение

высшего профессионального образования


«РОСТОВСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ»


МЕТОДИЧЕСКИЕ УКАЗАНИЯ

к курсу программирования

для студентов физического факультета

Сравнительное объектно-ориентированное проектирование

Delphi vs C++ vs C#

Часть 2




Ростов-на-Дону

2006


Методические указания разработаны кандидатом физико-математических наук, доцентом кафедры теоретической и вычислительной физики Г.В. Фоминым.


Ответственный редактор доктор физ.-мат. наук, профессор В.П. Саченко


Компьютерный набор и верстка Г.В. Фомин


Печатается в соответствии с решением кафедры теоретической и вычислительной физики физического факультета РГУ, протокол №1 от 17 января 2006 г.


^

Сравнительное объектно-ориентированное проектирование

Delphi vs C++ vs C#

Часть 2



Содержание настоящего пособия является продолжением его 1-ой части «Сравнительное объектно-ориентированное проектирование Delphi vs C++ vs C#».

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

Спрайты


Это классы, реализующие алгоритм воспроизведения коллекции графических объектов, упорядоченных в третьем измерении (так называемое z-упорядочение). Каждый спрайт занимает свой «слой» в измерении, перпендикулярном экрану (z-направление), как отдельное окно. Однако в отличие от окна спрайт принадлежит коллекции, связанной лишь с одним окном.

Delphi


В Delphi код приложения разбивается на отдельные модули. Каждый модуль состоит из интерфейсной секции, секции реализации и, возможно, секции инициализации. В интерфейсной секции размещаются описания типов, переменных, заголовков процедур и функций, доступных тем частям приложения, которые ссылаются на данный модуль. В секции реализации размещается код, реализующий объявленные в интерфейсе методы классов, процедуры и функции, а также локальные типы, переменные, процедуры и функции, доступные только коду самого модуля.
^

Интерфейсная секция классов спрайтов


unit uSprite;

{В модуле описаны классы TSpriteList, TSprite и их наследники,

предназначенные для Z-упорядочения графических изображений

на любой канве (например канве объекта типа TPaintBox).

Конструктор класса TSpriteList имеет один параметр -

канву, на которой производится отрисовка.

Конструктор класса TSprite имеет два параметра, определяющие

прямоугольник спрайта и список, которому спрайт принадлежит.}

interface

//Модули VCL, в которых описаны используемые в интерфейсе типы

uses Controls,Graphics,Classes,Types;

type

// Предварительное объявление класса TSprite

TSprite=class;

// Тип переменных, содержащих ссылки на классы типа TSprite

TSpriteClass=class of TSprite;

// Список спрайтов

TSpriteList=class

private

// Поля

// Хранит канву ("контекст устройства"), используемую для отображения спрайтов списка

FCanvas:Controls.TControlCanvas;

// Хранит режим отображения графического объекта при его копировании на канву

FCanvasCopyMode:Graphics.TCopyMode;

// Хранит прямоугольник, ограничивающий область отображения спрайтов списка

FClientRect:Types.TRect;

// Хранит список указателей на спрайты

FList:Classes.TList;

// Хранит текущее число спрайтов в списке

FCount:integer;

// Метод

// Возвращает спрайт списка под номером aZ

function GetSprite(aZ:integer):TSprite;

public

// Свойства

// Возвращает спрайт из списка как элемент массива

property Sprites[aZ:integer]:TSprite read GetSprite;default;

// Возвращает текущее число спрайтов в списке

property Count:integer read FCount;

// Возвращает ссылку на список указателей спрайтов

property List:Classes.TList read FList;

// Возвращает ссылку на канву, с которой связаны спрайты списка

property Canvas:Controls.TControlCanvas read FCanvas;

// Возвращает прямоугольник, ограничивающий область изображения спрайтов списка

property ClientRect:Types.TRect read FClientRect;

// Конструктор

// Создает и инициализирует экземпляр списка спрайтов, связанного с данной канвой

constructor Create(const aCanvas:Controls.TControlCanvas);

// Методы

// Реализует действия перед освобождением объекта

procedure BeforeDestruction;override;

// Создает и добавляет в список объект класса aSpriteClass,

// занимающего прямоугольник SpriteRect

function AddSprite(const aSpriteClass:TSpriteClass;

const SpriteRect:Types.TRect):TSprite;

// Перемещает спрайт внутри списка в z-направлении (с одного слоя в другой)

procedure MoveSprite(const fromZ,toZ:integer);

// Удаляет спрайт с индексом aZ (слой) из списка

procedure DeleteSprite(const aZ:integer);virtual;

// Очищает список от указателей на спрайты

procedure Clear;virtual;

end;


// Тип обработчика события, наступающего перед смещением спрайта

OnMoveEvent=function(Sender:TSprite;var NewLocation:Types.TPoint):

Boolean of object;

// Абстрактный класс спрайта регулирует изображение и перемещение спрайта.

// Изображению спрайта на канве предшествует сохранение в памяти фона,

// который перекрывается изображением.

// Требуемый участок фона сохраняется в объекте типа TBitmap.

// Изображение спрайта исчезает в момент восстановления фона –

// обратного копирования на канву сохраненного участка.

TSprite=class(TObject)

private

// Поля

// Хранит состояние видимости спрайта

FVisible: boolean;

// Хранит номер слоя, занимаемого спрайтом

FZ: integer;

// Хранит маску - наличие пересечений с одним из выше лежащих спрайтов

FMask: boolean;

// Хранит ссылку на список, которому принадлежит спрайт

FSpriteList: TSpriteList;

// Хранит Bitmap, содержащий фон спрайта

FImage: Graphics.TBitmap;

// Хранит координаты левого верхнего угла спрайта

FLocation: Types.TPoint;

// Хранит размеры спрайта

FSize: Types.TSize;

// Хранит ссылку на обработчик смещения спрайта

FOnMove: OnMoveEvent;

// Методы

// Готовит спрайт к изображению

procedure BeginPaint;

// Завершает процесс изображения спрайта

procedure EndPaint;

// Устанавливает маску для спрайта из слоя aZ

procedure SetMask(const aZ:integer);

// Определяет факт перекрытия спрайтов из слоев First и Second

function Intersect(const First,Second:integer):boolean;

// Устанавливает состояние видимости спрайта

procedure SetVisible(const aVisible: Boolean);

// Возвращает прямоугольник спрайта

function GetSpriteRect:Types.TRect;

// Конструктор

// Создает и инициализирует спрайт, принадлежащий списку Sprites

// с прямоугольником SpriteRect

constructor Create(const SpriteRect: Types.TRect;const Sprites: TSpriteList);

protected

// Методы

// Восстанавливает изображение фона спрайта

procedure Restore;virtual;

// Изображает спрайт

procedure Paint;virtual;

// Формирует реальное изображение спрайта (в этом классе метод абстрактный)

procedure PaintPicture;virtual;abstract;

public

// Свойства

// Возвращает слой спрайта

property Z:integer read FZ;

// Устанавливает и возвращает обработчик при перемещении спрайта

property OnMove:OnMoveEvent read FOnMove write FOnMove;

// Устанавливает и возвращает состояние видимости спрайта

property Visible:Boolean read FVisible write SetVisible;

// Возвращает положение левого верхнего угла спрайта

property Location:Types.TPoint read FLocation;

// Возвращает размеры спрайта

property SpriteSize:Types.TSize read FSize;

// Возвращает прямоугольник спрайта

property SpriteRect:Types.TRect read GetSpriteRect;

// Возвращает ссылку на список, которому спрайт принадлежит

property SpriteList:TSpriteList read FSpriteList;

// Методы

// Выполняет инициализирующие действия сразу после создания спрайта

procedure AfterConstruction;override;

// Выполняет действия непосредственно перед освобождением спрайта

procedure BeforeDestruction;override;

// Перемещает спрайт на вектор drift

function Move(const drift: Types.TSize): boolean;virtual;

// Перемещает спрайт в новое положение NewLocation

function MoveTo(const NewLocation: Types.TPoint): boolean;virtual;

end;


// Тип массива, хранящего карту следов (пикселей) спрайтов на канве

TTraceMap=Array of array of Boolean;


// Список спрайтов, оставляющих след на канве

TTracedSpriteList=class(TSpriteList)

private

// Поле

// Хранит карту следов на канве

FTraceMap:TTraceMap;

public

//Возвращает карту следов на канве

property TraceMap:TTraceMap read FTraceMap;

// Методы

// Выполняет инициализирующие действия сразу после создания списка

procedure AfterConstruction;override;

// Выполняет действия непосредственно перед освобождением списка

procedure BeforeDestruction;override;

// Удаляет спрайт с индексом aZ (слой) из списка

procedure DeleteSprite(const aZ:integer);override;

// Очищает список от указателей на спрайты

procedure Clear;override;

end;


// Тип массива точек следа спрайта

TTracePoints=array of Types.TPoint;

// Класс, спрайты которого оставляют след перемещения

// по канве списка типа TTracedSpriteList

TTracedSprite=class(TSprite)

private

// Поля

// Хранит указание, оставляет ли спрайт след

FTraced:Boolean;

// Хранит точки со следом

FTracePoints:TTracePoints;

// Хранит указание, имеет ли след определенный цвет

FTraceColored:Boolean;

// Хранит цвет следа

FTraceColor:Graphics.TColor;

// Хранит центр спрайта

FCenter:Types.TPoint;

// Метод

// Устанавливает цвет спрайта

procedure SetTraceColor(const aTraceColor:Graphics.TColor);

public

// Свойства

// Возвращает и устанавливает указание на наличия следа

property Traced:Boolean read FTraced write FTraced;

// Возвращает и устанавливает указатель на точки следа

property TracePoints:TTracePoints read FTracePoints;

// Возвращает и устанавливает указание, имеет ли след определенный цвет

property TraceColored:Boolean read FTraceColored write FTraceColored;

// Возвращает и устанавливает цвет следа

property TraceColor:Graphics.TColor read FTraceColor write SetTraceColor;

// Возвращает центр спрайта

property Center:Types.TPoint read FCenter;

// Методы

// Выполняет инициализирующие действия сразу после создания спрайта

procedure AfterConstruction;override;

// Выполняет действия непосредственно перед освобождением спрайта

procedure BeforeDestruction;override;

// Перемещает спрайт на вектор drift

function Move(const drift:Types.TSize):boolean;override;

// Воспроизводит след

procedure PutTrace;

end;


const DefaultColor=$ffffff;//Цвет эллипса по умолчанию

type

// Класс, изображающий спрайт в форме сплошного эллипса

TEllipseSprite=class(TTracedSprite)

private

// Поле

// Хранит цвет эллипса

FColor:Graphics.TColor;

protected

// Методы

// Изображает эллипс

procedure PaintPicture;override;

// Устанавливает цвет эллипса

procedure SetColor(const aColor:Graphics.TColor);

public

// Свойство

// Возвращает и устанавливает цвет эллипса

property Color:Graphics.TColor read FColor write SetColor;

// Метод

// Выполняет инициализирующие действия сразу после создания спрайта

procedure AfterConstruction;override;

end;


Вспомним правила описания в Delphi в контексте приведенного выше интерфейса модуля uSprite. С этой целью рассмотрим фрагмент начала модуля

uses Controls,Graphics,Classes,Types;

type

// Предварительное объявление класса TSprite

TSprite=class;

// Тип переменных, содержащих ссылки на классы типа TSprite

TSpriteClass=class of TSprite;

// Список спрайтов

TSpriteList=class

// Описание членов класса



end;

  • Директива uses означает, что в коде настоящего модуля используются типы, переменные, процедуры, функции или константы (короче – имена), описанные в интерфейсах модулей Controls, Graphics, Classes, Types. Все перечисленные модули принадлежат в данном случае библиотеке среды Delphi.

  • Служебное слово type означает, что ниже следует описание типов. Тип – это формат переменных. Существуют стандартные типы такие как , , и другие. Их формат задан средой. Другие типы, которые оказываются необходимыми в конкретном приложении или модуле, требуют специального описания.

  • Краткое описание TSprite=class; типа TSprite означает, что класс TSprite будет описан ниже, но упоминание о нем необходимо уже здесь. Дело в том, что описанный ниже класс TSpriteList использует в своем описании TSprite. В то же время полное описание класса TSprite в свою очередь содержит ссылку на класс TSpriteList. Эта взаимозависимость описаний двух классов не позволяет предпочесть в порядке описания один класс другому. Выход – дать краткое (пустое) описание одного из классов перед полным описанием другого.

  • Тип TSpriteClass=class of TSprite описывает переменные, которые содержат в себе ссылки на таблицы виртуальных методов класса TSprite и его наследников. Такие переменные могут быть использованы, например, при создании экземпляра объекта, о котором во время программирования известно лишь то, что он принадлежит к семейству спрайтов, то есть является наследником класса TSprite. Так одним из параметров метода AddSprite(const aSpriteClass: TSpriteClass; const SpriteRect: Types.TRect) класса TSpriteList является переменная типа TSpriteClass, указывающая, экземпляр какого класса спрайтов следует добавить в список.

Строка TSpriteList=class открывает описание класса, которое содержит в себе поля, свойства и методы класса TSpriteList вплоть до служебного слова end, завершающего перечисление членов класса. Все поля объекта инициализируются при явном вызове конструктора в коде приложения. По умолчанию, если в теле конструктора не указаны другие значения, все поля будут инициализированы нулями.

Каждый член класса TSpriteList имеет определенный уровень доступа. Так в описании класса TSpriteList имеется две секции, выделенные модификаторами доступа private и public.

Рассмотрим фрагмент кода, описывающий класс TSpriteList:

TSpriteList=class

private

// Поля

// Хранит канву ("контекст устройства"),используемую для отображения спрайтов списка

FCanvas:Controls.TControlCanvas;



// Метод

// Возвращает спрайт списка под номером aZ

function GetSprite(aZ:integer):TSprite;

public

// Свойства

// Возвращает ссылку на канву, с которой связаны спрайты списка

property Canvas:Controls.TControlCanvas read FCanvas;



// Возвращает спрайт из списка как элемент массива

property Sprites[aZ:integer]:TSprite read GetSprite;default;

// Конструктор

// Создает и инициализирует экземпляр списка спрайтов, связанного с данной канвой

constructor Create(const aCanvas:Controls.TControlCanvas);



end;

В Delphi модификатор доступа private применяется к членам класса, которые доступны лишь тому же модулю, в котором описан сам класс, но недоступны другим модулям программы. Обычно поля класса имеют уровень доступа private. Члены класса с уровнем доступа public доступны любой части программы. Свойства класса обычно имеют уровень доступа public. Так поле FCanvas (идентификаторы полей в Delphi принято начинать буквой F от field – поле) имеет уровень доступа private, но свойство Canvas открыто для доступа. Через свойство Canvas можно прочесть поле FCanvas, но нельзя изменить его значение. Так свойства могут регулировать доступ к полям.

Что касается методов, то их разделение по уровням доступа зависит от логики класса. Так, метод GetSprite(aZ:integer):TSprite класса TSpriteList «спрятан» от внешнего доступа под модификатором private. Его роль ограничивается обеспечением доступного свойства Sprites[aZ:integer] возвращаемым значением – спрайтом с индексом aZ из списка. Другие методы класса TSpriteList имеют открытый доступ. Среди них конструктор класса Create, создающий экземпляр объекта и инициализирующий его поля. Параметром конструктора является объект типа TControlCanvas из библиотечного модуля Controls. Объекты этого типа предоставляют спрайтам область изображения - прямоугольник с известными границами в окне приложения и инструменты изображения – кисть и карандаш с цветовой палитрой.

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

Модификатор default в свойстве Sprites указывает на то, что доступ к объектам класса TSpriteList может осуществляться через свойство Sprites как к элементам массива – в индексном виде.

В коде настоящего модуля имена, описанные в других модулях, специально записаны в расширенном формате с тем, чтобы явно указать их принадлежность. Например, имя типа TControlCanvas, описанного в модуле Controls, записано в расширенном виде Controls.TControlCanvas. Вообще говоря, расширенное имя можно сократить, убрав имя модуля, если отсутствует конфликт имен.

Метод

procedure BeforeDestruction; override;

имеет модификатор override. Это означает, что метод BeforeDestruction является виртуальным и унаследован от предка класса TSpriteList, где он описан как виртуальный (virtual). Предком класса TSpriteList является класс TObject.

Другие методы

procedure DeleteSprite(const aZ:integer); virtual;

procedure Clear; virtual;

описаны как виртуальные в самом классе TSpriteList. У наследника TTracedSpriteList, эти же методы преобретают модификатор override.

Рассмотрим еще один фрагмент кода, относящийся к описанию Tsprite и следующий за описанием класса TSpriteList.

// Тип обработчика события, наступающего перед смещением спрайта

OnMoveEvent=function(Sender:TSprite;var NewLocation:Types.TPoint):Boolean of object;

// Абстрактный класс спрайта, регулирующий изображение и перемещение спрайта

TSprite=class(TObject)

private



// Конструктор

// Создает и инициализирует спрайт, принадлежащий списку Sprites

// с прямоугольником SpriteRect

constructor Create(const SpriteRect:Types.TRect;const Sprites:TSpriteList);

protected



// Формирует реальное изображение спрайта (в этом классе метод абстрактный)

procedure PaintPicture;virtual;abstract;

public



end;

Здесь

  • Тип функции OnMoveEvent, описанный с модификатором of object, означает, что это тип метода класса, а не просто тип какой-то отдельной функции. Разница в том, что метод класса обязательно имеет один скрытый параметр Self - экземпляр класса, который его вызывает. У обычных процедур и функций такого параметра нет. Обработчики событий в Delphi обычно имеют тип метода. Тогда в них можно подставить ссылку на метод либо формы приложения, либо другого класса, использующего объявленное событие в своих целях.

  • В заголовке описания класса TSprite в скобках указан предок TObject, хотя такое указание отсутствует в описании класса TSpriteList. В Delphi отсутствие предка по умолчанию означает, что предком является класс TObject. Так что в описании класса TSprite ссылку на TObject можно также опустить.

  • Конструктор класса TSprite помещен в раздел private. Это делает невозможным создание экземпляров отдельных спрайтов из кода, написанного вне модуля uSprite. Логика классов TSprite и TSpriteList предполагает, что созданием спрайтов занимается только метод Add класса TSpriteList, который только и вызывает конструктор экземпляров класса TSprite.

  • В описании класса TSprite присутствуют методы с уровнем доступа protected. Эти методы и вообще члены класса с доступом protected доступны любому предку класса TSprite, даже если они описаны в других модулях, но не доступны коду других классов, описанных в других модулях.

  • Среди методов класса TSprite, защищенных модификатором protected есть абстрактный метод procedure PaintPicture; virtual; abstract. Он отмечен модификатором abstract. Абстрактный метод PaintPicture не имеет реализации в классе TSprite. Его реализация будет предложена наследниками. Наличие абстрактного метода делает сам класс TSprite абстрактным в том смысле, что его экземпляры не могут быть созданы.

После описания класса TSprite описаны один тип динамического массива

// Тип массива, хранящего карту следов (пикселей) спрайтов на канве

TTraceMap=Array of array of Boolean;

Тип TTraceMap описывает двумерный массив логических значений.

Динамичность массива в том, что его размер не фиксируется как постоянная величина в процессе разработки класса (design time), а определяется лишь в ходе счета (run time). Конкретные переменные, например, размеры области изображения спрайтов, приобретают реальные значения при создании экземпляра класса TTracedSpriteList=class(TSpriteList). Это происходит в методе AfterConstruction класса TTracedSpriteList, выполняющемся сразу вслед за созданием экземпляра объекта этого класса.

За описанием класса TTracedSpriteList и перед описанием класса TtracedSprite есть описание другого типа динамического массива

// Тип массива точек следа спрайта

TTracePoints=array of Types.TPoint;

Это уже одномерный массив точек - записей типа TPoint, описанных в стандартном модуле Types.

Вслед за этим описан класс

TTracedSprite=class(TSprite)

наследник класса TSprite.

Обратите внимание, что класс TTracedSprite, как и его предок TSprite, является абстрактным классом, так как не реализует абстрактный метод PaintPicture.

Вслед за описанием класса TTracedSprite расположен текст

const DefaultColor=$ffffff; //Цвет эллипса по умолчанию

type

// Класс, изображающий спрайт в форме сплошного эллипса

TEllipseSprite=class(TTracedSprite)

Здесь

  • Служебное слово const указывает на то, что DefaultColor является постоянной величиной. Значение DefaultColor записано в 16-ной системе счисления, которая удобна при записи цветов. (В данном случае $ffffff означает максимальное число, содержащееся в трех байтах; в десятичной системе это число равно 224 – 1 = 1677215.) Дело в том, что информация о цвете в Delphi представляется четырехбайтовым целым числом. Старший байт используется для системных цветов, а в трех младших байтах находятся стандартные цвета – в младшем красный, в среднем зеленый и в старшем байте - синий. Другими словами чисто зеленый цвет, к примеру, отвечает числу $ff00. В 16-ричной записи видна структура байтов. Каждому байту отводится по две 16-ричные цифры. В данном случае число $ffffff означает, что все составляющие цвета входят одинаково и с полной интенсивностью – это белый цвет.

  • Вслед за описанием постоянной идет описание класса TEllipseSprite, поэтому набирается служебное слово type, действие которого было отменено const.

  • Класс TEllipseSprite является наследником класса TTracedSprite. В классе TEllipseSprite уже реализован абстрактный метод PaintPicture, поэтому можно создавать его экземпляры – сплошные эллипсовидые спрайты заданного цвета.
^

Секция реализации


В этой секции модуля находится код методов пяти классов, описанных выше


implementation uses SysUtils;


//Определяет, находится ли прямоугольник source внутри прямоугольника dest

function Contains(const source,dest:Types.TRect):Boolean;

begin

with dest do

Result:=(source.Left>=Left) and (source.Top>=Top)

and (source.Right<=Right) and (source.Bottom<=Bottom);

end {Contains};


//Реализация методов класса TSpriteList

constructor TSpriteList.Create(const aCanvas:Controls.TControlCanvas);

begin

inherited Create;

if Assigned(aCanvas) then FCanvas:=aCanvas else

raise SysUtils.Exception.Create('Конструктору класса TSpriteList не передана канва!');

FClientRect:=FCanvas.Control.ClientRect;

FCanvasCopyMode:=FCanvas.CopyMode;

FList:=Classes.TList.Create;

end {TSpriteList.Create};


procedure TSpriteList.BeforeDestruction;

begin

Clear;

FCanvas.CopyMode:=FCanvasCopyMode;

FList.Free;

FCount:=0;

inherited

end {TSpriteList.BeforeDestruction};


function TSpriteList.GetSprite(aZ:integer):TSprite;

begin

Result:=TSprite(FList[aZ]);

end {GetSprite};


function TSpriteList.AddSprite(const aSpriteClass:TSpriteClass;

const SpriteRect:Types.TRect):TSprite;

var aSprite:TSprite;

begin

Result:=nil;

if Assigned(aSpriteClass) and (SpriteRect.Right- SpriteRect.Left>0) and

(SpriteRect.Bottom-SpriteRect.Top>0) and Contains(SpriteRect,ClientRect) then

begin

aSprite:=aSpriteClass.Create(SpriteRect,Self);

aSprite.FZ:=FList.Add(aSprite);

FCount:=FList.Count;

Result:=aSprite;

end

end {AddSprite};


procedure TSpriteList.MoveSprite(const fromZ,toZ:integer);

var i,minZ:integer;

begin

if (fromZ<>toZ) and (fromZ>-1) and (fromZand

(toZ>-1) and (toZthen

begin

if fromZthen minZ:=fromZ else minZ:=toZ;

for i:=FCount-1 downto minZ do

if Self[i].FVisible then Self[i].Restore;

FList.Move(fromZ,toZ);

for i:=minZ to FCount-1 do

begin

Self[i].FZ:=i;

if Self[i].FVisible then Self[i].Paint

end

end

end {MoveSprite};


procedure TSpriteList.DeleteSprite(const aZ:integer);

var i:integer;

begin

if (aZ>-1) and (aZthen

begin

for i:= FCount-1 downto aZ do

with Self[i] do

if Visible then Restore;

Self[aZ].Free;

FList[aZ]:=nil;

FList.Delete(aZ);

FCount:=FList.Count;

for i:= aZ to FCount-1 do

with Self[i] do

begin

Dec(FZ);

if Visible then Paint;

end

end

end {TSpriteList.DeleteSprite};


procedure TSpriteList.Clear;

var i:integer;

begin

if Assigned(FList) then

for i:= FCount - 1 downto 0 do DeleteSprite(i);

end {TSpriteList.Clear};


//Реализация методов класса TSprite

constructor TSprite.Create(const SpriteRect:Types.TRect;const Sprites:TSpriteList);

begin

inherited Create;

FZ:=-1;

FSpriteList:=Sprites;

FLocation:=SpriteRect.TopLeft;

with FSize,SpriteRect do

begin

cx:=Right-Left;cy:=Bottom-Top

end;

end {TSprite.Create};


procedure TSprite.AfterConstruction;

begin

inherited;

FImage:=Graphics.TBitmap.Create;

FImage.Height:=FSize.cy;

FImage.Width:=FSize.cx;

end {TSprite.AfterConstruction};


procedure TSprite.BeforeDestruction;

begin

FImage.Free;

inherited

end {TSprite.BeforeDestruction};


procedure TSprite.SetVisible(const aVisible:Boolean);

begin

if aVisible<>FVisible then

begin

if aVisible then

begin

BeginPaint;

Paint;

EndPaint;

end else

begin

BeginPaint;

Restore;

EndPaint;

end;

FVisible:=aVisible

end

end {SetVisible};


function TSprite.Move(const drift:Types.TSize):boolean;

var NewPos:Types.TPoint;VisState:Boolean;

begin

Result:=true;

NewPos:=Types.Point(FLocation.X+drift.cx,FLocation.Y+drift.cy);

if Assigned(FOnMove) then Result:=FOnMove(Self,NewPos);

Result:=Result and Contains(

Types.Rect(NewPos.X,NewPos.Y,NewPos.X+FSize.cx,NewPos.Y+FSize.cy),

FSpriteList.FClientRect);

if Result then

begin

VisState:=FVisible;

Visible:=false;

FLocation:=NewPos;

Visible:=VisState

end

end {TSprite.Move};


function TSprite.MoveTo(const NewLocation:Types.TPoint):boolean;

begin

Result:=Move(Types.TSize(

Types.Point(NewLocation.X-FLocation.X,NewLocation.Y-FLocation.Y)))

end {MoveTo};


procedure TSprite.BeginPaint;

var i:integer;

begin

SetMask(FZ);

for i:=FSpriteList.FCount-1 downto FZ+1 do

with FSpriteList[i] do

if FMask and FVisible then Restore;

end {BeginPaint};


procedure TSprite.SetMask(const aZ:integer);

var i:integer;

begin

for i:=aZ+1 to FSpriteList.FCount-1 do

begin

with FSpriteList[i] do

FMask:= Intersect(aZ,i) or FMask;

if FMask then SetMask(i)

end

end {SetMask};


procedure TSprite.EndPaint;

var i:integer;

begin

for i:=FZ+1 to FSpriteList.FCount-1 do

with FSpriteList[i] do

if FMask then

begin

if FVisible then Paint;

FMask:=false

end

end {EndPaint};


procedure TSprite.Paint;

begin

with FSpriteList do

begin

FCanvas.CopyMode:=cmSrcCopy;

with FImage do

Canvas.CopyRect(Types.Rect(0,0,Width,Height),FCanvas,SpriteRect);

end;

PaintPicture

end {Paint};


procedure TSprite.Restore;

begin

with FSpriteList.FCanvas do

begin

CopyMode:= cmSrcCopy;

with FImage do CopyRect(SpriteRect,Canvas,Types.Rect(0,0,Width,Height));

end

end {Restore};


function TSprite.GetSpriteRect:Types.TRect;

begin

with FLocation,FSize do Result:=Types.Rect(X, Y, X+cx,Y+cy)

end {GetSpriteRect};


function TSprite.Intersect(const First,Second:integer):boolean;

var rect:Types.TRect;

begin

with FSpriteList[First] do

Result:=IntersectRect(rect,SpriteRect,FSpriteList[Second].SpriteRect);

end {Intersect};


//Реализация методов класса TTracedSpriteList

procedure TTracedSpriteList.AfterConstruction;

begin

inherited;

with ClientRect do SetLength(FTraceMap,Right-Left+1,Bottom-Top+1);

end {TTracedSpriteList.AfterConstruction};


procedure TTracedSpriteList.BeforeDestruction;

begin

inherited;

FTraceMap:=nil;

end {TTracedSpriteList.BeforeDestruction};


procedure TTracedSpriteList.DeleteSprite(const aZ:integer);

begin

if (aZ > -1) and (aZ < Count) then

begin

TTracedSprite(Self[aZ]).FTracePoints:=nil;

inherited DeleteSprite(aZ);

end

end {TTracedSpriteList.DeleteSprite};


procedure TTracedSpriteList.Clear;

var i,j:integer;

begin

for i:= Low(FTraceMap) to High(FTraceMap) do

for j:= Low(FTraceMap[i]) to High(FTraceMap[i]) do

FTraceMap[i,j]:= false;

inherited Clear;

end {TTracedSpriteList.Clear};


//Реализация методов класса TTracedSprite

procedure TTracedSprite.AfterConstruction;

begin

inherited;

FCenter:=Types.CenterPoint(SpriteRect);

end {TTracedSprite.AfterConstruction};


procedure TTracedSprite.BeforeDestruction;

begin

FTracePoints:=nil;

inherited

end {TTracedSprite.BeforeDestruction};


procedure TTracedSprite.SetTraceColor(const aTraceColor:Graphics.TColor);

begin

FTraceColor:=aTraceColor;

FTraceColored:=true

end {SetTraceColor};


function TTracedSprite.Move(const drift:Types.TSize):Boolean;

begin

if FVisible and FTraced then PutTrace;

Result:=inherited Move(drift);

if Result then

FCenter:=Types.CenterPoint(SpriteRect)

end {TTracedSprite.Move};


procedure TTracedSprite.PutTrace;

var i:integer;

begin

with FCenter do

begin

for i:=FSpriteList.FCount-1 downto 0 do

begin

with FSpriteList[i] do

if FVisible and Types.PtInRect(SpriteRect,Self.FCenter)

then Restore;

end;

with TTracedSpriteList(FSpriteList),FClientRect do

if not TraceMap[x-Left,y-Top] then

begin

with FCanvas do

if FTraceColored then Pixels[x,y]:=FTraceColor else

Pixels[x,y]:=$ffffff xor Pixels[x,y];

TraceMap[x-Left,y-Top]:=true;

SetLength(FTracePoints,High(FTracePoints)+2);

FTracePoints[High(FTracePoints)].X:=x;FTracePoints[High(FTracePoints)].Y:=y;

end;

for i:=0 to FSpriteList.FCount-1 do

begin

with FSpriteList[i] do

if FVisible and Types.PtInRect(SpriteRect,Self.FCenter)

then Paint;

end

end

end {PutTrace};


//Реализация методов класса TEllipseSprite

procedure TEllipseSprite.AfterConstruction;

begin

inherited;

FColor:=DefaultColor;

end {TEllipseSprite.AfterConstruction};


procedure TEllipseSprite.SetColor(const aColor: Graphics.TColor);

var VisState:Boolean;

begin

if FColor<>aColor then

begin

VisState:=FVisible;

Visible:=false;

FColor:=aColor;

if VisState then Visible:=true

end

end {SetColor};


procedure TEllipseSprite.PaintPicture;

begin

with FSpriteList.FCanvas do

begin

Brush.Style:=bsSolid;

Brush.Color:=Color;

Pen.Color:=color;

Ellipse(SpriteRect);

end;

end {PaintPicture};


end {uSprite}.


Следует отметить, что в Delphi в разделе реализации можно указывать лишь имена методов, не повторяя список параметров и тип функции. Например, вместо строки кода

function TTracedSprite.Move(const drift: Types.TSize): Boolean;

можно было бы записать ее краткий вариант

function TTracedSprite.Move;

Здесь мы этим не пользовались, чтобы не затруднять чтение кода.

Предлагается составить оконное приложение, тестирующее представленные классы спрайтов. Для этого следует разместить на форме объект типа TPaintBox с произвольным фоном (в виде рисунка). Создать на нем произвольный список эллиптических спрайтов, имеющих разные атрибуты (цвет, размер) и перемещающихся в границах прямоугольника с произвольными скоростями, зеркально отражаясь от границ и оставляя след.




оставить комментарий
страница1/4
Дата22.09.2011
Размер0,82 Mb.
ТипМетодические указания, Образовательные материалы
Добавить документ в свой блог или на сайт

страницы:   1   2   3   4
Ваша оценка этого документа будет первой.
Ваша оценка:
Разместите кнопку на своём сайте или блоге:
rudocs.exdat.com

Загрузка...
База данных защищена авторским правом ©exdat 2000-2017
При копировании материала укажите ссылку
обратиться к администрации
Анализ
Справочники
Сценарии
Рефераты
Курсовые работы
Авторефераты
Программы
Методички
Документы
Понятия

опубликовать
Загрузка...
Документы

Рейтинг@Mail.ru
наверх