Единственным приемлемым вариантом управления игрой для Symbian OS является клавиатура. Конечно, эта ОС поддерживает световое перо, но устройств, оснащенных им, пренебрежимо мало. С другой стороны, клавиатура - лучшее решение для большинства игр. При разработке следует иметь в виду, что клавиатуры телефонов очень маленькие, а клавиши могут располагаться как угодно. В идеале пользователь должен иметь возможность самостоятельно настроить управление.
Обработка событий клавиатуры реализуется достаточно просто:
AppUI принимает клавиатурные события в HandleKeyEventL.
AppUI передает событие активному в настоящее время виду, вызывая его метод OfferKeyEventL.
При использовании AddToStackL, события клавиатуры автоматически передаются от AppUI активному виду, посредствам добавления записи в стек управления. События клавиатуры не должны обрабатываться в AppUI, за исключением случаев, когда клавиша выполняет какие-нибудь глобальные действия.
TKeyEvent и TEventCode передаются в качестве параметров OfferKeyEventL. Они содержат важную информацию:
Нажатие клавиш приводит к последовательному возникновению трех событий:
На практике EEventKeyDown используются для определения команд пользователя. Если Вы хотите чтобы какое-то игровое действие происходило, пока нажата клавиша (Например, пока Вы жмете клавишу "влево" космический корабль смещается влево), используйте флаги. Установите флаг при возникновении события EEventKeyDown и снимите его при EEventKeyUp.
Если клавиша удерживается продолжительное время, событие EEventKey передается приложению несколько раз. Частоту возникновения этого события можно задать с помощью RWsSession::SetKeyboardRepeatRate. Вы можете использовать это событие как таймер. Например, можете выпускать снаряды через определенные интервалы времени.
TKeyEvent содержит два различных кода для клавиши - скан код и символьный код. Для управления игрой удобней использовать скан код (TKeyEvent::iScanCode), поскольку символьный код (TKeyEvent::iCode) может меняться при многократном нажатии клавиши, а в игре важен сам факт нажатия клавиши.
По умолчанию, Вы не можете обработать одновременное нажатие нескольких клавиш. (Обрабатывается лишь первая из нажатых.) Это явление называется блокировкой клавиш (key blocking). При обычном режиме работы не блокируются только клавиши "power" и "edit". Чтобы снять блокировку и получить возможность обрабатывать несколько клавиш одновременно необходимо использовать метод SetKeyBlockMode класса CAknAppUi. Не рекомендуется без особой надобности снимать блокировку. Это системная установка и ее изменение может сказаться на работе других приложений. Ниже приведен пример кода, снимающего блокировку:
void CMyGameAppUi::ConstructL() { SetKeyBlockMode(ENoKeyBlock); }
Приведем пример использования метода OfferKeyEventL в игре
TKeyResponse CMyGameView::OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType) { switch(aType) { case EEventKey: if(aKeyEvent.iScanCode== EStdKeyNkp5|| aKeyEvent.iScanCode== EStdKeyDevice3) { // EEventKey вызывается через установленные // промежутки времени, пока удерживается клавиша. // Даем команду движку выпустить очередную ракету. iMyGameEngine->Fire(); return EKeyWasConsumed; } break; case EEventKeyDown: switch(aKeyEvent.iScanCode) { // Нажата клавиша. Начинаем двигать корабль // влево или вправо. Движение продолжается // пока удерживается клавиша case EStdKeyNkp4: case EStdKeyLeftArrow: iMyGameEngine->SetShipMovingTo( ELeft); return EKeyWasConsumed; case EStdKeyNkp6: case EStdKeyRightArrow: iMyGameEngine->SetShipMovingTo( ERight); return EKeyWasConsumed; } break; case EEventKeyUp: switch(aKeyEvent.iScanCode) { // Кнопка отпущена. Прекращаем движение case EStdKeyNkp4: case EStdKeyLeftArrow: case EStdKeyNkp6: case EStdKeyRightArrow: iMyGameEngine->SetShipMovingTo( ENowhere); return EKeyWasConsumed; } break; } return EKeyWasNotConsumed; }
Перевод:aRix