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));
}