Chinaunix首页 | 论坛 | 博客
  • 博客访问: 10258
  • 博文数量: 4
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 30
  • 用 户 组: 普通用户
  • 注册时间: 2012-12-19 23:42
文章分类
文章存档

2012年(4)

我的朋友

分类:

2012-12-19 23:50:02

原文地址:SDL事件循环及按键处理 作者:bluedrum

Andrew Huang
 
 
一.事件循环
------------------------------------------------------
  一个完整的GUI程序,需要处理各种事件,如按键,鼠标,窗口操作等。一般这种程序会设计成一个与底层交互的事件驱动模型。即底层不断发送事件,而在程序用一个循环不断处理各种事件
 
各个GUI都是采用这样模型来实现,SDL抽象这个模型,采用SDL_event来抽象表示具体的事件,它有如下几种类型。
 

/** Event enumerations */
typedef enum {
       SDL_NOEVENT = 0,            /**< Unused (do not remove) */
       SDL_ACTIVEEVENT,            /**< Application loses/gains visibility */
       SDL_KEYDOWN,            /**< Keys pressed */
       SDL_KEYUP,            /**< Keys released */
       SDL_MOUSEMOTION,            /**< Mouse moved */
       SDL_MOUSEBUTTONDOWN,        /**< Mouse button pressed */
       SDL_MOUSEBUTTONUP,        /**< Mouse button released */
       SDL_JOYAXISMOTION,        /**< Joystick axis motion */
       SDL_JOYBALLMOTION,        /**< Joystick trackball motion */
       SDL_JOYHATMOTION,        /**< Joystick hat position change */
       SDL_JOYBUTTONDOWN,        /**< Joystick button pressed */
       SDL_JOYBUTTONUP,            /**< Joystick button released */
       SDL_QUIT,            /**< User-requested quit */
       SDL_SYSWMEVENT,            /**< System specific event */
       SDL_EVENT_RESERVEDA,        /**< Reserved for future use.. */
       SDL_EVENT_RESERVEDB,        /**< Reserved for future use.. */
       SDL_VIDEORESIZE,            /**< User resized video mode */
       SDL_VIDEOEXPOSE,            /**< Screen needs to be redrawn */
       SDL_EVENT_RESERVED2,        /**< Reserved for future use.. */
       SDL_EVENT_RESERVED3,        /**< Reserved for future use.. */
       SDL_EVENT_RESERVED4,        /**< Reserved for future use.. */
       SDL_EVENT_RESERVED5,        /**< Reserved for future use.. */
       SDL_EVENT_RESERVED6,        /**< Reserved for future use.. */
       SDL_EVENT_RESERVED7,        /**< Reserved for future use.. */
       /** Events SDL_USEREVENT through SDL_MAXEVENTS-1 are for your use */
       SDL_USEREVENT = 24,
       
/** This last event is only for bounding internal arrays
    * It is the number of bits in the event mask datatype -- Uint32
        */

       SDL_NUMEVENTS = 32
} SDL_EventType;

 
SDL采用 int SDL_PollEvent(SDL_Event *event); 来从底层提取事件。
 
每一个事件都有一个独立数据结构来定义,但是第一个成员必是一个int type,
 
SDL_Event就是一个各种事件定义的联合

/** General event structure */
typedef union SDL_Event {
    Uint8 type;
    SDL_ActiveEvent active;
    SDL_KeyboardEvent key;
    SDL_MouseMotionEvent motion;
    SDL_MouseButtonEvent button;
    SDL_JoyAxisEvent jaxis;
    SDL_JoyBallEvent jball;
    SDL_JoyHatEvent jhat;
    SDL_JoyButtonEvent jbutton;
    SDL_ResizeEvent resize;
    SDL_ExposeEvent expose;
    SDL_QuitEvent quit;
    SDL_UserEvent user;
    SDL_SysWMEvent syswm;
} SDL_Event;

 
而象常用的事件有,退出事件(当你点击窗口关闭键,就会触发此事件)
  

typedef struct SDL_QuitEvent {
    Uint8 type;    /**< SDL_QUIT */
} SDL_QuitEvent;

 
按键处理事件
 

