Программирование 3D-игр в DirectX на Delphi
 
         
    [Главная] [Новости] [Статьи] [Игры] [Проекты] [Автор]  
         
  Основы 3D-программирования DirectX8.1 в Delphi 6-7: теоретические и практические основы создания игр.  
     
 
Создание игрового меню и другие сопутствующие заметки
 
     
  Продолжаем серию уроков, посвященных разработке Delphi DirectX игры. В данном уроке показано как создать игровое главное меню с использованием 2D-изображений на поверхности 3D-сцены. Если тема покажется Вам сложной, то лучше сначала познакомиться с Выводом 2D-изображения на поверхность 3D-сцены (Вывод заставки).  
     
  [Все уроки]  
     
  Урок носит характер полезных замечаний и рабочих заметок. Пример позволит Вам создать реальное игровое меню для реальной игры.  
       
  ПОСТАНОВКА ЗАДАЧИ: Требуется организовать вывод меню в виде 2D-изображений (текстур) на поверхности 3-х мерной сцены.

Что Мы рассмотрим:

- Как подготовить изображения для вывода меню?

- Как организовать работу меню?

- Как улучшить объектно-ориентированный код для использования GDI-объектов?

 
     
 

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

- архив с исходным кодом; (529 Кб)

- архив с ОБЩИМ КОДОМ; (772 Кб)

Архив с исходным кодом содержит пример решения поставленной задачи, архив с общим кодом - содержит дополнительный общий код необходимый при разработке Delphi DirectX 8.1 - приложений.  
     
 

Для начала откомпилируйте пример и запустите приложение. Убедитесь, что всё работает. (Если нет, то читайте файлы readme.txt приложенные к архивам)

 
     
 

Нормально работающий пример (см. файл DOLEngine.exe внутри архива DOLEngine.rar) должен давать следующий результат: создание нормального Windows-окна, быстрое проявление на экране заставки, вывод игрового меню. Перемещение мыши или нажатие клавиш курсора приводит к перемещениям курсора меню. Выход из приложения - выбор пункта меню [Выход]. Работа остальных пунктов меню опущена, т.к. выходит за рамки данного урока.

 
     
  Сначала поговорим о подготовке изображений. После распаковки архива с примером внутри папки вы найдете папку ресурсов Media. Внутри нее есть папка Textures. В ней находятся все изображения, использование которых относится к теме данного урока.  
     
  Файл logo2.jpg - изображение для вывода титульной заставки. Степень сжатия задана так, чтобы файл был более компактен, но с наименьшей потерей качества.  
     
  Реализация вывода заставки находится в методе procedure TD3DGameApp.DrawScreenSplash способ вывода подробно описывался в уроке Вывод заставки.  
     
  Информацию о процессе рисования заставок Вы можете найти в Уроках посвященных работе в Photoshop.  
     
  Сохранение созданного изображения из Photoshop можно произвести выбором пункта меню File > Save As и выбором формата jpg.  
     
 
 
     
  Далее, нажатием кнопки Save (Сохранить) выбирается необходимая степень сжатия JPG-файла -  
     
 
 
     
  В нашем случае для файла logo2.jpg при сохранении была задана степень сжатия (параметр Качество) 7. Надо полагать, что использование опции Прогрессивный приведет к дольшей обработке изображения внутри Direct3D, поэтому для критичных к скорости процессов лучше использовать менее сжатые или вообще несжатые (не JPG) файлы текстур. Как описано в документации по DirectX самый быстрый формат для использования - DDS.  
     
 
 
     
  Для наложения названий пунктов меню (mainmenu.tga) и меню-курсора (mainmenu_btn.tga, mainmenu_btn_down.tga) на поверхность титульного изображения меню (nn_title_mainmenu.jpg) применяется формат TGA. Этот формат позволяет размещать внутри себя изображение для управления прозрачностью (полупрозрачностью) или так называемую альфа-маску.  
     
  О создании альфа-маски рассказано в уроке Создание растительных текстур и объектов сборника Уроки Photoshop.  
     
  Подготовленную альфа-маску очень легко разместить внутри TGA-файла. 1) На слое с подготовленным изображением альфа-маски выделяем всё и копируем. 2) Затем в панели Каналы нажимаем кнопку Создать новый канал 3) Вставляем скопированное содержимое буфера обмена в канал 4) сохраняем файл в формате TGA 32 бит, сжатие RLE.  
     
 
 
     
 
 
     
 
 
     
  Далее остается только загружать и отображать созданные изображения.  
     
 

Рассмотрим содержание примера с исходным кодом (DOLEngine.dpr).

Приложение построено на принципах стандартного WinAPI-приложения. Для лучшего уяснения того, что это такое обратитесь к предыдущим урокам. Хорошим стартом в понимании разработки Delphi DirectX - игр является также пример игры - Donuts3D.

 
     
  Класс приложения - TD3DGameApp. Название класса чисто условное и его легко изменить в своих приложениях. Если Вы заглянете в исходный код (файл Main.pas проекта DOLEngine.dpr), то увидите что данный класс производится от TD3DAbstractApp. Основа данного класса приложения - из Donuts3D с небольшими изменениями.  
     
 

