Lesson 4 按键

本文介绍了一种通过键盘事件动态展示不同图像的方法,利用SDL库实现,通过枚举键码对应不同的图像表面,实现图像的实时切换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关闭窗口只是SDL中一种可以处理的事件,其他类型例如游戏中大量的键盘输入,本教程我们将让不同的图像显示根据你按下的键盘:

enum KeyPressedSurfaces{
    KEY_PRESS_SURFACE_DEFAULT,
    KEY_PRESS_SURFACE_UP,
    KEY_PRESS_SURFACE_DOWN,
    KEY_PRESS_SURFACE_LEFT,
    KEY_PRESS_SURFACE_RIGHT,
    KEY_PRESS_SURFACE_TOTAL
};
/*
在代码的顶部我们声明了一个枚举来表示不同的窗口表面,枚举用一种快速的方法来声明符号常量而不是const int KEY_PRESS_SURFACE_DEFAULT = 0; const int KEY_PRESS_UP = 1;const int KEY_PRESS_SURFACE_DOWN = 2等等。默认是从 0 开始上升计数。这样就意味着
 KEY_PRESS_SURFACE_DEFAULT = 0,KEY_PRESS_SURFACE_UP = 1,
 KEY_PRESS_SURFACE_DOWN = 2,KEY_PRESS_SURFACE_LEFT = 3,
 KEY_PRESS_SURFACE_RIGHT = 4,KEY_PRESS_SURFACE_TOTAL = 5。 你可以赋值明确的整数值,但是我们这里不做,谷歌搜索:枚举如何覆盖
程序员使用硬编码而不是符号常量是一种坏习惯。例如:用1来代表主菜单,2代表选项,等等。这样做适合小型项目。当你处理成千上百行代码的时候(通常是游戏开发),用一行代码像这样:"if(option == 1)",这样非常头疼的代码,应该用: if(option == MAIN)_MENU)这样的代码
*/
//启动SDL并创建窗口
bool init();
//加载媒体
bool loadMedia();
//释放媒体资源并关闭SDL
void close();

//加载个人形象
SDL_Surface* loadSurface(string path);
//声明窗口对象
SDL_Window* gWindow = nullptr;
//声明声明对象
SDL_Surface* gScreenSurface = nullptr;
//图像对应键盘按键
SDL_Surface* gKeyPressSufrace[KEY_PRESS_SURFACE_TOTAL];
//当前显示图像
SDL_Surface* gCurrentSurface = nullptr;
/*
利用通用函数原型,我们声明一个新的函数 loadSurface,如果你拷贝/粘贴代码这是一种通用的代码,防止在复制/粘贴的时候出现错误,我们使用一个函数来处理

这个项目最终要的是,我们有一个SDL_Surface数组的指针叫做gKeyPressSurfaces将包含我们所使用的所有图片,在用户按下键盘,将会显示这个数组中所包含的一个表面
*/ 
SDL_Surface* loadSurface(string path){
    //加载指定路径图像
    SDL_Surface* loadedSurface = SDL_LoadBMP(path.c_str());
    if(loadedSurface == nullptr){
        printf("Unable to load image:%s! SDL_Error:%s\n",path.c_str(), SDL_GetError());
    }
    return loadedSurface;
}
/*
loadSurface 用来加载图片,如果出现错误的话就会报告一个错误,差不多和以前一样,但是这个函数包含了加载图像和报告错误的功能使它可以很容易的加载图片和调试程序
*/ 
bool loadMedia()
{
    //加载成功标志
    bool success = true;
    //加载默认外观
    gKeyPressSufrace[KEY_PRESS_SURFACE_DEFAULT] = loadSurface("04_key_presses/press.bmp");
    if(gKeyPressSufrace[KEY_PRESS_SURFACE_DEFAULT] == nullptr){
        printf("Failed to load default image!\n");
        success == false;
    }

    //加载上表面
    gKeyPressSufrace[KEY_PRESS_SURFACE_UP] = loadSurface("04_key_presses/up.bmp");
    if(gKeyPressSufrace[KEY_PRESS_SURFACE_UP] == nullptr){
        printf("Failed to load up image!\n");
        success = false;
    }

    //加载下表面
    gKeyPressSufrace[KEY_PRESS_SURFACE_DOWN] = loadSurface("04_key_presses/down.bmp");
    if(gKeyPressSufrace[KEY_PRESS_SURFACE_DOWN] == nullptr){
        printf("Failed to load down image!\n");
        success = false;
    }
    //加载左表面
    gKeyPressSufrace[KEY_PRESS_SURFACE_LEFT] = loadSurface("04_key_presses/left.bmp");
    if(gKeyPressSufrace[KEY_PRESS_SURFACE_LEFT] == nullptr){
        printf("Failed to load left image!\n");
        success = false;
    }
    //加载右表面
    gKeyPressSufrace[KEY_PRESS_SURFACE_RIGHT] = loadSurface("04_key_presses/right.bmp");
    if(gKeyPressSufrace[KEY_PRESS_SURFACE_RIGHT] == nullptr){
        printf("Failed to load right image!\n");
        success = false;
    }

    return success;
}
//在loadMdia()函数函数函数中我们添加了所要需要显示的图片
int main(){

    //主循环标志
    bool quit = false;
    //事件处理程序
    SDL_Event e;
    //设置默认当前表面
    gCurrentSurface = gKeyPressSufrace[KEY_PRESS_SURFACE_DEFAULT];
    //初始化SDL并创建窗口
    if(!init()){
        printf("Failed to initialized!\n");
    }
    else{
        //添加媒体文件
        if(!loadMedia()){
            printf("Failed to load media!\n");
        }else{
                //程序运行
                while(!quit){
                    //事件处理队列
                    while(SDL_PollEvent(&e) != 0){
                        if(e.type == SDL_QUIT){
                            quit = true;
                        }
                        //用户按下键盘
                        else if(e.type == SDL_KEYDOWN){
                            switch(e.key.keysym.sym){
                                case SDLK_UP:
                                    gCurrentSurface = gKeyPressSufrace[KEY_PRESS_SURFACE_UP];
                                    break;
                                case SDLK_DOWN:
                                    gCurrentSurface = gKeyPressSufrace[KEY_PRESS_SURFACE_DOWN];
                                    break;
                                case SDLK_LEFT:
                                    gCurrentSurface = gKeyPressSufrace[KEY_PRESS_SURFACE_LEFT];
                                    break;
                                case SDLK_RIGHT:
                                    gCurrentSurface = gKeyPressSufrace[KEY_PRESS_SURFACE_RIGHT];
                                    break;
                                default:
                                    gCurrentSurface = gKeyPressSufrace[KEY_PRESS_SURFACE_DEFAULT];
                                    break;
                            }
                        }
                    }
                     //应用当前外观
                    SDL_BlitSurface(gCurrentSurface, NULL, gScreenSurface, NULL);
                    //更新窗口外观
                    SDL_UpdateWindowSurface(gWindow);
                }
            }
        }
    close();
    return 0;
}
/*
这是我们的事件循环,里面的SDL事件是一个SDL键盘事件,其中包含关键事件的信息。这是一个 SDL Keysym其中包含关键信息,把包含 SDL Keycode 的键按下,设置新的外观到窗口中
更新新的外观到窗口上
*/
程序的完整代码和媒体文件下载地址(这个二维码是我博客的地址,修改图片后缀为 .rar就可以解压,因为我不知道csdn在哪上传文件):下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值