Программирование стратегических игр с DirectX 9.0
bda5893f

Функция WinMain()


Первой представляющей интерес функцией является WinMain(). Как и в любой программе для Windows, она является главной точкой входа в код. Вот как выглядит ее листинг:

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { HWND hWnd; MSG msg; WNDCLASSEX wndclass; RECT rcWindowClient; // Инициализация класса окна wndclass.cbSize = sizeof(wndclass); wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = fnMessageProcessor; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = "Title Demo"; wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); // Регистрация класса окна if(RegisterClassEx(&wndclass) == NULL) { // Выход из программы при сбое exit(1); } // Создание окна hWnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, "Title Demo", "D3D_TitleScreen", WS_OVERLAPPEDWINDOW, 0, 0, g_iWindowWidth, g_iWindowHeight, NULL, NULL, hInstance, NULL); // Отображение окна ShowWindow(hWnd, iCmdShow); // Получение размеров клиентской области GetClientRect(hWnd, &rcWindowClient); // Вычисление смещения визуализации на основе размеров клиентской области g_iXOffset = (g_iWindowWidth - (rcWindowClient.right - rcWindowClient.left)); g_iYOffset = (g_iWindowHeight - (rcWindowClient.bottom - rcWindowClient.top)); // Изменение размеров окна, чтобы они соответствовали желаемому разрешению SetWindowPos(hWnd, NULL, 0, 0, g_iWindowWidth + g_iXOffset, // Ширина g_iWindowHeight + g_iYOffset, // Высота NULL); // Очистка структуры сообщения ZeroMemory(&msg, sizeof(msg)); // Инициализация Direct3D if(SUCCEEDED(InitD3D(hWnd))) { // Инициализация виртуального буфера для отображения четырехугольников vInitInterfaceObjects(); // Вход в цикл сообщений while(msg.message != WM_QUIT) { if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } else { // Визуализация сцены vRender(); } } } // Освобождение ресурсов и выход из приложения vCleanup(); UnregisterClass("Title Demo", wndclass.hInstance); return 0; }

Чтобы отделить код, относящийся к Direct3D от «стандартного» кода программы для Windows, взгляните на рис. 6.12.


Рис. 6.12. Структура вызовов других функций в функции WinMain()

На рис. 6.12 показан список функций, которые я использую в WinMain(). Они приведены в порядке их исполнения. Обратите внимание, что большинство вызовов не относятся к Direct3D. Это объясняется тем, что функциия WinMain() содержит в основном код инициализации, а не код выполнения или визуализации.

Первым интересным фрагментом кода является вызов функции GetClientRect(). Вы можете недоумевать, почему она внесена в список. Для лучшего понимания позвольте мне рассказать о некоторых особенностях написания программ для работы в оконном режиме.


Функция WinMain() в рассматриваемой программе изменилась весьма незначительно. Взгляните на приведенный ниже фрагмент кода, в котором выделены главные отличия:

// Инициализация Direct3D if(SUCCEEDED(InitD3D(hWnd))) { // Инициализация виртуального буфера для отображения четырехугольников vInitInterfaceObjects(); // Инициализация активных зон vSetupMouseZones(0);

// Начало цикла обработки сообщений while(msg.message != WM_QUIT) { if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } else { // Если все нормально, обработать щелчок мыши if(timeGetTime() > dwInputTimer) {

// Проверка входных данных

vCheckInput();

dwInputTimer = timeGetTime() + 50;

}

// Проверка необходимости выхода из программы if(g_iCurrentScreen == 3) {

break;

}

// Визуализация сцены vRender(); } } }

Первым изменением является добавленный вызов функции vSetupMouseZones(). Программа только что была запущена и вызов этой функции необходим для того, чтобы установить активные зоны для первого экрана. На рис.6.23 показан первый экран, выводимый программой.


Рис. 6.23. Первый экран программы D3D_MouseZones

Сейчас изображенный на рис. 6.23 экран должен выглядеть для вас очень знакомо. Это титульный экран игры Battle Armor. Поскольку делать на титульном экране почти нечего, я устанавливаю лишь пару активных зон. Давайте перейдем к коду функции vSetupMouseZones(), чтобы увидеть какие зоны используются на титульном экране.



Содержание раздела