Лучше уяснить структуру и функционирование данного класса можно рассмотрев пример Donuts3D. В контексте данного урока важны следующие опорные моменты:

TGameMainMenu = class(TD3D_GDOListItem) //класс игрового меню, производный от TD3D_GDOListItem

 

 
  Внутри данного класса Вы найдете всё, что относится к реализации работы с меню.  
     
  TGameMainMenu = class(TD3D_GDOListItem)
private
MainMenuTitle: TD3DImage2D; //фон экрана главного меню
MainMenuItems: TD3DImage2D; //изображение названий пунктов меню
MainMenuItemCursor: TD3DImage2D;//курсор меню
MainMenuItemSelected: TD3DImage2D;
//курсор меню в нажатом состоянии

CurrentItem: TGameMainMenuItem;//текущий пункт меню
CurrentPosY: Single;//позиция курсора в меню
bEnterMenu: Boolean;//индикатор того, что пункт меню выбран

procedure EnterItem;//обработка выбора меню
procedure UpdateInput;//опрос состояний клавиатуры и мыши для управления курсором меню
procedure DrawMainMenuScreen;//реализация отрисовки сцены с меню
protected
function DoRender: HResult; override;//вызов процедур выполнения отрисовки
function DoFrameMove: HResult; override;//вызов процедур анимации

function DoInitDeviceObjects(pd3dDevice: IDirect3DDevice8): HResult; override;//реализация загрузки ресурсов в память
function DoRestoreDeviceObjects: HResult; override;//выполнение установок, настройка вершинных и др. буферов
function DoInvalidateDeviceObjects: HResult; override;//сброс установок, настроек
function DoDeleteDeviceObjects: HResult; override;//удаление ресурсов из памяти
public
constructor Create;//создание контейнера объекта данного типа
destructor Destroy; override; //разрушение контейнера объекта данного типа
end;

 
     
  Создание контейнера объекта означает, что объект создается, но действительная загрузка используемых ресурсов (текстур, моделей и т.п.) происходит внутри реализации метода загрузки ресурсов в память (DoInitDeviceObjects).  
     
 

Почему класс меню производится от класса TD3D_GDOListItem ?

В описании класса приложения (TD3DGameApp) вы найдете поле D3D_GDOList: TD3D_GDOList;

 
  Данное поле представляет собой список т.н. объектов GDO (Graphic Device Objects) условно. Это все объекты, представляющие графические ресурсы игры и зависимые от контекста текущего Direct3DDevice-устройства. По причине рутинности выполнения стандартных стадий подготовки графических ресурсов, их код, с использованием класса TD3D_GDO_List можно вынести в код объекта, освободив тем самым код приложения от этих рутинных операций.  
     
  Это и показано в коде объекта меню. Более подробно о назначении класса TD3D_GDOList.  
     
  Следует обратить внимание на вывод 2D-изображений отображающих элементы меню.  
     
  Посмотрите на реализацию метода - procedure TGameMainMenu.DrawMainMenuScreen;  
     
  Для вывода изображений используется метод DrawScaled класса TD3DImage2D. Этим методом необходимо выводить плоское изображение, но не в привычных экранных координатах (разрешении окна приложения по вертикали и горизонтали), а в векторных координатах окна Viewport. Эти координаты относительные и независимы от разрешения окна приложения. Т.к. изображения для вывода элементов меню не квадратные текстуры, то в указанном методе приходится применить коэффициенты масштабирования.  
     
  На первых порах можно подбирать векторные координаты и масштабные коэффициенты опытным путем, что и было сделано в примере реализации меню.  
     
 

Данный пример меню сильно упрощен. Можно и нужно также сделать:

- вывод игрового курсора с отображением текущих векторных координат (будет удобно для подбора координат расположения элементов меню);

- активация указанных (прямоугольных) областей экрана меню при попадании в них курсора;

- специальные пункты экрана главного меню, содержащие сетевые ссылки (например на сайт проекта);

- организация подменю и экранных диалоговых окон (например при выборе [выход] желательно запрашивать подтверждение) и т. д.

 
     
  Как видим организация и создание игрового меню не так тривиальна, как кажется на первый взгляд, особенно для новичков. Кроме того, подход к его реализации и возможностям зависит только от фантазии разработчика. Описанное здесь - не догма, а лишь один из возможных вариантов. Возможно, поэкспериментировав, Вы откроете и что-то своё. Вот это и будет самое главное! Именно тогда можно считать, что цель данного урока достигнута! И можно двигаться дальше в создании более изощренного меню или перейти к следующей стадии создания игры - реализации работы отдельных пунктов меню и, собственно, организации игрового процесса.  
     
     
     
     
     
     
     
     
     
     
     
  [Назад] [Все уроки]  
     
    [Главная] [Новости] [Статьи] [Игры]    
         
(c) Мега Информатик 2006-2007    
Hosted by uCoz