【c++|SDL】二、读取图片、显示图片、动画制作

news2024/11/24 14:38:27

every blog every motto: You can do more than you think.
https://blog.csdn.net/weixin_39190382?type=blog

0. 前言

读取图片,显示图片,动画


SDL中有两种在屏幕上显示的方法

  • SDL_Surface: 使用软件渲染处理
  • SDL_Texture: 使用硬件加速渲染处理

1. 在界面上显示图片

修改Game.h

#ifndef __Game__
#define __Game__

#include <SDL2/SDL.h>
class Game
{

public:
    Game() {};
    ~Game() {};
    // simply set the running variable to true
    bool init(const char* title, int xpos, int ypos,int width, int height, bool fullscreen);
    void render();
    void update();
    void handleEvents();
    void clean();
    // a function to access the private running variable
    bool running() { return m_bRunning; }
private:
    bool m_bRunning;
    // SDL_Window* m_pWindow;
    // SDL_Renderer* m_pRenderer;

    SDL_Window* m_pWindow;
    SDL_Renderer* m_pRenderer;
    SDL_Texture* m_pTexture; // the new SDL_Texture variable
    SDL_Rect m_sourceRectangle; // the first rectangle
    SDL_Rect m_destinationRectangle; // another rectangle
};

#endif /* defined(__Game__) */

修改Game.cpp

修改其中的init和render函数

#include "Game.h"
#include <iostream>

using namespace std;

bool Game::init(const char* title, int xpos, int ypos, int width, int height, bool fullscreen)
{   
    int flags = 0;
    if (fullscreen)
    {
        flags = SDL_WINDOW_FULLSCREEN;
    }
    // attempt to initialize SDL
    if(SDL_Init(SDL_INIT_EVERYTHING) == 0)
    {
        std::cout << "SDL init success\n";
        // init the window
        m_pWindow = SDL_CreateWindow(title, xpos, ypos, width, height, flags);
        if(m_pWindow != 0) // window init success
        {
            std::cout << "window creation success\n";
            m_pRenderer = SDL_CreateRenderer(m_pWindow, -1, 0);
            if(m_pRenderer != 0) // renderer init success
            {
                std::cout << "renderer creation success\n";
                SDL_SetRenderDrawColor(m_pRenderer,255,255,255,255);
            }
            else
            {
                std::cout << "renderer init fail\n";
                return false; // renderer init fail
            }
        }
        else
        {
            std::cout << "window init fail\n";
            return false; // window init fail
        }
    }
    else
    {
        std::cout << "SDL init fail\n";
        return false; // SDL init fail
    }
    std::cout << "init success\n";

    SDL_Surface* pTempSurface = SDL_LoadBMP("assets/rider.bmp");
    m_pTexture = SDL_CreateTextureFromSurface(m_pRenderer, pTempSurface);
    SDL_FreeSurface(pTempSurface);

    SDL_QueryTexture(m_pTexture, NULL, NULL,&m_sourceRectangle.w,&m_sourceRectangle.h); // 获取长宽

    m_destinationRectangle.x = m_sourceRectangle.x = 0;
    m_destinationRectangle.y = m_sourceRectangle.y = 0;
    m_destinationRectangle.w = m_sourceRectangle.w;
    m_destinationRectangle.h = m_sourceRectangle.h;

    m_bRunning = true; // everything inited successfully, start the main loop
    return true;
}

void Game::render()
{
    SDL_RenderClear(m_pRenderer); // clear the renderer to the draw color
    SDL_RenderCopy(m_pRenderer, m_pTexture,&m_sourceRectangle,&m_destinationRectangle);
    SDL_RenderPresent(m_pRenderer); // draw to the screen
}


void Game::handleEvents()
{
    SDL_Event event;
    if(SDL_PollEvent(&event))
    {
        switch (event.type)
    {
        case SDL_QUIT:
            m_bRunning = false;
        break;

        default:
        break;
    }
    }
}

