zoukankan      html  css  js  c++  java
  • 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循环中就可以看到。

  • 相关阅读:
    URL传参数导致乱码
    [转载]HTTP协议详解
    https中关于密码学的基础概念
    JavaScript高级程序设计 第四章 变量、作用域和内存问题
    JavaScript高级程序设计 第三章 基本概念
    实现sticky footer的五种方法
    css grid学习材料整理
    ASP.NET MVC编程——视图
    Entity Framework——配置文件设置
    Entity Framework——记录执行的命令信息
  • 原文地址:https://www.cnblogs.com/hpcpp/p/7940545.html
Copyright © 2011-2022 走看看