А также, я посчитал необходимым добавить в каркас следующие функции:
Рисование Курсора (CCursor).Это позволило сделать каркас законченным приложением. Все равно практически всегда требуется рисовать собственный курсор. Возможно реализация, которая предлагается спорна и требует доработки, но у меня она работает без ошибок как в оконном режиме, так и в полноэкранном режиме, кроме того, особенностью (но не недостатком) этого класса можно считать только то, что инициализация курсора происходит изнутри класса, то есть не определяется необходимая функциональность для смены загруженного курсора на лету. Но это, в общем, не сложная задача, а здесь я ее не реализовал только потому, что не посчитал нужным. Реализована анимация курсора и реализована смена стадий курсора, в заголовочном файле описан пример добавления новых стадий (кстати, как вам мой английский :)), а в функции Create() — создания анимационных цепочек.
Распаковка ресурсов из файла ресурсов (ResourceManager).Я прекрасно понимаю, что реализация, которая есть в этом классе, неидеальна, но это лучше, чем отдельно лежащие ресурсы, пусть даже записанные не в общедоступном формате. А при необходимости реализацию можно дописать или переделать — было бы желание. Используется CFolder класс, основанный на реализации одной из олимпиадных задачек (задача про хакера Билла у которого накрылся жесткий диск). Он создает и удаляет дерево каталогов по названию файла, начиная с определенного пути (названия файлов должны быть относительными). Описание использования класса есть в main.cpp и мне кажется достаточно логичным.
Сохранение и восстановление параметров приложения из файла конфигурации (CConfigFile).Эта возможность была означена как необходимая для качественного графического приложения. Класс простой, использование тоже несложное. Единственное ограничение - нужно переписать функцию класса CConfigFile::restore() - она должна восстанавливать сбойный конфигурационный файл к первоначальному состоянию. Эта специфичная задача требует специфичной реализации для каждого приложения, и поэтому здесь я ее не провел, но при расширении приложения, я обязательно занесу некоторые значения в реализацию этой функции. Кстати, изменение разряда строк не введено, поэтому следите, чтобы параметр, определенный в файле и строка, по которой вы получаете его параметр, не только совпадали, но и были в одном разряде.
Сохранение информации о выполнении приложения в файл протокола.Эта реализация не принадлежит мне, автора я не знаю, но все равно хочется сказать ему спасибо. Стандартная качественная реализация. Исходник поставлялся с одним из примеров NVIDIA, поэтому, я думаю, его использование не является нарушением авторского законодательства.
В каркасе рисуется счетчик FPS, для его реализации были введены классы: ueFontD3D — это CD3DFont из DirectX SDK, переименован он был просто из соглашения об именовании. Под него написан класс Label, который заданным шрифтом выводит информацию на экран. Также строчку можно скрыть или сделать серой (dimmed). Им выводится счетчик FPS и некоторая дополнительная информация.
В каркасе реализовано перемещение по сцене и изменение направления взгляда (от первого лица). Используются следующие клавиши:
LEFT ARROW, A — стрейф влево.
RIGHT ARROW, D — стрейф вправо.
UP ARROW, W — вперед.
DOWN ARROW, S — назад.
C — вверх.
V — вниз.
Для изменения наклонов головы достаточно прижать правую клавишу мыши и передвигать ей — перемещение вдоль оси Y — голову вверх/вниз, перемещение вдоль оси X — голову влево/вправо. Направление вдоль оси Y инвертировано. Если вы хотите ввести возможность инвертировать мышку, то можно ввести в конфигурационный файл переменную inverty, которая будет принимать значение 1 или -1, и читать ее в программе. А в месте изменения параметра m_iFi на нее просто умножать.
Соглашения по использованию каркаса:
Используется MFC, статично подключенная к приложению. Часть определений занесена в файл STDAFX.h, а имплементаций в файл STDAFX.cpp. Они активно используются всеми классами, поэтому определены именно там. Все общие определения типов сделаны в common.h — файле с глобальными определениями, используемыми каркасом и графическими классами. Вспомогательные классы в нем ничего не хранят. Для именования функций используется система, в которой главное слово, по которому подразделяются классы функций, ставится перед остальной частью. Например, если функция относится к движку (каркасу), то она имеет префикс ueEngine*, если к событиям — ueAction* и т. д.
Читать дальше