grupa AntalisaСтатьи

Класс Модификаторов

Автор:

Общаясь со мной в коментах (http://www.gamedev.ru/community/ants/forum/?id=54203) Lion007 убедил меня создать классы модификаторов, каждый из которых ответственен только за свое воздействие на объект (изменение координат объектов в соответствии с воздействием на них). А Менеджер сцены занимается только отрисовкой объектов.

Для совместимости всех используемых мной типов, и во избежание перекрестных ссылок модулей друг на друга, мне пришлось вынести описание типов в отдельный модуль под названием GlobalTypeVar. Далее, создал новый модуль под названием modificator в котором я описываю родительский класс TModificator и его потомка TTranslater2D. Вот так выглядит предок:

TModificator=class
  private
  FObjectCount:Cardinal;
  FIndexArray:array of Cardinal;
  FP:PObjectArray; //указатель
  public
  constructor Create;
  destructor Destroy;

  property Count:Cardinal read FObjectCount;

  procedure SetCount(const Count:Cardinal);
  procedure AddObject(Number:Cardinal); virtual;
  procedure RemoveObject(Number:Cardinal); virtual;
  procedure ConnectToObjectList(ObjectArray:TObjectArray); virtual;

  procedure UpdateObjects(ObjectArray:TObjectArray); virtual;
  end;

В переменной FObjectCount будет храниться колличество подключенных к данному модификатору объектов. В массиве FIndexArray будут храниться индексы, по-которым можно обратиться к нужным объектам.
Сами объекты (точнее, записи свойств объектов) будут храниться в массиве-внутреннем поле Менеджера Сцены (FObjectBANK: TObjectArray), где будут храниться все без исключения объекты (записи описывающие свойства объектов).
Подключение объекта к модификатору - это занесение его индекса в массив в модификаторе, при этом счетчик числа подключенных объектов инкрименируется.
Для задания размера данного массива я описал метод SetCount(Count).
Отключение объекта от модификатора осуществляется процедурой RemoveObject(Number) - в ней находится элемент массива хранящий указанный номер, на его место записывается номер (индекс) последнего записанного в массив объекта, а счетчик числа подключенных объектов декрементируется (уменьшается на единицу).  А так как в последствии будут использоваться элементы массива только от нуля до значения счетчика, то элементы по адресу больше значения счетчика будут хранить мусор, но нас это мало беспокоит.
Процедура UpdateObjects(); переопределяется у каждого потомка - таким образом, при обращении к данному экземпляру класса как классу-родителю, получаем полиморфизм. (Название методов одно и то же, а выполняемые действия разные).
К сожалению, мне пришлось в данной процедуре явно обращаться к массиву объектов UpdateObjects(ObjectArray:TObjectArray) так как процедура  ConnectToObjectList  где использовался указатель на массив в последствии выдавал ошибку в процедуре UpdateObjects();

procedure TModificator.ConnectToObjectList(ObjectArray:TObjectArray);
begin
  FP:=@ObjectArray; //Сохраняем адрес
end;

в процедуре UpdateObjects(); обращение к элементам массива объектов происходило ввиде такой записи (где и происходил сбой программы):
FP^[FIndexArray[loop]].StartX:=....... Поэтому процедура UpdateObjects(ObjectArray:TObjectArray); стала нуждаться в аргументе ObjectArray.

Далее, в менеджер сцены добавил    переменную FTranslater2D:TTranslater2D; //потомок TModificator-а
Пока текст программы грубо-обтесанный - я лишь в ускоренном темпе попытался оттестировать новый класс и сунул его в несколько разных методов менеджера сцены, так что пока без полиморфизма, без специальных процедур подключения модификаторов (пока у меня описан только один потомок данного класса - TTranslater2D.

В процедуре TAPSceneMenager.ObjectsPropertiesFromFile(FileName:String);
Получаю колличество записей в файле, в соответствии с этим числом задаю размеры массивов в классах:
  Size:=FileSize(F); //Определим колличество записей
  SetLength(FObjectBANK,Size); //Задаем колличество объектов равным колличеству записей в файле
  FTranslater2D.SetCount(Size); //Задаем длину списка в модификаторе

Пока я не нашел другого места, поэтому прямо в этой же процедуре добавил несколько объектов в список модификатора:
  FTranslater2D.AddObject(0);
  FTranslater2D.AddObject(1);
  //FTranslater2D.AddObject(2);
  FTranslater2D.AddObject(3);
  //FTranslater2D.AddObject(4);

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

Далее, в процедуру TAPSceneMenager.UpdateObjects; добавил:
FTranslater2D.UpdateObjects(FObjectBANK); - здесь происходит изменение координат объектов в соответствии с особенностью конкретного модификатора FTranslater2D.
Текст главного модуля main не изменился.

Осталось написать методы Менеджера Сцены, которые будут подключать и отключать нужные модификаторы.

Исходники можно скачать ((90.49 Кб) по адресу: http://www.gamedev.ru/download/?id=4213

12 сентября 2006

Комментарии [3]