void Game::clean()
{
    std::cout << "cleaning game\n";
    SDL_DestroyWindow(m_pWindow);
    SDL_DestroyRenderer(m_pRenderer);
    SDL_Quit();
}

void Game::update()
{

}

在这里插入图片描述

2. 显示位置和范围

修改m_sourceRectangle和m_destinationRectangle
具体在Game.cpp SDL_QueryTexture代码下面

Game.cpp init函数代码如下,其他代码相同

bool Game::init(const char* title, int xpos, int ypos, int width, int height, bool fullscreen)
{   
    int flags = 0;
    if (fullscreen)
    {
        flags = SDL_WINDOW_FULLSCREEN;
    }
    // attempt to initialize SDL
    if(SDL_Init(SDL_INIT_EVERYTHING) == 0)
    {
        std::cout << "SDL init success\n";
        // init the window
        m_pWindow = SDL_CreateWindow(title, xpos, ypos, width, height, flags);
        if(m_pWindow != 0) // window init success
        {
            std::cout << "window creation success\n";
            m_pRenderer = SDL_CreateRenderer(m_pWindow, -1, 0);
            if(m_pRenderer != 0) // renderer init success
            {
                std::cout << "renderer creation success\n";
                SDL_SetRenderDrawColor(m_pRenderer,255,255,255,255);
            }
            else
            {
                std::cout << "renderer init fail\n";
                return false; // renderer init fail
            }
        }
        else
        {
            std::cout << "window init fail\n";
            return false; // window init fail
        }
    }
    else
    {
        std::cout << "SDL init fail\n";
        return false; // SDL init fail
    }
    std::cout << "init success\n";

    SDL_Surface* pTempSurface = SDL_LoadBMP("assets/rider.bmp");
    m_pTexture = SDL_CreateTextureFromSurface(m_pRenderer, pTempSurface);
    SDL_FreeSurface(pTempSurface);

    SDL_QueryTexture(m_pTexture, NULL, NULL,&m_sourceRectangle.w,&m_sourceRectangle.h); // 获取长宽

    m_sourceRectangle.w = 50;
    m_sourceRectangle.h = 50;
    m_destinationRectangle.x = 100;
    m_destinationRectangle.y = 100;

    m_sourceRectangle.x = 50;
    m_sourceRectangle.y = 50;
    
    // m_destinationRectangle.x = m_sourceRectangle.x = 0;
    // m_destinationRectangle.y = m_sourceRectangle.y = 0;
    m_destinationRectangle.w = m_sourceRectangle.w;
    m_destinationRectangle.h = m_sourceRectangle.h;

    m_bRunning = true; // everything inited successfully, start the main loop
    return true;
}

在这里插入图片描述

3. 动图

有多帧图片,每100ms显示其中一张,可以让图片动起来
在这里插入图片描述

#include "Game.h"
#include <iostream>

using namespace std;

