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。

 

posted @ 2019-05-06 16:50  HenryLiuY  阅读(907)  评论(0)    收藏  举报