(翻译的)这个教程囊括了如何检测键盘事件的发生,代码是一个简单的演示哪个箭头键被按下,你现在已经用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的结构是很简单了。