bool Game::init(const char* title, int xpos, int ypos, int width, int height, bool fullscreen)
{   
    int flags = 0;
    if (fullscreen)
    {
        flags = SDL_WINDOW_FULLSCREEN;
    }
    // attempt to initialize SDL
    if(SDL_Init(SDL_INIT_EVERYTHING) == 0)
    {
        std::cout << "SDL init success\n";
        // init the window
        m_pWindow = SDL_CreateWindow(title, xpos, ypos, width, height, flags);
        if(m_pWindow != 0) // window init success
        {
            std::cout << "window creation success\n";
            m_pRenderer = SDL_CreateRenderer(m_pWindow, -1, 0);
            if(m_pRenderer != 0) // renderer init success
            {
                std::cout << "renderer creation success\n";
                SDL_SetRenderDrawColor(m_pRenderer,255,255,255,255);
            }
            else
            {
                std::cout << "renderer init fail\n";
                return false; // renderer init fail
            }
        }
        else
        {
            std::cout << "window init fail\n";
            return false; // window init fail
        }
    }
    else
    {
        std::cout << "SDL init fail\n";
        return false; // SDL init fail
    }
    std::cout << "init success\n";

    // SDL_Surface* pTempSurface = SDL_LoadBMP("assets/rider.bmp");
    SDL_Surface* pTempSurface = SDL_LoadBMP("assets/animate.bmp");
    m_pTexture = SDL_CreateTextureFromSurface(m_pRenderer, pTempSurface);
    SDL_FreeSurface(pTempSurface);

    SDL_QueryTexture(m_pTexture, NULL, NULL,&m_sourceRectangle.w,&m_sourceRectangle.h); // 获取长宽

    m_sourceRectangle.x = 0;
    m_sourceRectangle.y = 0;
    m_sourceRectangle.w = 128;
    m_sourceRectangle.h = 82;

    m_destinationRectangle.x = 0;
    m_destinationRectangle.y = 0;

    
    // m_destinationRectangle.x = m_sourceRectangle.x = 0;
    // m_destinationRectangle.y = m_sourceRectangle.y = 0;
    m_destinationRectangle.w = m_sourceRectangle.w;
    m_destinationRectangle.h = m_sourceRectangle.h;

    m_bRunning = true; // everything inited successfully, start the main loop
    return true;
}

void Game::render()
{
    SDL_RenderClear(m_pRenderer); // clear the renderer to the draw color
    // SDL_RenderCopy(m_pRenderer, m_pTexture,0,0);
    SDL_RenderCopy(m_pRenderer, m_pTexture,&m_sourceRectangle,&m_destinationRectangle);
    SDL_RenderPresent(m_pRenderer); // draw to the screen
}


void Game::handleEvents()
{
    SDL_Event event;
    if(SDL_PollEvent(&event))
    {
        switch (event.type)
    {
        case SDL_QUIT:
            m_bRunning = false;
        break;

        default:
        break;
    }
    }
}

void Game::clean()
{
    std::cout << "cleaning game\n";
    SDL_DestroyWindow(m_pWindow);
    SDL_DestroyRenderer(m_pRenderer);
    SDL_Quit();
}

void Game::update()
{
    m_sourceRectangle.x = 128 * int(((SDL_GetTicks() / 100) % 6));

}

在这里插入图片描述

可以翻转图片

void Game::render()
{
    SDL_RenderClear(m_pRenderer); // clear the renderer to the draw color
    // SDL_RenderCopy(m_pRenderer, m_pTexture,0,0);
    // SDL_RenderCopy(m_pRenderer, m_pTexture,&m_sourceRectangle,&m_destinationRectangle);
    SDL_RenderCopyEx(m_pRenderer, m_pTexture,&m_sourceRectangle, &m_destinationRectangle,0, 0, SDL_FLIP_HORIZONTAL); // pass in the horizontal flip
    SDL_RenderPresent(m_pRenderer); // draw to the screen
}

3. SDL_image

前面用的是SDL_LoadBMP只能加载bmp图片,SDL_image可以加载很多格式的图片,包括png,jpg,bmp,tiff,pcx,tif,lbm,xpm,gif,tk和xv等。

Game.h中引入SDL_image

#include <SDL2/SDL_image.h>

修改加载图片代码Game.cpp

SDL_Surface* pTempSurface = IMG_Load("assets/animate.png");

编译修改为:

g++ m14main.cpp Game.cpp  -o m14 -lSDL2 -lSDL2_image

Game.cpp代码如下:

#include "Game.h"
#include <iostream>

using namespace std;

