Lazyfoo's SDL_Tutorial 摘要翻译4

LazyFoo's SDL Tutorial 摘要翻译

Tutorial4: Key Presses

[原文](https://lazyfoo.net/tutorials/SDL/04_key_presses/index.php.htm)
更加深入的事件处理相关的内容,这次是根据不同的按键来显示不同的图片.

//Key press surfaces constants
enum KeyPressSurfaces
{
    KEY_PRESS_SURFACE_DEFAULT,
    KEY_PRESS_SURFACE_UP,
    KEY_PRESS_SURFACE_DOWN,
    KEY_PRESS_SURFACE_LEFT,
    KEY_PRESS_SURFACE_RIGHT,
    KEY_PRESS_SURFACE_TOTAL
};

首先定义一个枚举,熟悉C/C++的人都知道这是啥,主要是比较看得清楚.

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

//Loads media
bool loadMedia();

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

//Loads individual image
SDL_Surface* loadSurface( std::string path );

//The window we'll be rendering to
SDL_Window* gWindow = NULL;
    
//The surface contained by the window
SDL_Surface* gScreenSurface = NULL;

//The images that correspond to a keypress
SDL_Surface* gKeyPressSurfaces[ KEY_PRESS_SURFACE_TOTAL ];

//Current displayed image
SDL_Surface* gCurrentSurface = NULL;

多了几个东西.
一个是函数loadSurface(std::string path),这个其实是把之前的loadMedia()函数里面的加载图片的几行代码抽了出来,没啥特别的,方便.
还有一个是gKeyPressSurfaces,用来存所有要用到的图片,这里有一个enum的妙用,不知是否注意到.至于gCurrentSurface就是当前显示的图片.

SDL_Surface* loadSurface( std::string path )
{
    //Load image at specified path
    SDL_Surface* loadedSurface = SDL_LoadBMP( path.c_str() );
    if( loadedSurface == NULL )
    {
        printf( "Unable to load image %s! SDL Error: %s\n", path.c_str(), SDL_GetError() );
    }

    return loadedSurface;
}

代码平淡无奇.
至于作者说由很多萌新问这个loadedSurface会不会变成内存泄漏,至少这里是不会,因为这个指针最后是返回出去了,并没有变成野指针.记得把返回出去的指针最后销毁就好了

bool loadMedia()
{
    //Loading success flag
    bool success = true;

    //Load default surface
    gKeyPressSurfaces[ KEY_PRESS_SURFACE_DEFAULT ] = loadSurface( "04_key_presses/press.bmp" );
    if( gKeyPressSurfaces[ KEY_PRESS_SURFACE_DEFAULT ] == NULL )
    {
        printf( "Failed to load default image!\n" );
        success = false;
    }

    //Load up surface
    gKeyPressSurfaces[ KEY_PRESS_SURFACE_UP ] = loadSurface( "04_key_presses/up.bmp" );
    if( gKeyPressSurfaces[ KEY_PRESS_SURFACE_UP ] == NULL )
    {
        printf( "Failed to load up image!\n" );
        success = false;
    }

    //Load down surface
    gKeyPressSurfaces[ KEY_PRESS_SURFACE_DOWN ] = loadSurface( "04_key_presses/down.bmp" );
    if( gKeyPressSurfaces[ KEY_PRESS_SURFACE_DOWN ] == NULL )
    {
        printf( "Failed to load down image!\n" );
        success = false;
    }

    //Load left surface
    gKeyPressSurfaces[ KEY_PRESS_SURFACE_LEFT ] = loadSurface( "04_key_presses/left.bmp" );
    if( gKeyPressSurfaces[ KEY_PRESS_SURFACE_LEFT ] == NULL )
    {
        printf( "Failed to load left image!\n" );
        success = false;
    }

    //Load right surface
    gKeyPressSurfaces[ KEY_PRESS_SURFACE_RIGHT ] = loadSurface( "04_key_presses/right.bmp" );
    if( gKeyPressSurfaces[ KEY_PRESS_SURFACE_RIGHT ] == NULL )
    {
        printf( "Failed to load right image!\n" );
        success = false;
    }

    return success;
}

加载所有的图片.

   //Main loop flag
    bool quit = false;

    //Event handler
    SDL_Event e;

    //Set default current surface
    gCurrentSurface = gKeyPressSurfaces[ KEY_PRESS_SURFACE_DEFAULT ];

    //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;
    }
    //User presses a key
    else if( e.type == SDL_KEYDOWN )
    {
        //Select surfaces based on key press
        switch( e.key.keysym.sym )
        {
            case SDLK_UP:
            gCurrentSurface = gKeyPressSurfaces[ KEY_PRESS_SURFACE_UP ];
            break;

            case SDLK_DOWN:
            gCurrentSurface = gKeyPressSurfaces[ KEY_PRESS_SURFACE_DOWN ];
            break;

            case SDLK_LEFT:
            gCurrentSurface = gKeyPressSurfaces[ KEY_PRESS_SURFACE_LEFT ];
            break;

            case SDLK_RIGHT:
            gCurrentSurface = gKeyPressSurfaces[ KEY_PRESS_SURFACE_RIGHT ];
            break;

            default:
            gCurrentSurface = gKeyPressSurfaces[ KEY_PRESS_SURFACE_DEFAULT ];
            break;
        }
    }
}

事件循环.除了之前的关闭事件,多了一个按键事件.
SDL_Event内部是一个SDL Keyboard event事件,其中包含按键事件的信息。 其内部是一个SDL Keysym,其中包含有关已按下键的信息。 该Keysym包含SDL Keycode,该SDL Keycode标识按下的键。这些内容还请自行翻看SDL文档.做过桌面客户端开发的人应该对这些不陌生来着.

接下来依然是无趣的渲染环节.つづく。

posted @ 2020-05-10 15:27  Prisrak  阅读(79)  评论(0编辑  收藏  举报