Этот урок рассказывает о том, как обнаруживать нажатия клавиш. Мы будем писать простую программу, показывающую какая из клавиш-стрелок была нажата. Мы уже делали простую обработку событий (SDL_QUIT). Сегодня мы разберемся с тем, как определять что была нажата клавиша, и что это была за клавиша.

    //Сгенерировать поверхности с сообщениями
    upMessage = TTF_RenderText_Solid( font, "Up was pressed.", textColor );
    downMessage = TTF_RenderText_Solid( font, "Down was pressed.", textColor );
    leftMessage = TTF_RenderText_Solid( font, "Left was pressed", textColor );
    rightMessage = TTF_RenderText_Solid( font, "Right was pressed", textColor );

После того, как все инициализировано и загружено, мы генерируем 4 поверхности с сообщениями. Мне вероятно следовало бы проверять на ошибки при рендеринге текста, но ... хм, так меньше печатать.

    //Если есть событие для обработки
    if( SDL_PollEvent( &event ) ) {
        //Если была нажата клавиша
        if( event.type == SDL_KEYDOWN ) {

Теперь, когда мы хотим проверить была ли нажата клавиша, мы проверяем равен ли тип события SDL_KEYDOWN.

            //Выбрать правильное сообщение
            switch( event.key.keysym.sym ) {
                case SDLK_UP: message = upMessage; break;
                case SDLK_DOWN: message = downMessage; break;
                case SDLK_LEFT: message = leftMessage; break;
                case SDLK_RIGHT: message = rightMessage; break;
            }
        }
        //Если пользователь хочет выйти
        else if( event.type == SDL_QUIT ) {
            //Выходим из программы
            quit = true;
        }
    }

Теперь, если была нажата клавиша, мы должны проверить что это была за клавиша.SDL_PollEvent() кладет данные типа SDL_KEYDOWN в структуру события как SDL_KeyboardEvent по имени key:и внутри key находится структура keysym:а внутри keysym SDL_Key под названием sym, который хранит информацию о том какая кнопка была нажата. Если была нажата стрелка вверх, sym будет равен SDLK_UP и мы выберем сообщение "вверх", если sym будет равен SDLK_DOWN мы выберем сообщение "вниз" и т.д. Посмотреть все определения SDL_Key вы можете в документации по SDL. Так же мы проверяем не хочет ли пользователь выйти и соответствующим образом обрабатываем это событие. Замечание: Некоторые IDE, типа Code::Blocks, включают флаг -Wall по умолчанию. Из-за этого компилятор может жаловаться на то что у вас нет выражений case для всех возможных значений. Чтобы компилятор перестал жаловаться просто добавьте в конец блока switch:

default : ;

    //Если есть сообщение для отображения
    if( message != NULL ) {
        //Скопировать сообщение на экран
        apply_surface( 0, 0, background, screen );
        apply_surface(
            ( SCREEN_WIDTH - message->w ) / 2,
            ( SCREEN_HEIGHT - message->h ) / 2,
            message,
            screen
        );
        //Обнулить указатель на поверхность сообщения
        message = NULL;
    }
    //Обновить экран
    if( SDL_Flip( screen ) == -1 ) {
        return 1;
    }

Если поверхность сообщения никуда не указывает, ее значение будет NULL и ничего не будет скопировано. В обратном случае мы копируем фон и затем помещаем сообщение по центру экрана. Способ центрирования заключается в вычитании ширины/высоты копируемой поверхности из ширины/высоты поверхности на которую вы копируете. А так как поверхность должна быть отцентрирована, отступ с обеих сторон должен быть одинаковым, поэтому мы делим оставшееся расстояние пополам. После этого мы сбрасываем сообщение в NULL и обновляем экран.

Скачать исходники и материалы