(翻译的)这个教程囊括了如何检测键盘事件的发生,代码是一个简单的演示哪个箭头键被按下,你现在已经用SDL_QUIT等一些事件句柄做了退出处理,现在要学习的是如何检测键盘按键按下,并且检测键标。
代码和注释:
#include"SDL.h" #include <string>
const int SCREEN_WIDTH=640; const int SCREEN_HEIGHT=480; const int SCREEN_BPP=32; SDL_Surface *screen=NULL; SDL_Surface *background=NULL; SDL_Surface *message=NULL; SDL_Surface *upMessage; SDL_Surface *downMessage; SDL_Surface *leftMessage; SDL_Surface *rightMessage;
//定义显示字体的颜色SDL_Color textColor={100,100,0};
//定义字体指针TTF_Font *font=NULL;
//定义事件结构SDL_Event event;
SDL_Surface *load_image(std::string filename) {//装载图片 SDL_Surface *loadedImage=NULL; SDL_Surface *optimizedImage=NULL; loadedImage=IMG_Load(filename.c_str()); if(loadedImage!=NULL) { optimizedImage=SDL_DisplayFormat(loadedImage); SDL_FreeSurface(loadedImage); if(optimizedImage!=NULL) { SDL_SetColorKey(optimizedImage,SDL_SRCCOLORKEY,SDL_MapRGB(optimizedImage->format,0,0,0)); } } return optimizedImage; }
void apply_surface(int x,int y,SDL_Surface *source,SDL_Surface *destination,SDL_Rect *clip=NULL) {//stick表面 SDL_Rect offset; offset.x=x; offset.y=y; SDL_BlitSurface(source,clip,destination,&offset); }
bool init() { //初始化,设置窗口 if(SDL_Init(SDL_INIT_EVERYTHING)==-1) return false; screen=SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,SDL_SWSURFACE); if(screen==NULL) return false; if(TTF_Init()==-1) return false; SDL_WM_SetCaption( "Press an Arrow Key", NULL ); return true; } bool load_files() { //装载背景和字体 background=load_image("D:/Users/lucy/Documents/Visual Studio 2008/Projects/SDLtest/background.png"); font=TTF_OpenFont("D:/Users/lucy/Documents/Visual Studio 2008/Projects/SDLtest/lazy.ttf",70); if(background==NULL) return false; if(font==NULL) return false; return true; } void clean_up() { //清理工作,注意字体也要清理 SDL_FreeSurface(background); SDL_FreeSurface(upMessage); SDL_FreeSurface(downMessage); SDL_FreeSurface(rightMessage); TTF_CloseFont(font); TTF_Quit(); SDL_Quit(); } int main(int argc,char *argv[]) { bool quit=false; if(init()==false) return 1; if(load_files()==false) return 1; //定义消息显示的表面 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); apply_surface(0,0,background,screen); while(quit==false) { if(SDL_PollEvent(&event)) { //在消息循环队列中判断键盘按键事件 if(event.type==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; } } //显示按键事件的判断 if(message!=NULL) {//如果有事件要予以显示就blit 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; } } clean_up(); } 效果:(按键的时候屏幕就会显示你按下的是哪个键)
什么键都没有按下的时候
分别按下上、右、下、左键的时候屏幕显示的情况 总结:
总的来说,所有键盘事件的处理貌似都是利用了事件或者消息的方式,然后不断的循环,更新当前屏幕,从而得到实时响应的效果,在SDL中也是如此,其标志键盘按下的事件是SDL_KEYDOWN,而存储键标的结构是event.key.keysym.sym,键标的命名格式是SDLK_XX,一般也是像消息处理机制一样使用switch语句,这个程序中用ttf文字生成surface的事件循环来响应按键事件,相信只要掌握了surface的基本使用和ttf,再了解event的结构是很简单了。