/** Keyboard event structure */
typedef struct SDL_KeyboardEvent {
    Uint8 type;    /**< SDL_KEYDOWN or SDL_KEYUP */
    Uint8 which;    /**< The keyboard device index */
    Uint8 state;    /**< SDL_PRESSED or SDL_RELEASED */
    SDL_keysym keysym;
} SDL_KeyboardEvent;

 
 
 
同步事件
1.2 同步事件处理框架
 
它将是在主循环完成事件处理,这个循环过程是就是主线程的执行过程
 

int quit = false;
 
while( quit == false )
    {
Now we start the main loop. This loop will keep going until the user sets quit to true.
//While there's an event to handle

        while( SDL_PollEvent( &event ) )
        {
             switch(event.type)
             {
             case SDL_QUIT:
                 quit = true;
                  break;
             default:
                 break;
             }
 
        }

 
 
还有两个不常用的事件函数
 SDL_WaitEvent(); //必须等到有一个事件才返回,而SDL_PollEvent 没有事件也立即返回,这样提高系统反应速度。
 SDL_PeepEvents(). 是提出事件,但事件本身仍然在事件队列中
 
 
1.3异步事件处理。
   有时比较复杂的游戏的主循环可能用作其它程序,这时用得上事件过滤器,事件过滤器,在有事件发生调用事件处理回调函数。因此称为异步事件处理.
  它调用 void SDL_SetEventFilter(SDL_EventFilter filter);来加入事件过滤回调函数.
  其中.filter是一个函数指针,它有如下类型
 
SDL_SetEventFilter(PAL_EventFilter);
 
 
 
二.SDL按键处理
---------------------------------------------------------------------
 按键类型是 event.type == SDL_KEYDOWN,
 

typedef struct{
  Uint8 scancode;
  SDLKey sym;
  SDLMod mod;
  Uint16 unicode;
} SDL_keysym;

 
 表示用户按下键盘 
 
1.普通按键盘处理。
       保存在event.key.keysym.sym 是相应的键值
 
keysym有如下定义
 
   

/*
SDLK_LEFTBRACKET    = 91,
    SDLK_BACKSLASH        = 92,
    SDLK_RIGHTBRACKET    = 93,
    SDLK_CARET        = 94,
    SDLK_UNDERSCORE        = 95,
    SDLK_BACKQUOTE        = 96,
    SDLK_a            = 97,
    SDLK_b            = 98,
    SDLK_c            = 99,
    SDLK_d            = 100,
    SDLK_e            = 101,
    SDLK_f            = 102,
*/

int quit = false;
 
while( quit == false )
    {
Now we start the main loop. This loop will keep going until the user sets quit to true.
//While there's an event to handle

        while( SDL_PollEvent( &event ) )
        {
             switch(event.type)
             {
             case SDL_QUIT:
                 quit = true;
                  break;
             case SDL_KEYDOWN:
                 switch( event.key.keysym.sym )
                    {
                    case SDLK_UP: ; break;
                    case SDLK_DOWN: ; break;
                    case SDLK_a: ; break;
                    case SDLK_RIGHT: ; break;
                   }
                 break;
             default:
                 break;
             }
 
        }

 
 


2.判断是按下组合键

   key.keysym.mod 保存组合键状态,如果检测是否按下 ALT

   if(lpEvent->key.keysym.mod & KMOD_ALT)

各个组合状态如下

 

SDLMod

Meaning

KMOD_NONE

No modifiers applicable

KMOD_LSHIFT

Left Shift is down

KMOD_RSHIFT

Right Shift is down

KMOD_LCTRL

Left Control is down

KMOD_RCTRL

Right Control is down

KMOD_LALT

Left Alt is down

KMOD_RALT

Right Alt is down

KMOD_LMETA

Left Meta is down

KMOD_RMETA

Right Meta is down

KMOD_NUM

Numlock is down

KMOD_CAPS

Capslock is down

KMOD_MODE

Mode is down

KMOD_CTRL

A Control key is down

KMOD_SHIFT

A Shift key is down

KMOD_ALT

An Alt key is down

KMOD_META

A Meta key is down

   




阅读(5690) | 评论(0) | 转发(0) |
0

上一篇:SDL 鼠标事件处理

下一篇:没有了

给主人留下些什么吧!~~