用 SDL2 处理石器精灵图

  一个精灵图,由多个固定间隔的图标组成。利用精灵图的好处就是不必将图标逐个读入内存进行操作。我们可以将精灵图中需要的部分用一个个矩形截取下来,然后再输出到渲染器上。


环境:SDL2 + VC++2015


下面的代码将打开sprite.png,并对相应的操作做出响应。

C
上面就是一个精灵图,由多个固定间隔的图标组成。利用精灵图的好处就是不必将图标逐个读入内存进行操作。我们可以将精灵图中需要的部分用一个个矩形截取下来,然后再输出到渲染器上。
环境:SDL2 + VC++2015下面的代码将打开sprite.png,并对相应的操作做出响应。#include <stdexcept>#include <string>#include <iostream>#include "SDL.h"#include "SDL_image.h"//屏幕宽度const int SCREEN_WIDTH = 500;const int SCREEN_HEIGHT = 500;//全局窗口和渲染器SDL_Window *window = nullptr;SDL_Renderer *renderer = nullptr;//记录SDL错误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 = IMG_LoadTexture(ren, file.c_str());
    if (texture == nullptr) logSDLError(std::cout, "LoadTexture");
    return texture;}//根据坐标生成截取区域并复制输出到渲染器void renderTexture(SDL_Texture *tex, SDL_Renderer *ren, int x, int y, SDL_Rect *clip = nullptr){
    //目标截面区域初始化,提供目标在渲染器的坐标
    SDL_Rect dst; dst.x = x; dst.y = y;
    //源截面区域不为空,将其值赋给目标截面
    if (clip != nullptr) { dst.w = clip->w; dst.h = clip->h; }
    //将截面输出到渲染器
    SDL_RenderCopy(ren, tex, clip, &dst);}int main(int argc, char** argv){
    //初始化SDL
    if (SDL_Init(SDL_INIT_EVERYTHING) == -1)
    {
        std::cout << SDL_GetError() << std::endl;
        return 1;
    }

    //创建窗口
    window = SDL_CreateWindow("Lesson 5",
        SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
        SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
    if (window == nullptr)
    {
        std::cout << SDL_GetError() << std::endl;
        return 2;
    }

    //创建渲染器
    renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    if (renderer == nullptr)
    {
        std::cout << SDL_GetError() << std::endl;
        return 3;
    }

    //创建纹理
    SDL_Texture *image = nullptr;
    try    {
        image = loadTexture("sprite.png", renderer);
    }
    catch (const std::runtime_error &e)
    {
        std::cout << e.what() << std::endl;
        return 4;
    }

    //iW,iH 表示截面宽高
    int iW = 100, iH = 100;
    //x,y 分别为截面在渲染器输出的坐标
    int x = SCREEN_WIDTH / 2 - iW / 2;
    int y = SCREEN_HEIGHT / 2 - iH / 2;

    //为精灵图设置截面
    SDL_Rect clips[4];

    //初始化截面信息
    for (int i = 0; i < 4; ++i)
    {
        clips[i].x = i / 2 * iW;
        clips[i].y = i % 2 * iH;
        clips[i].w = iW;
        clips[i].h = iH;
    }

    //表示将要输出的截面
    int useClip = 0;

    SDL_Event e;
    bool quit = false;
    //主循环
    while (!quit)
    {
        //事件轮询
        while (SDL_PollEvent(&e))
        {
            //按右上角的X退出
            if (e.type == SDL_QUIT) quit = true;

            //点击鼠标随机输出截面
            if (e.type == SDL_MOUSEBUTTONDOWN) useClip = rand() % 4;

            //使用数字键决定输出截面,分别有1,2,3,4
            if (e.type == SDL_KEYDOWN)
            {
                switch (e.key.keysym.sym)
                {
                case SDLK_1:
                case SDLK_KP_1:
                    useClip = 0;
                    break;
                case SDLK_2:
                case SDLK_KP_2:
                    useClip = 1;
                    break;
                case SDLK_3:
                case SDLK_KP_3:
                    useClip = 2;
                    break;
                case SDLK_4:
                case SDLK_KP_4:
                    useClip = 3;
                    break;
                case SDLK_ESCAPE:
                    quit = true;
                    break;
                default:
                    break;
                }
            }
        }
        //清空渲染器
        SDL_RenderClear(renderer);
        //绘制材质
        renderTexture(image, renderer, x, y, &clips[useClip]);
        //呈现渲染器
        SDL_RenderPresent(renderer);
    }

    //释放资源
    SDL_DestroyTexture(image);
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);

    SDL_Quit();

    return 0;}


免责声明:本内容来于网络,不代表本站的观点和立场。

相关阅读

  • group1.txt详解

    group1.txt详解

    【教学名称】:group1.txt详解【用途说明】:遇怪时会遇到的怪物  看一下教学因该会懂喔^^【教学开始】: 沙姆岛魔兽,1509,19421,19422,5146,,,,,,,,,,1,,,,,,,,,这是2诶人龙...

    2019.11.06 10:53:27作者:石器
  • skillcode.txt详解

    skillcode.txt详解

    【教学名称】:skillcode.txt详解【用途说明】:限制某些技能只给该宠物学习【教学开始】: 以下为例:首先在skillcode加入 限制捐献只给扑满乌力学习的条件如下资料:扑满乌力 1558 725 Aa&pets...

    2019.11.06 10:53:05作者:石器
  • 修改代码仿石器官方显示经验值

    修改代码仿石器官方显示经验值

    我不知道是不是目前的端都是仿官方化的经验值我的端是经验直跑完升级后NEXT那栏会显示的不是累计经验值而是下ㄧ级跟前ㄧ级的经验差然后我的上面经验值则变回0正服是下面是下次升级所需的总累计经验值上面是目前你所得到的累计经验值原本以为要动很多档案...

    2019.11.06 10:52:38作者:石器时代
  • 老石器实现自动寻路的相关代码

    老石器实现自动寻路的相关代码

    距离估计与实际值越接近,估价函数取得就越好例如对于几何路网来说,可以取两节点间曼哈顿距离做为距离估计,即f=g(n) + (abs(dx - nx) + abs(dy - ny));这样估价函数f(n)在g(n)一定的情况下,会或多或少的受...

    2019.11.06 10:51:53作者:石器
  • 发属于自己的石器时代,都需要哪一些东西?

    发属于自己的石器时代,都需要哪一些东西?

    「第一篇」由于很多原因,所以我决定用源代码进行二次开发学习,创造属于自己的石器时代的版本和功能。相信很多朋友也曾经想过,如果能够拥有一套完全属于自己的石器时代的版本,该是多么自由与方便。这里说的完全属于石器时代的版本,具体应该包括哪一些?很...

    2019.11.06 10:51:15作者:石器时代
  • 用 SDL2 处理石器精灵图

    用 SDL2 处理石器精灵图

      一个精灵图,由多个固定间隔的图标组成。利用精灵图的好处就是不必将图标逐个读入内存进行操作。我们可以将精灵图中需要的部分用一个个矩形截取下来,然后再输出到渲染器上。环境:SDL2 + VC++2015下面的代码将打开sprite...

    2019.11.06 10:50:43作者:石器