在上一章,我们已经了解到如何设置窗口背景,现在,我们将继续引进几张新图片,让它能够在窗口移动。下面的链接可以回顾前面的内容:
1.我们先要确定我们在窗口移动的是哪些图片和图片的大小。
string a[] = { "furong1.jpg",
"furong2.jpg",
"furong3.jpg",
"furong4.jpg",
"furong5.jpg"
};
const int image_longer = 100;
我们将这些图片放进了一个数组中,方便后面的读取操作,这里放的是图片的位置,因为我是把图片放在当前编译文件夹下的,所以直接用的图片名字,如果放在其他的文件夹下,要写出文件夹的位置。
2.编写一个函数,用来将图片的结构转换成纹理数据,也就是能够显示在窗口上的结构数据。
SDL_Texture* texture_image(const string& oip, SDL_Renderer* render)
{
// 加载移动图片
SDL_Surface* move_surface = IMG_Load(oip.c_str());
if (!move_surface) {
printf("移动的图片不能被加载! SDL_image Error: %s\n", IMG_GetError());
return nullptr;
}
//将图片数据转换成纹理数据
SDL_Texture* texture = SDL_CreateTextureFromSurface(render, move_surface);
if (!texture) {
printf("不能将Surface转换为Texrure! SDL_Error: %s\n", SDL_GetError());
return nullptr;
}
return texture;
}
在上一章我们已经了解过了,`SDL_Suface()`函数只是将图片初步处理,通常用于存储未经优化的原始图像数据,而`SDL_Texture()`函数是一种专为渲染优化的数据结构,将图片数据转换成纹理数据,也就能直接映射到窗口上显示出来了。
3.初始化图片位置
void RandomPoints(int longer,int higt, int image_longer)
{
\\定义一个随机数生成器,它可以定义一个伪随机数。
default_random_engine e;
\\定义一个整数范围在(1,longer-image_longer)的均匀分布,用于生成指定范围内的随机整数。
uniform_int_distribution<int> u(1, (longer - image_longer));
\\保证在多次调用时能保留种子数,这确保了每次程序运行时生成的随机数序列是不同的。
static bool seeded = false;
if (!seeded) {
e.seed(static_cast<unsigned int>(time(0)));
seeded = true;
}
for (int i = 0; i <= 4; i++)
{
lo[i].x = u(e);
cout << i << " " << lo[i].x << endl;
}
std::uniform_int_distribution<int> n(1, (higt - image_longer));
for (int i = 0; i <= 4; i++)
{
lo[i].y = n(e);
cout << i << " " << lo[i].y << endl;
}
}
这里我们是通过一个创建随机数,确定图片距离窗口左上角的位置,我们使用当前时间作为种子,保证随机数生成器能够生成随机序列。(在概率论和统计学中,均匀分布也叫矩形分布,它是对称概率分布,在相同长度间隔的分布概率是等可能的。)
4.使图片能够自主移动
//初始化每张图片在x轴和y轴上的移动方向
int v_x[] = {1,1,1,1,1};
int v_y[] = {1,1,1,1,1};
bool run=true;
while(!run){
for (int i = 0; i <= 4; i++)
{
//获取图片的纹理
SDL_Texture* texture = texture_image(a[i], renderer);
//每次移动3像素。
lo[i].x += v_x[i]*3;
lo[i].y += v_y[i]*3;
//如果图片碰到了窗口边缘,向反方向移动。
if (lo[i].x <= 0|| lo[i].x >= (length - image_longer))
v_x[i] *= -1;
else if(lo[i].y<=0||lo[i].y>=(high-image_longer))
v_y[i] *=-1;
//更新图片位置
SDL_Rect rect = { lo[i].x,lo[i].y,image_longer,image_longer};
SDL_RenderCopy(renderer, texture, NULL, &rect);
//释放纹理,防止空间泄露
SDL_DestroyTexture(texture);
}
}
我们通过不断的更新画面,来达到使图片有动感的效果。但我这里的做法是不准确的,每台电脑的屏幕刷新频率不是统一的,在我的电脑上,可能速度正合适,但是放在其他的电脑上就会出现过快或者过慢的现象。如何避免这种现象,我下次讲吧。最近耍如鸢耍的太入迷了,(这游戏好上头,现在好困)。
5.总的代码
#include <SDL.h>
#include <SDL_image.h>
#include<stdio.h>
#include<string>
#include<random>
#include<ctime>
#include<iostream>
const int length = 474;
const int high = 998;
const int image_longer = 100;
int v_x[] = {1,1,1,1,1};
int v_y[] = {1,1,1,1,1};
using namespace std;
string a[] = { "furong1.jpg",
"furong2.jpg",
"furong3.jpg",
"furong4.jpg",
"furong5.jpg"
};
typedef struct location
{
int x;
int y;
}location;
location lo[5];
SDL_Texture* texture_image(const string& oip, SDL_Renderer* render);
void RandomPoints(int longer, int image_longer,int higt);
int main(int argc, char* argv[]) {
// 初始化 SDL
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
printf("SDL视频子系统不能被初始化, SDL_Error: %s\n", SDL_GetError());
return -1;
}
// 初始化 SDL_image 以支持 JPG 格式
if (!(IMG_Init(IMG_INIT_JPG) & IMG_INIT_JPG)) {
printf("SDL_image 不能被初始化! SDL_image Error: %s\n", IMG_GetError());
return -1;
}
// 创建窗口
SDL_Window* window = SDL_CreateWindow(
"SDL Background ",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
length, high,
SDL_WINDOW_SHOWN
);
if (!window) {
printf("Window could not be created! SDL_Error: %s\n", SDL_GetError());
return -1;
}
// 创建渲染器
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (!renderer) {
printf("渲染器不能被创造! SDL_Error: %s\n", SDL_GetError());
return -1;
}
// 加载背景图片
SDL_Surface* background_surface = IMG_Load("OIP-C.jpg");
if (!background_surface) {
printf("xiaomu.jpg 不能被加载! SDL_image Error: %s\n", IMG_GetError());
return -1;
}
// 将图片数据转换成纹理数据
SDL_Texture* background_texture = SDL_CreateTextureFromSurface(renderer, background_surface);
if (!background_texture) {
printf("不能将Surface转换为Texrure! SDL_Error: %s\n", SDL_GetError());
return -1;
}
// 释放Surface占用的内存
SDL_FreeSurface(background_surface);
//创建初始位置
RandomPoints(length,image_longer,high);
// 主循环
bool quit = false;
SDL_Event event;
while (!quit) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
quit = true;
}
}
// 清屏
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
// 渲染背景
SDL_RenderCopy(renderer, background_texture, NULL, NULL);
for (int i = 0; i <= 4; i++)
{
SDL_Texture* texture = texture_image(a[i], renderer);
lo[i].x += v_x[i]*3;
lo[i].y += v_y[i]*3;
if (lo[i].x <= 0|| lo[i].x >= (length - image_longer))
v_x[i] *= -1;
else if(lo[i].y<=0||lo[i].y>=(high-image_longer))
v_y[i] *=-1;
SDL_Rect rect = { lo[i].x,lo[i].y,image_longer,image_longer};
SDL_RenderCopy(renderer, texture, NULL, &rect);
SDL_DestroyTexture(texture);
}
// 呈现内容
SDL_RenderPresent(renderer);
}
// 清理资源
SDL_DestroyTexture(background_texture);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
IMG_Quit();
SDL_Quit();
return 0;
}
SDL_Texture* texture_image(const string& oip, SDL_Renderer* render)
{
// 加载移动图片
SDL_Surface* move_surface = IMG_Load(oip.c_str());
if (!move_surface) {
printf("移动的图片不能被加载! SDL_image Error: %s\n", IMG_GetError());
return nullptr;
}
//将图片数据转换成纹理数据
SDL_Texture* texture = SDL_CreateTextureFromSurface(render, move_surface);
if (!texture) {
printf("不能将Surface转换为Texrure! SDL_Error: %s\n", SDL_GetError());
return nullptr;
}
return texture;
}
void RandomPoints(int longer, int image_longer,int higt)
{
std::default_random_engine e;
std::uniform_int_distribution<int> u(1, (longer - image_longer));
static bool seeded = false;
if (!seeded) {
e.seed(static_cast<unsigned int>(time(0)));
seeded = true;
}
for (int i = 0; i <= 4; i++)
{
lo[i].x = u(e);
cout << i << " " << lo[i].x << endl;
}
std::uniform_int_distribution<int> n(1, (higt - image_longer));
for (int i = 0; i <= 4; i++)
{
lo[i].y = n(e);
cout << i << " " << lo[i].y << endl;
}
}
6.运行结果
<iframe allowfullscreen="true" data-mediaembed="csdn" frameborder="0" id="QBihhHeI-1728226832898" src="https://live.csdn.net/v/embed/428146"></iframe>SDL下图片移动
代码还有很多可以改进的地方,因为我也是新手,哈哈哈哈哈哈哈,所以很多地方也没有优化思路,自己也不知道咋优化,还在学习中,大家一起加油啊!
标签:longer,int,创建,image,texture,SDL,移动,图片 From: https://blog.csdn.net/weixin_73918008/article/details/142720108