bool Game::init(const char* title, int xpos, int ypos, int width, int height, bool fullscreen)
{   
    int flags = 0;
    if (fullscreen)
    {
        flags = SDL_WINDOW_FULLSCREEN;
    }
    // attempt to initialize SDL
    if(SDL_Init(SDL_INIT_EVERYTHING) == 0)
    {
        std::cout << "SDL init success\n";
        // init the window
        m_pWindow = SDL_CreateWindow(title, xpos, ypos, width, height, flags);
        if(m_pWindow != 0) // window init success
        {
            std::cout << "window creation success\n";
            m_pRenderer = SDL_CreateRenderer(m_pWindow, -1, 0);
            if(m_pRenderer != 0) // renderer init success
            {
                std::cout << "renderer creation success\n";
                SDL_SetRenderDrawColor(m_pRenderer,255,0,0,255);
            }
            else
            {
                std::cout << "renderer init fail\n";
                return false; // renderer init fail
            }
        }
        else
        {
            std::cout << "window init fail\n";
            return false; // window init fail
        }
    }
    else
    {
        std::cout << "SDL init fail\n";
        return false; // SDL init fail
    }
    std::cout << "init success\n";

    // SDL_Surface* pTempSurface = SDL_LoadBMP("assets/rider.bmp");
    // SDL_Surface* pTempSurface = SDL_LoadBMP("assets/animate.bmp");
    // SDL_Surface* pTempSurface = IMG_Load("assets/animate.png");
    SDL_Surface* pTempSurface = IMG_Load("assets/animate-alpha.png");
    m_pTexture = SDL_CreateTextureFromSurface(m_pRenderer, pTempSurface);
    SDL_FreeSurface(pTempSurface);

    SDL_QueryTexture(m_pTexture, NULL, NULL,&m_sourceRectangle.w,&m_sourceRectangle.h); // 获取长宽

    m_sourceRectangle.x = 0;
    m_sourceRectangle.y = 0;
    m_sourceRectangle.w = 128;
    m_sourceRectangle.h = 82;

    m_destinationRectangle.x = 0;
    m_destinationRectangle.y = 0;

    
    // m_destinationRectangle.x = m_sourceRectangle.x = 0;
    // m_destinationRectangle.y = m_sourceRectangle.y = 0;
    m_destinationRectangle.w = m_sourceRectangle.w;
    m_destinationRectangle.h = m_sourceRectangle.h;

    m_bRunning = true; // everything inited successfully, start the main loop
    return true;
}

void Game::render()
{
    SDL_RenderClear(m_pRenderer); // clear the renderer to the draw color
    // SDL_RenderCopy(m_pRenderer, m_pTexture,0,0);
    // SDL_RenderCopy(m_pRenderer, m_pTexture,&m_sourceRectangle,&m_destinationRectangle);
    SDL_RenderCopyEx(m_pRenderer, m_pTexture,&m_sourceRectangle, &m_destinationRectangle,0, 0, SDL_FLIP_HORIZONTAL); // pass in the horizontal flip
    SDL_RenderPresent(m_pRenderer); // draw to the screen
}


void Game::handleEvents()
{
    SDL_Event event;
    if(SDL_PollEvent(&event))
    {
        switch (event.type)
    {
        case SDL_QUIT:
            m_bRunning = false;
        break;

        default:
        break;
    }
    }
}

void Game::clean()
{
    std::cout << "cleaning game\n";
    SDL_DestroyWindow(m_pWindow);
    SDL_DestroyRenderer(m_pRenderer);
    SDL_Quit();
}

void Game::update()
{
    m_sourceRectangle.x = 128 * int(((SDL_GetTicks() / 100) % 6));

}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1265580.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++二分查找、离线算法:最近的房间

作者推荐 利用广度优先或模拟解决米诺骨牌 本文涉及的基础知识点 二分查找算法合集 题目 一个酒店里有 n 个房间&#xff0c;这些房间用二维整数数组 rooms 表示&#xff0c;其中 rooms[i] [roomIdi, sizei] 表示有一个房间号为 roomIdi 的房间且它的面积为 sizei 。每一…

基于SSM的云鑫曦科技办公自动化管理系统设计与实现

