SDL 2 Нажатие пробела не обнаружено, но нажатие пробела работает нормально

Привет, я работаю над проектом / 2D-игрой, и у меня какое-то странное поведение от SDL, и я уверен, что, вероятно, я чего-то не понимаю. Функция ProcessKeys вызывается и отлично работает для всех нажатий клавиш, кроме SDLK_SPACE, и я не могу понять, почему.

Что еще более странно, так это то, что переключатель SDL_KEYUP SDLK_SPACE прекрасно работает. Я попытался использовать код отладки, чтобы распечатать, какая клавиша нажата, и когда вы нажимаете пробел, ничего не регистрируется. Все остальные клавиши на клавиатуре регистрируются в моем операторе отладки в верхней части случая SDL_KEYDOWN.

Если кто-то может видеть, что происходит, я был бы очень признателен.

И если вам нужно увидеть, где его вызывают, дайте мне знать.

SDLKeyboard::KeyState SDLKeyboard::ProcessKeys(SDL_Event * event)
{
switch(event->type)
{
    /* Look for a keypress */
    case SDL_KEYDOWN:
    {
        std::cout << "Key currently pressed" << event->key.keysym.sym << std::endl;
        /* Check the SDLKey values and move change the coords */
            switch(event->key.keysym.sym)
            {
                case SDLK_LEFT:
                {    // rotate the ship left
                    c.setIsTurningLeft(true);
                    return this->keystate = LeftPressed;
                    // add code when user presses left
                    break;
                }
                case SDLK_RIGHT:
                {
                // rotate the ship right
                    c.setIsTurningRight(true);
                    return this->keystate = RightPressed;
                    // add code when user presses right
                    break;
                }
                case SDLK_UP:
                {    
                    // accleration
                    c.setIsAccelerating(true);
                    return this->keystate = UpPressed;
                    // add code when user presses up
                    break;
                }
                case SDLK_SPACE:
                {    
                    // shoot
                    c.setIsShooting(true);
                    std::cout << "keystate = " << this->keystate;
                    return this->keystate = SpacePressed;
                    // add code when user presses space
                    break;
                }
                default:
                {
                    return this->keystate = NotPressed;
                    break;
                }
            }
        break;
    }
    /* We must also use the SDL_KEYUP events to zero the x */
    /* and y velocity variables. But we must also be       */
    /* careful not to zero the velocities when we shouldn't*/
    case SDL_KEYUP:
    {   
        std::cout << "Key currently pressed" << event->key.keysym.sym << std::endl;
        switch(event->key.keysym.sym)
        {
            case SDLK_LEFT:
             {   /* We check to make sure the ship is moving */
                /* to the left. If it is then we zero the    */
                /* velocity. If the ship is moving to the   */
                /* right then the right key is still press   */
                /* so we don't touch the velocity            */
                c.setIsTurningLeft(false);
                return this->keystate = LeftReleased;
                // code to do things when left isn't pushed anymore but still moving left
                break;
            }
            case SDLK_RIGHT:
            {    // code to do things when right isn't pushed anymore but still moving right
                c.setIsTurningRight(false);
                return this->keystate = RightReleased;
                break;
            }
            case SDLK_UP:
            {    // code to do things when up isn't pushed anymore but still moving up
                c.setIsAccelerating(false);
                return this->keystate = UpReleased;
                break;
            }
            case SDLK_SPACE:
            {    // accleration
                c.setIsShooting(false);
                return this->keystate = SpaceReleased;
                // add code when user presses up
                break;
            }
            default:
                break;
        }
        break;
    }
    default:
    {
        return this->keystate = NotPressed;
        break;
    }
 }
}

РЕДАКТИРОВАТЬ:

Вот запрошенный пример. Еще одна вещь, которую я заметил, это то, что задержка ответа не так велика. Например, если вы нажимаете клавишу, иногда консоль не печатает соответствующую клавишу. Вероятно, это связано с проблемой, которая у меня возникла с пространством.

