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

本文翻译自《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 constants
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;

//Starts up SDL and creates window
bool init();

//Loads media
bool loadMedia();

//Frees media and shuts down SDL
void close();

//The window we'll be rendering to
SDL_Window* gWindow = NULL;

//The surface contained by the window
SDL_Surface* gScreenSurface = NULL;

//The image we will load and show on the screen
SDL_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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值