事件驱动编程
除了把图片显示在屏幕上,游戏要求你处理来自用户的输入,你可以用SDL的事件处理系统
//主循环标志
bool quit = false;
//事件处理函数
SDL_Event e;
/*
在我们的代码中,SDL已经初始化同时媒体文件加载完成(<a target=_blank href="http://blog.csdn.net/ant_look/article/details/50878137">前一个教程</a>提到的),我们声明一个退出标志,跟踪用户是否
已经退出。因为我们是干刚开始将这一点应用在程序上,它的初始化显然是错误的
*/
//应用程序正在运行
while(!quit){
/*
在前面的教程中,我们让程序等待数秒后关闭,在这个程序中,我们让程序等待直到用户退出后关闭
*/
//事件处理队列
while(SDL_PollEvent(&e) != 0){
//User request 退出
if(e.type == SDL_QUIT){
quit = true;
}
}
/*
主循环顶部是我们的事件循环,这样做是不断处理事件队列,直到它为空
当你按下一个键,移动一下鼠标或者触摸一下屏幕就会把这个事件添加到事件队列
*/
事件队列按照事件发生的顺序存储同时等待你处理他们,当你找到发生了什么事件的时候你就可以处理他们。通过
SDL_PollEvent函数轮寻获取最新事件。SDL_PollEvent从事件队列中获取最新的事件并将事件的数据保存到我们传递到函数中的SDL_Event中
SDL_PollEvent将把事件从队列中取出,直到它为空。当队列为空时,SDL_PollEvent将返回 0。这段代码的作用是从事件队列中轮寻事件,直至它为空。如果一个从事件队列中取出的事件是一个SDL_QUIT事件(用户退出窗口事件),我们将标志位设置为 ture然后就可以退出程序
//应用图像
SDL_BlitSurface(gXout, NULL, gScreenWindow, NULL);
//更新表面
SDL_UpdateWindowSurface(gWindow);
/*
之前我们做了实践处理框架,现在绘制屏幕同时更新它(前面讨论的<a target=_blank href="http://blog.csdn.net/ant_look/article/details/50878137">前一个教程</a>),如果退出标志为true,程序将会结束并退出。如果它是false,程序会一直运行直到用户关闭窗口
*/
程序完整的运行代码:(x.bmp下载)
#include<SDL2/SDL.h>
#include<cstdio>
#include<string>
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
//初始化SDL并创建窗口
bool init();
//加载媒体文件
bool loadMedia();
//释放文件并关闭SDL
void close();
//创建窗口指针
SDL_Window* gWindow = nullptr;
//窗口所包含的表面
SDL_Surface* gScreenWindow = nullptr;
//图片将会在这个表面加载显示
SDL_Surface* gXout = nullptr;
bool init(){
bool success = true;
if(SDL_Init(SDL_INIT_VIDEO) == -1){
printf("SDL could not initialize! SDL_Error:%s\n",SDL_GetError());
success = false;
}else{
//创建窗口
gWindow = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT,
SDL_WINDOW_SHOWN);
if(gWindow == nullptr){
printf("Window could not be Creaated! SDL_Error:%s\n",SDL_GetError());
success = false;
}else{
//获得窗口外观
gScreenWindow = SDL_GetWindowSurface(gWindow);
}
}
return success;
}
bool loadMedia(){
//设置标志位
bool success = true;
std::string dir = "Lesson3/x.bmp";
//加载位图文件
gXout = SDL_LoadBMP(dir.c_str());
if(gXout == nullptr){
printf("Unable to load image%s! SDL_Error:%s\n",dir.c_str(), SDL_GetError());
success = false;
}
return success;
}
void close(){
//释放外观
SDL_FreeSurface(gXout);
gXout = nullptr;
//销毁窗口
SDL_DestroyWindow(gWindow);
gWindow = nullptr;
SDL_Quit();
}
int main(int argc, char *argv[]){
if(!init()){
printf("Failed to initialized!\n");
}else{
//加载文件
if(!loadMedia()){
printf("Failed to load media!\n");
}else{
//主循环标志
bool quit = false;
//事件处理程序
SDL_Event e;
//当程序运行的时候
while(!quit){
//事件队列
while(SDL_PollEvent(&e) != 0){
//用户请求退出
if(e.type == SDL_QUIT){
quit = true;
}
}
//应用图片
SDL_BlitSurface(gXout, NULL, gScreenWindow, NULL);
//更新外观
SDL_UpdateWindowSurface(gWindow);
}
}
}
close();
return 0;
}