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

Управление щелчками мыши


Внутри этого небольшого фрагмента кода находится вызов функции vCheckInput(). Возможно, вы недоумеваете для чего здесь нужен вызов функции timeGetTime(). Дело в том, что современные компьютеры настолько быстрые, что единственное нажатие на кнопку мыши длится десятки итераций цикла обработки сообщений. В результате одно нажатие на кнопку мыши активирует пункт меню десятки раз. Это приведет к проблемам, поскольку ваш интерфейс окажется слишком чувствительным к сделанным пользователем щелчкам мышью. Чтобы побороть проблему, я установил таймер, который разрешает обработку сообытия мыши не чаще чем раз в 50 милисекунд. Код проверяет текущее время и смотрит прошло ли 50 милисекунд с момента последнего вызова функции vCheckInput(). Если прошло достаточно времени, функция вызывается снова и таймер сбрасывается. Если время еще не истекло, выполнение кода продолжается, но никакой проверки введенных данных не происходит. Величина 50 милисекунд выбрана мной произвольным образом и вы можете изменить ее в соответствии с вашими вкусами. Если вам непонятно, какой эффект она оказывает, установите значение 0 и запустите пример (попробуйте щелкнуть в меню по кнопке Options).

Функция vCheckInput() проверяет текущую позицию указателя мыши и выполняет действия, зависящие от того, какое меню в данный момент показывается пользователю. Вот как выглядит код этой функции:

void vCheckInput(void) { bool bRet; char szZoneHit[64]; POINT Point; RECT rcWindowRect; int iMouseX; int iMouseY;

// Проверка смещения окна GetWindowRect(g_hWnd, &rcWindowRect); // Обновление позиции указателя мыши GetCursorPos(&Point); // Вычисление реальных координат указателя мыши iMouseX = Point.x - g_iXOffset - rcWindowRect.left; iMouseY = Point.y - g_iYOffset - rcWindowRect.top; // Проверка попадания в активную зону bRet = MZones.bCheckZones( (short)iMouseX, (short)iMouseY, szZoneHit, g_bLeftButton, g_bRightButton); if(bRet) { // ЛОГИКА ДЛЯ ТИТУЛЬНОГО ЭКРАНА if(g_iCurrentScreen == 0) { // Переход к главному меню if(!stricmp(szZoneHit, "TITLE_SCREEN")) { // Делаем главное меню текущим g_iCurrentScreen = 1; // Устанавливаем активные зоны vSetupMouseZones(1); } // Переход к экрану завершения игры else if(!stricmp(szZoneHit, "EXIT_BUTTON")) { // Делаем завершающий экран текущим g_iCurrentScreen = 2; // Устанавливаем активные зоны vSetupMouseZones(2); } } // ЛОГИКА ГЛАВНОГО МЕНЮ else if(g_iCurrentScreen == 1) { // Переход к экрану завершения игры if(!stricmp(szZoneHit, "EXIT_BUTTON")) { // Делаем завершающий экран текущим g_iCurrentScreen = 2; // Устанавливаем активные зоны vSetupMouseZones(2); } else if(!stricmp(szZoneHit, "MAINMENU_NEWGAME")) { // Добавьте сюда код для начала новой игры } else if(!stricmp(szZoneHit, "MAINMENU_LOADGAME")) { // Добавьте сюда код для загрузки игры } else if(!stricmp(szZoneHit, "MAINMENU_SAVEGAME")) { // Добавьте сюда код для сохранения игры } else if(!stricmp(szZoneHit, "MAINMENU_OPTIONS")) { // Делаем меню параметров текущим g_iCurrentScreen = 7; // Устанавливаем активные зоны vSetupMouseZones(7); } } // ЛОГИКА ЭКРАНА ЗАВЕРШЕНИЯ ИГРЫ else if(g_iCurrentScreen == 2) { // Выходим из программы, если пользователь // нажмет любую кнопку мыши if(!stricmp(szZoneHit, "TITLE_SCREEN")) { // Сообщаем WinMain() о завершении программы g_iCurrentScreen = 3; } } // ЛОГИКА МЕНЮ ПАРАМЕТРОВ else if(g_iCurrentScreen == 7) { // Переход к экрану завершения игры if(!stricmp(szZoneHit, "EXIT_BUTTON")) { // Делаем экран завершения игры текущим g_iCurrentScreen = 2; // Устанавливаем активные зоны vSetupMouseZones(2); } // Возврат к главному меню else if(!stricmp(szZoneHit, "OPTIONS_BACK")) { // Делаем главное меню текущим g_iCurrentScreen = 1; // Устанавливаем активные зоны vSetupMouseZones(1); } } } }



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