Реклама:

TLifeObject=class(TMovable)

procedure Go(direction:TDirection); virtual;

procedure GoTo(obj:TObject); virtual;

procedure AI; virtual;

public

life:integer; end;

TBattleCharacter=class(TLifeObject) procedure Attack(obj: TLifeObject); virtual; end;

TMage=class(TBattleCnaracter) public

mana:integer ; end;

TTroll=class (TMage)

procedure CheckCollision(obj: TMovable); override; procedure Go(direction:TDirection); override; procedure GoTo(obj:TObject); override; procedure AI; override;

procedure Attack(obj: TLifeObject); override; end;

TAmmo= class(TMovable) public

speed: integer; attacktype:TAttackType; power:integer; end;

TArrow=class(TAmmo)

procedure CheckCollision(obj: TMovable); override;

end;

TSheep=class(TLi feObj ect)

procedure CheckCollision(obj: TMovable); override; procedure Go(direction:TDirection); override; procedure GoTo(obj:TObject); override; procedure AI; override ,-end;

TOrk=class(TBattleCharacter)

procedure CheckCollision(obj: TMovable); override procedure Go(directionrTDirection); override; procedure GoTo(obj:TObject); override; procedure AI; override;

procedure attack(obj: TLifeObject) override; end;

Золотые правила иерархии

У каждого конкретного движка своя собственная, совершенно неповторимая система иерархии. Но... Есть несколько общих принципов создания удобной иерархии, которые используются разработчиками во всех качественных движках. При построении собственного игрового "двигателя" обязательно нужно иметь их в виду.

• Принцип первый. Если два класса, относящиеся к разным базовым классам, имеют одинаковые по смыслу и реализации свойства или методы, значит, вы что-то не так сделали. Необходимо пересмотреть всю систему и сделать ее неизбыточной.

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

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

Полцарства за наследника

В коде, который мы только что рассмотрели, все методы, объявленные в родительском классе, переобъявляются в финальных классах. Причем в родительском классе после объявления стоит слово virtual, а в классе потомка — override. Такой прием называется перегрузкой. Давайте разберемся, зачем он нужен.

Возьмем для примера метод Attack, который есть у тролля и у орка. Если подумать, реализация этого метода должна быть для них разной. Ведь орк атакует оружием, а тролль — не только оружием, но и магией. Допустим, по нашей задумке тролль всегда атакует противника магией на дальних дистанциях, а оружием — на ближних. Орк атакует только оружием на ближних дистанциях. В реализации метода Attack для этих двух персонажей будут общая часть (атака оружием) и части различные. Можно также сказать, что на ближних дистанциях тролль ничем не отличается от орка. Тогда атаку обычным оружием мы реализуем в методе Attack у родительского класса орка — TBattleCharacter, а атаку магией реализуем в родительском классе тролля — тмаде. Причем у всех потомков тмаде будет возможность драться как магией (так как эта возможность заложена в сам этот класс), так и обычным оружием (так как эта возможность присутствует у одного из предков— TBattleCharacter). Допустим, метод Attack у TBattleCharacter уже реализован. Тогда метод Attack у всех магов, в том числе и у тролля, может выглядеть так:


⇐ Предыдущая страница| |Следующая страница ⇒