SDL 2 游戏编程(三)事件驱动程序

来源:互联网 发布:网络推广方法 编辑:程序博客网 时间:2024/05/16 06:29

本文翻译自《Lazy Foo’ Productions - Beginning Game Programming v2.0》,为原创翻译,转载请注明出处。
注:因为我懒,所以翻译可能各种不靠谱(手动微笑)
原文链接:Event Driven Programming

前言

上个教程中已经成功的显示了一个图片啦~但是这太tm无聊了,既然是游戏编程所以肯定要有交互啊~对不对。没关系,SDL提供了事件处理系统来处理用户的输入。

完整代码

/*This source code copyrighted by Lazy Foo' Productions (2004-2015)and may not be redistributed without written permission.*///Using SDL and standard IO#include <SDL.h>#include <stdio.h>//Screen dimension constantsconst int SCREEN_WIDTH = 640;const int SCREEN_HEIGHT = 480;//Starts up SDL and creates windowbool init();//Loads mediabool loadMedia();//Frees media and shuts down SDLvoid close();//The window we'll be rendering toSDL_Window* gWindow = NULL;//The surface contained by the windowSDL_Surface* gScreenSurface = NULL;//The image we will load and show on the screenSDL_Surface* gXOut = NULL;bool init(){    //Initialization flag    bool success = true;    //Initialize SDL    if( SDL_Init( SDL_INIT_VIDEO ) < 0 )    {        printf( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError() );        success = false;    }    else    {        //Create window        gWindow = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN );        if( gWindow == NULL )        {            printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError() );            success = false;        }        else        {            //Get window surface            gScreenSurface = SDL_GetWindowSurface( gWindow );        }    }    return success;}bool loadMedia(){    //Loading success flag    bool success = true;    //Load splash image    gXOut = SDL_LoadBMP( "../03_event_driven_programming/x.bmp" );    if( gXOut == NULL )    {        printf( "Unable to load image %s! SDL Error: %s\n", "03_event_driven_programming/x.bmp", SDL_GetError() );        success = false;    }    return success;}void close(){    //Deallocate surface    SDL_FreeSurface( gXOut );    gXOut = NULL;    //Destroy window    SDL_DestroyWindow( gWindow );    gWindow = NULL;    //Quit SDL subsystems    SDL_Quit();}int main( int argc, char* args[] ){    //Start up SDL and create window    if( !init() )    {        printf( "Failed to initialize!\n" );    }    else    {        //Load media        if( !loadMedia() )        {            printf( "Failed to load media!\n" );        }        else        {            //Main loop flag            bool quit = false;            //Event handler            SDL_Event e;            //While application is running            while( !quit )            {                //Handle events on queue                while( SDL_PollEvent( &e ) != 0 )                {                    //User requests quit                    if( e.type == SDL_QUIT )                    {                        quit = true;                    }                }                //Apply the image                SDL_BlitSurface( gXOut, NULL, gScreenSurface, NULL );                //Update the surface                SDL_UpdateWindowSurface( gWindow );            }        }    }    //Free resources and close SDL    close();    return 0;}

正文

            //Main loop flag            bool quit = false;            //Event handler            SDL_Event e;

我们从main函数开始讲起,首先和上一个教程一样我们初始化SDL并读取媒体文件。然后这里声明了一个退出标志,看名字就知道这东西是干嘛的,对吧。由于我们的程序才刚刚开始,所以肯定要设置成false。

同时还声明了一个SDL Event共用体。SDL Event用来记录发生的事件,比如按个键盘啦,动个鼠标啦什么的。我们这个程序呢,就是要找到退出事件并结束程序(好像有点无聊)。

            //While application is running            while( !quit )            {

记得上一个程序么,那里我们用了Delay函数让程序在关闭之前苟延残喘了两秒。现在这个程序会一直运行到地老天荒,直到你关掉它。

怎么做呢,只要用户没有关掉它,我们就让程序一直循环,这种循环就叫做主循环或者游戏循环,就和你打开了一个游戏不关掉它,它就一直开着是一样的道理。

                //Handle events on queue                while( SDL_PollEvent( &e ) != 0 )                {                    //User requests quit                    if( e.type == SDL_QUIT )                    {                        quit = true;                    }                }

在主循环的开始呢,我们放上了事件循环,事件循环会一直处理事件队列,直到事件队列为空。

当你按下键盘,移动鼠标,事件队列就会按照时间顺序储存这些事件,是一个先进先出队列。

当你想要处理下一个事件,那就需要先从队列里取出这个事件,SDL_PollEvent会帮你从事件队列里取出一个事件,并将这个事件传递给参数。

当事件队列为空,SDL_PollEvent将会返回0,当事件循环读取到SDL_QUIT事件的时候,程序会将退出标志quit设置为true。(SDL_QUIT事件是什么?当然就是点击窗口右上方的小xx了)

                //Apply the image                SDL_BlitSurface( gXOut, NULL, gScreenSurface, NULL );                //Update the surface                SDL_UpdateWindowSurface( gWindow );            }

别忘了我们最开始在屏幕上显示了一个图片,所以需要在主循环中渲染这个图片,还有更新窗口显示框。

0 0
原创粉丝点击