SDL2.0学习教程(二)——别什么都塞进main里

 英文版作者代码:https://github.com/Twinklebear/TwinklebearDev-Lessons

中文版翻译:http://adolfans.github.io/sdltutorialcn/blog/2013/01/28/lesson-2-dont-put-everything-in-main/

觉得中文版翻译讲得有些繁琐,就按照自己的理解,整理如下:

main.cpp文件中:

#include <SDL.h>
#include <string>
#include <iostream>
#include "cleanup.h"

//屏幕的宽高常量
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;

void logSDLError(std::ostream &os, const std::string &msg){
    os << msg << " error: " << SDL_GetError() << std::endl;
}

SDL_Texture* loadTexture(const std::string &file, SDL_Renderer *ren){
    SDL_Texture *texture = nullptr;
    SDL_Surface *loadedImage = SDL_LoadBMP(file.c_str());
    if (loadedImage != nullptr)
    {
        texture = SDL_CreateTextureFromSurface(ren, loadedImage);
        SDL_FreeSurface(loadedImage);
        if (texture == nullptr)
        {
            logSDLError(std::cout, "CreateTextureFromSurface");
        }
    }
    else
    {
        logSDLError(std::cout, "LoadBMP");
    }
    return texture;
}

void renderTexture(SDL_Texture *tex, SDL_Renderer *ren, int x, int y)
{
    SDL_Rect dst;
    dst.x = x;
    dst.y = y;
    SDL_QueryTexture(tex, NULL, NULL, &dst.w, &dst.h);
    SDL_RenderCopy(ren, tex, NULL, &dst);
}

int main(int argc, char *args[])
{
    if (SDL_Init(SDL_INIT_VIDEO) != 0)
    {
        logSDLError(std::cout, "SDL_Init");
        return 1;
    }

    SDL_Window *window = SDL_CreateWindow("Lesson 2", 100, 100, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
    if (window == nullptr)
    {
        logSDLError(std::cout, "CreateWindow");
        SDL_Quit();
        return 1;
    }

    SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    if (renderer == nullptr)
    {
        logSDLError(std::cout, "CreateRenderer");
        cleanup(window);
        SDL_Quit();
        return 1;
    }

    //The textures we'll be using
    SDL_Texture *background = loadTexture("background.bmp", renderer);
    SDL_Texture *image = loadTexture("image.bmp", renderer);

    if (background == nullptr || image == nullptr)
    {
        cleanup(background, image, renderer, window);
        SDL_Quit();
        return 1;
    }

    for (int i = 0; i < 3; ++i)
    {
        SDL_RenderClear(renderer);

        int bW, bH;
        SDL_QueryTexture(background, NULL, NULL, &bW, &bH);

        renderTexture(background, renderer, 0, 0);
        renderTexture(background, renderer, bW, 0);
        renderTexture(background, renderer, 0, bH);
        renderTexture(background, renderer, bW, bH);

        int iW, iH;
        SDL_QueryTexture(image, NULL, NULL, &iW, &iH);
        int x = SCREEN_WIDTH / 2 - iW / 2;
        int y = SCREEN_HEIGHT / 2 - iH / 2;
        renderTexture(image, renderer, x, y);

        SDL_RenderPresent(renderer);
        SDL_Delay(1000);
    }

    cleanup(background, image, renderer, window);
    SDL_Quit();
    return 0;
}

clearn.h文件中:

#ifndef CLEANUP_H
#define CLEANUP_H

#include <utility>
#include <SDL.h>

/*
 * Recurse through the list of arguments to clean up, cleaning up
 * the first one in the list each iteration.
 */
template<typename T, typename... Args>
void cleanup(T *t, Args&&... args){
    //Cleanup the first item in the list
    cleanup(t);
    //Clean up the remaining arguments
    cleanup(std::forward<Args>(args)...);
}
/*
 * These specializations serve to free the passed argument and also provide the
 * base cases for the recursive call above, eg. when args is only a single
 * item one of the specializations below will be called by
 * cleanup(std::forward<Args>(args)...), ending the recursion
 */
template<>
inline void cleanup<SDL_Window>(SDL_Window *win){
    if (!win){
        return;
    }
    SDL_DestroyWindow(win);
}
template<>
inline void cleanup<SDL_Renderer>(SDL_Renderer *ren){
    if (!ren){
        return;
    }
    SDL_DestroyRenderer(ren);
}
template<>
inline void cleanup<SDL_Texture>(SDL_Texture *tex){
    if (!tex){
        return;
    }
    SDL_DestroyTexture(tex);
}
template<>
inline void cleanup<SDL_Surface>(SDL_Surface *surf){
    if (!surf){
        return;
    }
    SDL_FreeSurface(surf);
}

#endif

 运行结果:

背景是4张小图片平铺而成,看for循环中就可以看到。

转载于:https://www.cnblogs.com/hpcpp/p/7940545.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SDL是Simple DirectMedia Layer(简易直控媒体层)的缩写。它是一个跨平台的多媒体库,以用于直接控制底层的多媒体硬件的接口。这些多媒体功能包括了音频、键盘和鼠标(事件)、游戏摇杆等。当然,最为重要的是提供了2D图形帧缓冲(framebuffer)的接口,以及为OpenGL与各种操作系统之间提供了统一的标准接口以实现3D图形。从这些属性我们可以看出,SDL基本上可以认为是为以电脑游戏为核心开发的多媒体库。 SDL支持主流的操作系统,包括Windows和Linux。在官方的介绍中,我们可以找到它所支持的其他平台。(SDL supports Linux, Windows, Windows CE, BeOS, MacOS, Mac OS X, FreeBSD, NetBSD, OpenBSD, BSD/OS, Solaris, IRIX, and QNX. )。SDL本身从C语言开发,并且能很好的在C++等高级语言中使用。在官方可以看到SDL所支持的语言很多。(Including Ada, C#, Eiffel, Erlang, Euphoria, Guile, Haskell, Java, Lisp, Lua, ML, Objective C, Pascal, Perl, PHP, Pike, Pliant, Python, Ruby, Smalltalk, and Tcl. ) SDL在GNU LGPL version 2下发布,这意味着你可以免费的使用。并且可以免费的用于商业软件的制作(只要你直接使用SDL的动态链接库,Windows下的SDL.dll)。如果你将SDL库编译进了自己的进制代码中,你需要指明你所使用的SDL库的版本以及包括你自己修改的源代码,并说明这些代码的原始出处。这是很宽松的法律,你可以用如此强大的多媒体库完全合法的免费开发商业游戏。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值