基于SSM的云鑫曦科技办公自动化管理系统设计与实现 摘 要: 随着时代的发展&#xff0c;单位办公方式逐渐从传统的线下纸张办公转向了使用个人pc的线上办公&#xff0c;办公效率低下的传统纸质化办公时代的淘汰&#xff0c;转型到信息化办公时代&#xff0c;面对当今数据逐渐膨…

上海亚商投顾:沪指震荡反弹 汽车产业链掀涨停潮

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 三大指数昨日震荡反弹&#xff0c;北证50指数跌超4%&#xff0c;近50只北交所个股跌超10%。 新能源车产业链掀…

探索短剧市场的商机:打造短视频平台的全方位指南

目前短剧市场蓬勃发展&#xff0c;上半年备案数远超电视剧&#xff0c;彰显了短剧小程序市场潜力巨大&#xff0c;商业价值巨大。用户对短小精悍娱乐内容的需求不断增加&#xff0c;而新兴市场中有限的短剧小程序正好能够迎合这一需求。 搭建短视频平台的关键步骤&#xff1a; …

Postgres 数据库中 ULID 和 UUID 的性能

大家好&#xff01;在本文中&#xff0c;我想分享我对经常用作标识符的数据类型的知识和看法。今天我们将同时讨论两个主题。这些是数据库端按键和键的数据类型衡量的搜索速度。 我将使用PostgreSQL数据库和演示Java服务来比较查询速度。 UUID 和 ULID 为什么我们需要某种难…

MyBatis使用教程详解<下>

回顾上一篇博文,我们讲了如何使用注解/XML的方式来操作数据库,实际上,一个Mapper接口的实现,这两种方式是可以并存的. 上一篇博文中,我们演示的都是比较简单的SQL语句,没有设计到复杂的逻辑,本篇博文会讲解复杂SQL的实现及一些细节处理.话不多说,让我们开始吧. 一. #{}和${} …

基于LNMP快速搭建WordPress平台

目录 1 LNMP简介 2 WordPress简介 3 安装MySQL环境 3.1 安装MySQL 3.1.1 下载wget工具 3.1.2 下载MySQL官方yum源安装包 3.1.3 安装MySQL官方yum源 3.1.4 mysql安装 3.2 启动MySQL 3.3 获取默认密码 3.4 登录MySQL ​ 3.5 修改密码 3.6 创建WordPress数据库并授权 3.6.1 创…

5 时间序列预测入门:LSTM+Transformer

0 引言 论文地址&#xff1a;https://arxiv.org/abs/1706.03762 1 Transformer Transformer 模型是一种用于处理序列数据的深度学习模型&#xff0c;主要用于解决自然语言处理&#xff08;NLP&#xff09;任务。它在许多 NLP 任务中取得了重大突破&#xff0c;如机器翻译、文本…

微服务实战系列之Cache

前言 欢迎来到Cache&#xff08;缓存&#xff09;的世界&#xff01; 自从世界第一台计算机诞生之日起&#xff0c;人们对效率的渴望逐步增强。从CPU到存储&#xff0c;从芯片到内存&#xff0c;一批又一批的先驱以一种孜孜不倦的“工匠”精神&#xff0c;为计算机运行效率的提…

【数据结构 —— 二叉树的链式结构实现】

数据结构 —— 二叉树的链式结构实现 1.树的概念及其结构1.1.树概念1.2.树的结构1.3树的相关概念1.4.树的表示1.5. 树在实际中的运用&#xff08;表示文件系统的目录树结构&#xff09; 2.二叉树的概念及其结构2.1二叉树的概念2.2.现实中的二叉树&#xff1a;2.3. 特殊的二叉树…

Flutter开发type ‘Future<int>‘ is not a subtype of type ‘int‘ in type cast错误

