Класс CUnit
Вот мы и рассмотрели все необходимые для подразделения базовые классы. У нас есть готовые к использованию данные защиты, атаки, передвижения и анимации. Отсутствует только клей, который соединит эти разрозненные компоненты вместе. По отдельности эти детали не слишком полезны, но собранные вместе они образуют подразделение. Здесь и вступает в игру класс CUnit. Он содержит указатели на различные базовые типы, а также ряд переменных состояния. Базовые типы хранят те данные подразделения, которые никогда не меняются, а данные состояния могут изменяться в зависимости от того, что происходит с подразделением. Все это иллюстрирует рис.8.20.
Рис. 8.20. Структура объекта подразделения
На рис. 8.20 видно, что класс подразделения состоит из базовых классов и данных состояния. В блоке данных состояния находятся переменные для различных параметров, таких как текущее количество очков повреждений, направление поворота, местоположение и текущая скорость. Обратите внимание на пунктирную линию, соединяющую максимальное количество очков повреждений в базовом объекте защиты и текущее количество очков повреждений в данных состояния. Текущее количество очков повреждений показывает сколько еще повреждений может получить подразделение до его уничтожения. Это значение изменяется когда подразделение получает повреждения или восстанавливается. Поскольку подразделения не могут совместно использовать одно общее значение здоровья, текущее значение здоровья хранится каждым подразделением локально в его данных состояния. Базовый тип защиты вступает в игру, когда вычисляется максимально возможный для подразделения показатель здоровья. Это значение никогда не изменяется, и поэтому базовый класс — наилучшее место для него.
Держа в уме информацию с рис. 8.20, взглянем на исходный код:
class CUnit { public: CUnitDefense *m_Defense; CUnitOffense *m_Offense1; CUnitOffense *m_Offense2; CUnitOffense *m_Offense3; CUnitMovement *m_Movement; CUnitAnimation *m_Animation; int m_iType; int m_iCurHitPoints; float m_fCurSpeed; float m_fXPos; float m_fYPos; float m_fRot; float m_fScale; int m_iUnitID; int m_iParentID; char m_szName[64]; bool m_bActive; int m_iOwner; int m_iCurAnimFrame; int m_iCurAttackFrame; int m_iCurStillFrame; int m_iCurMoveFrame; int m_iCurDieFrame;
public: CUnit(); ~CUnit(); virtual void vReset(void); virtual void vSetBaseValues( CUnitDefense* ptrDef, CUnitOffense* ptrOff1, CUnitOffense* ptrOff2, CUnitOffense* ptrOff3, CUnitMovement* ptrMove, CUnitAnimation* ptrAnim); virtual void vSetPosition(float fX, float fY); };
С точки зрения количества функций класс не выглядит слишком сложным. Большая часть кода состоит из объявлений необходимых для игры переменных состояния. Это ни в коем случае нельзя считать достаточным для завершенного класса подразделения. Перечисленных переменных состояния достаточно только для рассматриваемого примера. В реальной игре их будет гораздо больше!