使用c在Ubuntu上使用SDL熟悉OpenGL编程.经过一些环顾和试验,我开始明白了.我需要SDL的键盘事件处理方面的建议.
我有一个第一人称相机,可以左右走fwd,back,strafe,并使用鼠标环顾四周,这是伟大的.这是我的processEvents函数:
void processEvents() { int mid_x = screen_width >> 1; int mid_y = screen_height >> 1; int mpx = event.motion.x; int mpy = event.motion.y; float angle_y = 0.0f; float angle_z = 0.0f; while(SDL_PollEvent(&event)) { switch(event.type) { case SDL_KEYDOWN: switch(event.key.keysym.sym) { case SDLK_ESCAPE: quit = true; break; case SDLK_w: objCamera.Move_Camera( CAMERASPEED); break; case SDLK_s: objCamera.Move_Camera(-CAMERASPEED); break; case SDLK_d: objCamera.Strafe_Camera( CAMERASPEED); break; case SDLK_a: objCamera.Strafe_Camera(-CAMERASPEED); break; default: break; } break; case SDL_MOUSEMOTION: if( (mpx == mid_x) && (mpy == mid_y) ) return; SDL_WarpMouse(mid_x,mid_y); // Get the direction from the mouse cursor,set a resonable maneuvering speed angle_y = (float)( (mid_x - mpx) ) / 1000; angle_z = (float)( (mid_y - mpy) ) / 1000; // The higher the value is the faster the camera looks around. objCamera.mView.y += angle_z * 2; // limit the rotation around the x-axis if((objCamera.mView.y - objCamera.mPos.y) > 8) objCamera.mView.y = objCamera.mPos.y + 8; if((objCamera.mView.y - objCamera.mPos.y) <-8) objCamera.mView.y = objCamera.mPos.y - 8; objCamera.Rotate_View(-angle_y); break; case SDL_QUIT: quit = true; break; case SDL_VIDEORESIZE: screen = SDL_SetVideoMode( event.resize.w,event.resize.h,screen_bpp,SDL_OPENGL | SDL_HWSURFACE | SDL_RESIZABLE | SDL_GL_DOUBLEBUFFER | SDL_HWPALETTE ); screen_width = event.resize.w; screen_height = event.resize.h; init_opengl(); std::cout << "Resized to width: " << event.resize.w << " height: " << event.resize.h << std::endl; break; default: break; } } }
现在在工作的时候,它有一些限制.最大的一个,我的问题的目的是,似乎只是处理最新的按键.所以,如果我抱着’向后走’,我按’d’来说是正确的,我最后就是争取权利,而不是倒退.
有人可以指出我正确的方向,以更好的键盘处理与SDL,一次支持多个按键等?
谢谢
解决方法
一个很好的方法是写一个处理输入事件的键盘(“input”)处理程序,并将事件的状态保持在某种结构中(关联数组听起来很好 – 键[keyCode]).
每当键盘处理程序接收到“按键”事件时,它将该键设置为启用(true),并且当它获取一个关键的事件时,它将其设置为禁用(false).
然后,您可以一次检查多个键,而不直接拉动事件,您将能够在整个框架上重复使用键盘,而不会将其传递到子程序.
一些快速伪码:
class KeyboardHandler { handleKeyboardEvent(SDL Event) { keyState[event.code] = event.state; } bool isPressed(keyCode) { return (keyState[keyCode] == PRESSED); } bool isReleased(keyCode) { return (keyState[keyCode] == RELEASED); } keyState[]; } ... while(SDL Pull events) { switch(event.type) { case SDL_KEYDOWN: case SDL_KEYUP: keyHandler.handleKeyboardEvent(event); break; case SDL_ANOTHER_EVENT: ... break; } } // When you need to use it: if(keyHandler.isPressed(SOME_KEY) && keyHandler.isPressed(SOME_OTHER_KEY)) doStuff(TM);