C++ SDL学习之路 3rd —— 没法关闭SDL窗口?用事件列表!

来源:互联网 发布:王晓东视频 算法 编辑:程序博客网 时间:2024/06/06 08:41

OK,我这个初二学生又来了。
上一次我们成功创建了SDL窗口,但是细心(乱点)的人会发现,这个SDL窗口没法关闭···
这一会我们就讨论一下关闭的功能。

看过我的Lesson 03教程翻译(http://blog.csdn.net/yiwenyoucod/article/details/73555237)可以知道Lesson 03就是讲关闭功能的。
我这里直接上一下官方的代码(我翻译过注释并整理过代码):

//使用SDL和标准IO#include <SDL.h>#include <stdio.h>//屏幕尺寸常量const int SCREEN_WIDTH = 640;const int SCREEN_HEIGHT = 480;//启动SDL并创建窗口bool init();//加载媒体bool loadMedia();//释放媒体并关闭SDLvoid close();//我们将要渲染的窗口SDL_Window* gWindow = NULL;//窗口所包含的表面SDL_Surface* gScreenSurface = NULL;//我们将在屏幕上加载和显示的图像SDL_Surface* gXOut = NULL;bool init(){    //初始化标志    bool success = true;    //SDL进行初始化    if( SDL_Init( SDL_INIT_VIDEO ) < 0 )    {        printf( "SDL不能初始化!SDL错误: %s\n", SDL_GetError() );        success = false;    }    else    {        //创建窗口        gWindow = SDL_CreateWindow( "SDL教程", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN );        if( gWindow == NULL )        {            printf( "不能创建窗口!SDL错误: %s\n", SDL_GetError() );            success = false;        }        else        {            //得到窗口表面            gScreenSurface = SDL_GetWindowSurface( gWindow );        }    }    return success;}bool loadMedia(){    //加载成功标志    bool success = true;    //负载启动图像    gXOut = SDL_LoadBMP( "03_event_driven_programming/x.bmp" );    if( gXOut == NULL )    {        printf( "无法加载图片 %s!SDL错误: %s\n", "03_event_driven_programming/x.bmp", SDL_GetError() );        success = false;    }    return success;}void close(){    //释放表面    SDL_FreeSurface( gXOut );    gXOut = NULL;    //销毁窗口    SDL_DestroyWindow( gWindow );    gWindow = NULL;    //退出SDL子系统    SDL_Quit();}int main( int argc, char* args[] ){    //启动SDL并创建窗口    if( !init() )    {        printf( "初始化失败!\n" );    }    else    {        //加载媒体        if( !loadMedia() )        {            printf( "未能加载媒体!\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, gScreenSurface, NULL );                //更新表面                SDL_UpdateWindowSurface( gWindow );            }        }    }    //释放资源并关闭SDL    close();    return 0;}

这些函数(init,loadMedia,close)都是干什么用的可以看注释,最好的方式是看我的SDL学习之路2nd(http://blog.csdn.net/yiwenyoucod/article/details/73513168)。

可以看到,这个代码里面,首先是启动SDL(init),然后是加载媒体(loadMedia),然后就创建了一个标志(quit),然后就进入了主循环,只有当标志(quit)为true时,才会退出循环,然后就退出SDL界面(close)。

而这里创建了一个SDL的事件处理:

//事件处理程序SDL_Event e;

进入退出(quit)检测循环中时同时又进入了一个循环,这个循环叫做事件队列循环:

//处理事件队列while( SDL_PollEvent( &e ) != 0 ){    //用户请求退出    if( e.type == SDL_QUIT )    {        quit = true;    }}

这里的循环判断条件是事件队列是否为空,如果为空,就回到主循环(而主循环有个quit是否为true的判断)。

所以这个事件队列循环的作用就是判断事件队列是否为空,为空就不循环了,并且进入主循环。

这就是3rd主要要讲的内容:事件列表
这里我们将这个事件列表和2nd的代码融合在一起,这是完整代码(图片什么的可以在最下方找到,然后另存为就可以了):

//使用SDL和标准IO#include <SDL.h>#include <stdio.h>//屏幕尺寸常量const int SCREEN_WIDTH = 640;const int SCREEN_HEIGHT = 480;//启动SDL并创建窗口bool init();//加载媒体bool loadMedia();//释放媒体并关闭SDLvoid close();//我们将要渲染的窗口SDL_Window* gWindow = NULL;//窗口所包含的表面SDL_Surface* gScreenSurface = NULL;//我们将在屏幕上加载和显示的图像SDL_Surface* gHelloWorld = NULL;bool init(){    //初始化标志    bool success = true;    //初始化SDL    if (SDL_Init(SDL_INIT_VIDEO) < 0)    {        printf("SDL不能初始化! SDL错误: %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 == NULL)        {            printf("不能创建窗口! SDL错误: %s\n", SDL_GetError());            success = false;        }        else        {            //获取窗口表面            gScreenSurface = SDL_GetWindowSurface(gWindow);        }    }    return success;}bool loadMedia(){    //标志加载成功    bool success = true;    //负载启动图像    gHelloWorld = SDL_LoadBMP("02_getting_an_image_on_the_screen/hello_world.bmp");    if (gHelloWorld == NULL)    {        printf("无法加载图片 %s! SDL错误: %s\n", "02_getting_an_image_on_the_screen/hello_world.bmp", SDL_GetError());        success = false;    }    return success;}void close(){    //释放表面    SDL_FreeSurface(gHelloWorld);    gHelloWorld = NULL;    //销毁窗口    SDL_DestroyWindow(gWindow);    gWindow = NULL;    //退出SDL子系统    SDL_Quit();}int main(int argc, char* args[]){    //启动SDL并创建窗口    if (!init())    {        printf("初始化失败!\n");    }    else    {        //加载媒体        if (!loadMedia())        {            printf("未能加载媒体!\n");        }        else        {            //主循环标志            bool quit = false;            //事件处理程序            SDL_Event e;            //当应用程序运行时            while (!quit)            {                //处理事件队列                while (SDL_PollEvent(&e) != 0)                {                    //用户请求退出                    if (e.type == SDL_QUIT)                    {                        quit = true;                    }                }                //应用图像                SDL_BlitSurface(gHelloWorld, NULL, gScreenSurface, NULL);                //更新表面                SDL_UpdateWindowSurface(gWindow);            }        }    }    //释放资源并关闭SDL    close();    //结束程序    return 0;}

OK,3rd也完了,这个是我说过的图片(自己按照代码创建文件夹并把图片放入哦):
这里写图片描述