void GUI::TakeInput(SDL_Event *e)
{
    while (SDL_PollEvent(e))
        OnEvent(e);
}
void SDLEvent::OnEvent(SDL_Event * event) 
{
    switch(event->type) 
    {
        case SDL_KEYDOWN: 
        {
            OnKeyDown(event->key.keysym.sym);
            break;
        }

        case SDL_KEYUP:
        {
            OnKeyUp(event->key.keysym.sym);
            break;
        }

        case SDL_MOUSEMOTION:
        {
            OnMouseMove(event->motion.x,event->motion.y);
            break;
        }

        case SDL_MOUSEBUTTONDOWN: 
        {
            OnMouseButtonDown(event->button.button, event->button.x,event->button.y);
            break;
        }

        case SDL_MOUSEBUTTONUP:
        {
            OnMouseButtonUp(event->button.button, event->button.x,event->button.y);
            break;
        }

        case SDL_QUIT: {
            OnExit();
            break;
        }

        case SDL_SYSWMEVENT: {
            //Ignore
            break;
        }

        case SDL_WINDOWEVENT_RESIZED: {
            OnResize();
            break;
        }

        case SDL_WINDOWEVENT_EXPOSED: {
            OnExpose();
            break;
        }

        default: {
            OnUser(event->user.type,event->user.code,event->user.data1,event->user.data2);
            break;
        }
    }
}

void GUI::Play()
{
    Uint32 start_ticks = SDL_GetTicks();
    TakeInput(this->setup->GetEvent());
    this->keyboard->ProcessKeys(this->setup->GetEvent());
    this->setup->RenderBegin();
    this->ship->drawBackBuffer();
    this->ship->renderSprite();
    Uint32 end_ticks = SDL_GetTicks();
    int sleep_delay = (1000 / 60) - (end_ticks-start_ticks);

     if (sleep_delay > 0) {
      SDL_Delay(sleep_delay);
     }     
}

person xe0    schedule 01.03.2014    source источник
comment
Где вы вызываете событие опроса sdl?   -  person this    schedule 02.03.2014
comment
Прямо перед вызовом этой функции есть цикл while с SDL_PollEvent.   -  person xe0    schedule 03.03.2014
comment
Это не очень полезно. Создание минимального тестового примера было бы здорово.   -  person this    schedule 03.03.2014
comment
Извините, вы не были очень конкретными. Я надеюсь, что добавленный код добавляет достаточно, чтобы дать вам представление о том, как он работает. Недавно я попытался перейти на SDL_Scancode, и, похоже, он работает лучше, чем нажатие клавиши на основе событий, но моя проблема становится задержкой.   -  person xe0    schedule 03.03.2014
comment
как определить, что он не работает? вы std::cout в старом состоянии? так что вашим единственным индикатором будет то, что ваш c не ускоряется. эта функция работает правильно, если, например. ставится на другой ключ?   -  person cfrick    schedule 03.03.2014
comment
мой std::cout ‹‹ event-›key.keysym.sym должен распечатать любую клавишу, нажатую в текущий момент времени, если я правильно понимаю. Он никогда ничего не печатает, когда я нажимаю пробел. Он дает cout для любого другого ключа, но только для пробела, которого нет. Мне удалось получить ответ от пробела с помощью key.keysym.scancode, что странно. Кроме того, в проекте участвуют несколько других людей, и метод других парней c.isNotAccelerating(bool) в настоящее время не подлежит тестированию, поэтому я сначала пытаюсь определить, работает ли мой независимо.   -  person xe0    schedule 03.03.2014


Ответы (1)


Если вы пишете только event->key.keysym.sym на консоли, вы должны знать, что клавиша пробела производит почти невидимый символ.

Попробуйте это вместо этого:

std::cout << "<" << event->key.keysym.sym << ">"

Таким образом, вы можете увидеть невидимый символ, напечатанный между угловыми скобками.

person dogiordano    schedule 15.04.2014