文章目录 问题描述错误源码 问题分析解决方法修改后的代码 问题描述 今天有个同事调试flutter程序时报错&#xff0c;问我怎么解决&#xff0c;程序运行时报如下错误&#xff1a; type ‘Future’ is not a subtype of type ‘int’ in type cast 错误源码 int order Databas…

FFmpeg介绍

官方网站&#xff1a;http://www.ffmpeg.org/ 项目组成 libavformat 封装模块&#xff0c;封装了Protocol层和Demuxer、Muxer层&#xff0c;使得协议和格式对于开发者来说是透明的。FFmpeg能否支持一种封装格式的视频的封装与解封装&#xff0c;完全取决于这个库&#xff0c…

《微信小程序开发从入门到实战》学习三十五

4.2 云开发JSON数据库 4.2.3 权限控制 在云开发控制台可以对数据库中的数据进行操作&#xff0c; 在小程序端和云函数可以分别使用小程序API和服务端API对数据中的数据进行操作。 以上操作受到权限控制。 对数据库进行查询属于读操作&#xff0c;增删改操作属于写操作。 …

Python自动化办公:PDF文件的加密与解密

在本篇文章中&#xff0c;我们将介绍如何使用PyPDF2库对PDF文件进行加密和解密操作。 包括如何给PDF文件添加密码&#xff0c;以及如何从受密码保护的PDF文件中删除密码。 注&#xff1a;删除密码的操作&#xff0c;前提是需要知道密码哦 1. 安装PyPDF2库 首先&#xff0c;…

【小黑嵌入式系统第十课】μC/OS-III概况——实时操作系统的特点、基本概念(内核任务中断)、与硬件的关系实现

文章目录 一、为什么要学习μC/OS-III二、嵌入式操作系统的发展历史三、实时操作系统的特点四、基本概念1. 前后台系统2. 操作系统3. 实时操作系统&#xff08;RTOS&#xff09;4. 内核5. 任务6. 任务优先级7. 任务切换8. 调度9. 非抢占式&#xff08;合作式&#xff09;内核10…

el-table,列表合并,根据名称列名称相同的品名将其它列值相同的进行合并

el-table,列表合并,根据名称列名称相同的品名讲其它列值相同的进行合并,并且不能垮品名合并 如图 用到el-table合并行的方法合并 tableSpanMethod({ row, column, rowIndex, columnIndex }) {if (column.property "materielName") {//合并商品名const _row this…

CI/CD 构建中能保护好 SSHKEY吗?

目录 背景 方案 编码存储 逐行存储 合并存储 打马赛克 结论 背景 使用极狐GitLab CI/CD&#xff0c;在部署方面&#xff0c;主要有两种方式&#xff1a; 部署到K8S集群 Push模式&#xff1a;流水线通过kubectl执行命令部署&#xff0c;这需要把K8S的权限给流水线&#xf…

【python程序】把小于10的数值都变成1

【python程序】把小于10的数值都变成1 import numpy as np import xarray as xra xr.DataArray(np.arange(25).reshape(5, 5)) a[np.where(a < 10)] 1 print(a)

微信小程序+中草药分类+爬虫+torch

1 介绍 本项目提供中草药数据集&#xff0c;使用gpu、cpu版本的torch版本进行训练&#xff0c;将模型部署到后端flask&#xff0c;最后使用微信小程序进行展示出来。 数据爬虫可以参考&#xff1a;http://t.csdnimg.cn/7Olus 项目中的爬虫代码&#xff0c;并且本项目提供相同的…

拆解按摩器:有意思的按键与LED控制电路,学习借鉴一下!

拆解 外观和配色个人感觉还行,比较青春 拉开拉链&#xff0c;拆开外面的布面&#xff0c;里面还有一层纱面 按键部分使用魔术贴固定 拆开纱面后&#xff0c;看到里面的结构&#xff0c;整体是一个海绵 可以看到如下&#xff0c;电池&#xff0c;按键板&#xff0c;充电线的三条…