Глава 6 - створення власного контролера руху

Створення власного контролера руху

Переміщення об'єктів і польоти - це, звичайно, добре, але що робити, якщо вам знадобиться щось інше? Давайте подивимося, як створити контролер руху для більш цікавого об'єкта - космічного танка Mark VII з доплерівським радаром X-діапазону. Танк може пересуватися по поверхні планети з різною швидкістю і повертати на ходу. Його вежа швидко обертається, а гармата піднімається. Здається, я забув згадати про радар, який радісно крутиться на вежі? На рис. 6.11 зображений танк Mark VII при виконанні бойового завдання.


Глава 6 - створення власного контролера руху

Мал. 6.11. Космічний танк Mark VII з доплерівським радаром X-діапазону

Хмм. ви звернули увагу на те, що у танка немає коліс? Можу запропонувати два пояснення:

Це літаючий танк.

Мені було ліньки возитися з колесами.

На рис. 6.12 зображена діаграма рухомих частин танка (разом з колесами). Ілюстрація наведена на кольоровій вкладці.


Глава 6 - створення власного контролера руху

Мал. 6.12. Складові частини танка

У додатку Tank клас C3dTank є похідним від C3dFrame. Послідовність, в якій будується танк, така: спочатку ми приєднуємо корпус до зовнішнього кадру, потім приєднуємо вежу до корпусу і в останню чергу приєднуємо гармату і радар до башти. Радар наводиться в постійне обертання. Гармата може підніматися і опускатися, обертаючись навколо своєї горизонтальної осі. Вежа може обертатися навколо вертикальної осі корпусу.

Перед тим як займатися контролером, давайте розглянемо фрагмент коду, в якому створюється танк, щоб нам було легше керувати ним:

Єдине, що може тут здатися дивним, - це те, що я використовував для радара окремий фрейм. Мені довелося вчинити так через те, що в первинному варіанті танка вісь y радара була зміщена щодо того місця, де я хотів розташувати радар. Тому я поставив початок координат фрейма в тій точці вежі, де поміщається вісь, і змістив об'єкт-радар всередині фрейму, щоб він знаходився над віссю обертання (рис. 6.13).


Глава 6 - створення власного контролера руху

Мал. 6.13. Розміщення радара всередині фрейму

Всі об'єкти, з яких складається наш танк, були створені в 3D Studio і перетворені в формат .X за допомогою утиліти conv3ds. що входить в DirectX 2 SDK. Вони були включені в файл додатка RC2 в якості ресурсів:

Тег XOF. зустрічається в файлі ресурсів, насправді можна замінити будь-який інший рядком. Я вибрав XOF лише тому, що таке розширення використовується в файлах опису фігур. Єдине місце програми, де зустрічається рядок XOF - функція C3dShape :: Load. де цей рядок використовується для того, щоб відрізняти XOF-файли від інших типів ресурсів.

В клас танка увійшли три функції, що знаходяться в файлі 3dTank.cpp і призначені для регулювання кутів вежі і гармати, а також для стрільби:

Як бачите, щоб визначити положення вежі і гармати, ми обчислюємо вектор напрямку. Потім ми задаємо напрямок об'єкта по відношенню до його батьків; до речі кажучи, саме так функція SetDirection діє за замовчуванням. Але я хотів зробити свій код максимально простим і очевидним, тому при кожному виклику передаю додатковий аргумент - еталонний фрейм.

Танк готовий. Залишилося навчитися керувати ним.

контролер танка

Велика частина коду контролера знаходиться в класах C3dWnd і C3dController. Щоб створити власний контролер, необхідно лише ввести новий клас, похідний від C3dController. перевизначити в ньому функцію OnUpdate і встановити новий контролер в своєму додатку. Однак перед тим, як писати функцію OnUpdate. слід розподілити параметри джойстика по виконуваних функцій. Конфігурація, на якій я зупинився, приведена в таблиці 6.3.

Таблиця 6.3. управління танком

Я вирішив використовувати параметри x і r для поворотів, щоб навіть при наявності самого простого джойстика з двома осями можна було керувати танком. Я вибрав для цього додатка джойстик SideWinder Pro - він дає більш реалістичні відчуття, ніж SpaceBall. До того ж кнопка вибору виду, що знаходиться на рукояті джойстика, чудово підходить для поворотів вежі.

Визначившись з керуванням, можна писати програму. Весь код контролера складається з двох функцій:

Конструктор лише инициализирует деякі локальні дані; вся справжня робота виконується в функції OnUpdate. Параметр y задає поточну швидкість. Поточна позиція і напрямок танка зберігаються в об'єктах C3dVector. Параметри x і r визначають матрицю повороту, яка задає нову орієнтацію вектора напрямку. Вектор спрямування множиться на швидкість - отриманий вектор зміщення складається з вектором колишнього положення танка. Потім ми переміщаємо танк в нове положення і задаємо для танка новий напрямок.

Кнопка вибору виду визначає напрямок вежі. Ми перевіряємо стан кнопок 3 та 4, і якщо вони натиснуті, то кут підйому гармати змінюється на невелику величину. Якщо тримати одну з цих кнопок, утримуючи, ствол гармати буде повільно підніматися або опускатися.

Залишається лише врахувати кнопку стрільби. Перевірка локальної змінної m_bWasFire запобігає повторним постріли, утримуючи кнопку - автоматична зброя в США заборонено.

Остаточне складання додатка

За основу програми Tank був узятий код додатка Moving. Я видалив непотрібні команди меню і замінив поточну фігуру об'єктом C3dTank. Крім того, я включив в макет фонове зображення. Нижче наведено фрагмент коду, в якому відбувається настройка головного вікна програми:

Функція NewScene створює макет і задає початкові умови:

Якщо танк поїде за край вікна і загубиться, можна виконати команду File&mnsp;| New. щоб викликати функцію NewScene і почати все заново. Залишилося сказати про останній зміні, внесеному мною, - коли контролер запитує покажчик на фрейм, з яким він повинен працювати, функція OnGetCtrlFrame повертає йому покажчик на танк:

Зверніть увагу - хоча функція повинна повертати покажчик на C3dFrame. насправді вона передає покажчик на об'єкт C3dTank. Ми користуємося цією обставиною в функції OnUpdate. код якої був наведений вище. Якщо раніше вам могло здатися, що перетворення покажчика на C3dFrame в покажчик на C3dTank виглядає сумнівно, то тепер неважко переконатися, що ми мали повне право поступати таким чином.

Схожі статті