SDL入门之二 事件event
转自: https://blog.csdn.net/lf426/article/details/2086644 及其后续文章
1.1 SDL为我们提供了两种等待事件的方式:
int SDL_WaitEvent(SDL_Event *event);
int SDL_PollEvent(SDL_Event *event);
两个函数的返回值都是int,形参是SDL事件结构指针.他们的返回值是1或者0,他们会通过指针参数传值。
1.2 当前窗口,即正在操作的那个程序
SDL的事件查询机制是与SDL_INIT_VIDEO同时装载的。为什么呢?
有些event可能是各个窗口,甚至包括系统本身共享的,比如鼠标移动(这不是绝对的,只是有可能);有些event只会被当前窗口接受,就如同你不会希望同时开着两个Word文件在编辑,修改一个文件的时候,另外一个也被无情的修改了。所以,SDL程序运行的时候,只有指定了哪个窗口是这个程序的窗口,并且这个窗口是当前窗口的时候,大部分event才能被正确的响应。 注意,console窗口不是SDL程序的运行窗口,它属于操作系统本身。
要打开SDL的程序窗口,需要引入一个新函数:
SDL_Surface *SDL_SetVideoMode(int width, int height, int bitsperpixel, Uint32 flags);
1. 这个函数本身的作用:打开SDL程序窗口
2. 前三个参数分别是这个打开窗口的宽,高和位深,最后那个flags我们这里只介绍SDL_SWSURFACE,这个位标表示把返回值的数据建立在系统内存里面。
下面是按下ESC退出SDL窗口的程序:
#include <iostream>
#include "SDL/SDL.h"
void pressESCtoQuit();
void doSomeLoopThings();
int main(int argc,char* argv[]){
try {
if ( SDL_Init(SDL_INIT_VIDEO == -1 ))
throw SDL_GetError();
}
catch ( const char* s ) {
std::cerr << s << std::endl;
return -1;
}
atexit(SDL_Quit);
SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);
std::cout << "Program is running, press ESC to quit./n";
pressESCtoQuit();
std::cout << "GAME OVER" << std::endl;
return 0;
}
void pressESCtoQuit(){
bool gameOver = false;
while( gameOver == false ){
SDL_Event gameEvent;
while ( SDL_PollEvent(&gameEvent) != 0 ){ /* SDL_PollEvent(&gameEvent); if(&gameEvent != 0 ){ */
if ( gameEvent.type == SDL_QUIT ){
gameOver = true;
}
if ( gameEvent.type == SDL_KEYUP ){ /* if ( gameEvent.type == SDL_KEYDOWN ) */
if ( gameEvent.key.keysym.sym == SDLK_ESCAPE ){
gameOver = true;
}
}
}
doSomeLoopThings();
}
return;
}
void doSomeLoopThings()
{
std::cout << ".";
return;
}
我们把引起轮询机制的if换成了while。我们前面说过,查询&gameEvent是不是为空,是为了强调SDL_PollEvent()使用指针参数传了值。而事实上,if是判断,while不仅仅是判断,而且还是循环。但是更换这两个关键字似乎并没有出现不同,为什么呢?
我们分析两种情况下的模型。使用if的函数,实际上每次循环只查询event一次;而使用while的时候,内嵌的while循环会一直对“悬而未解”的事件队列(event queue)“弹”(这个隐喻意味着某个event一旦被处理,就不再属于queue的一个元素)出的头值进行处理,
直到事件队列为空。这似乎更符合理想的模型。但是实际上,计算机的效率并不是我们假设的那样低,event queue在一个外循环期间,始终保持两种状态:要么为空,要么最多一个。
换句话说,你不可能在一次gameOver==false的循环期间,为event queue挤进去1个之上(>1)的event,这就是if与while效果相同的原因。
我们修改的第二个细节是把SDL_KEYDOWN换成了SDL_KEYUP,这是为了提醒大家,按下某个键和按下某个键再松开,是两种不同的event。
浙公网安备 33010602011771号