- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在关注 LazyFoo 的 SDL tutorials (并且还添加了我自己的组织和编码风格)。当我到达他的animation tutorial我决定做一个单独的类来存储与动画算法相关的变量和方法,而不是全局变量。他使用 SDL_Rects 数组来定义 Sprite 表上不同 Sprite 的边界,所以我使用 SDL_Rect 指针将数组存储在我的自定义类中。当我编译所有东西时我没有看到动画,当我编译原始源代码时我看到了。当我开始调试时,我发现当我渲染 Sprite 时,矩形实际上充满了垃圾,即使当我初始化它们时矩形也很好。我曾多次尝试简化问题,但我在更简单的环境中重新创建错误的每一种方法实际上都按预期工作!因此,考虑到这一点,我为大量代码表示歉意,因为我似乎无法减少问题。
纹理.h
#ifndef TEXTURE_H
#define TEXTURE_H
#include <SDL2/SDL.h>
#include <string>
class Animation {
public:
Animation(SDL_Renderer* renderer);
~Animation();
void load(std::string path, int frames, SDL_Rect* clips),
free(),
render(int x, int y),
next_frame();
private:
SDL_Renderer* _renderer=NULL;
SDL_Rect* _clips=NULL;
SDL_Texture* _texture=NULL;
int _frame=0, _frames=0, _width=0, _height=0;
};
#endif
纹理.cpp
#include <stdio.h>
#include <SDL2/SDL_image.h>
#include "texture.h"
#include "error.h"
Animation::Animation(SDL_Renderer* renderer) {
_renderer = renderer;
}
Animation::~Animation() {
free();
_renderer = NULL;
}
void Animation::load(std::string path, int frames, SDL_Rect* clips) {
free();
SDL_Texture* texture = NULL;
SDL_Surface* surface = IMG_Load(path.c_str());
if (!surface)
throw ErrorIMG("Could not load image "+path);
SDL_SetColorKey(surface, SDL_TRUE,
SDL_MapRGB(surface->format, 0, 0xFF, 0xFF));
texture = SDL_CreateTextureFromSurface(_renderer, surface);
if (!texture)
throw ErrorSDL("Could not create texture from image "+path);
_width = surface->w;
_height = surface->h;
SDL_FreeSurface(surface);
_frames = frames;
_clips = clips;
printf("clips[%d]: w: %d h: %d\n", 0, _clips[0].w, _clips[0].h);
}
void Animation::free() {
if (_texture) {
SDL_DestroyTexture(_texture);
_texture = NULL;
_clips = NULL;
_frames = 0;
_frame = 0;
_width = 0;
_height = 0;
}
}
void Animation::render(int x, int y) {
SDL_Rect crect = _clips[_frame/4];
printf("in render (clips[%d]): w: %d, h: %d\n", _frame/4, crect.w, crect.h);
SDL_Rect render_space = {x, y, crect.w, crect.h};
SDL_RenderCopy(_renderer, _texture, &_clips[_frame], &render_space);
}
void Animation::next_frame() {
SDL_Rect crect = _clips[_frame/4];
printf("in next frame (clips[%d]): w: %d, h: %d\n", _frame/4, crect.w, crect.h);
++_frame;
if (_frame/4 >= _frames)
_frame = 0;
}
游戏.h
#ifndef GAME_H
#define GAME_H
#include "texture.h"
class Game {
public:
Game();
~Game();
void main();
private:
void load_media();
SDL_Window* _window=NULL;
SDL_Renderer* _renderer=NULL;
Animation* _anim=NULL;
const int SCREEN_WIDTH=640, SCREEN_HEIGHT=480;
};
#endif
游戏.cpp
#include <SDL2/SDL_image.h>
#include "game.h"
#include "error.h"
void Game::main() {
load_media();
bool has_quit = false;
SDL_Event event;
while (!has_quit) {
while (SDL_PollEvent(&event))
if (event.type == SDL_QUIT)
has_quit = true;
SDL_SetRenderDrawColor(_renderer, 0xff, 0xff, 0xff, 0xff);
SDL_RenderClear(_renderer);
_anim->render(100, 100);
_anim->next_frame();
SDL_RenderPresent(_renderer);
}
}
Game::Game() {
if (SDL_Init(SDL_INIT_VIDEO))
throw ErrorSDL("SDL could not initialize");
_window = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH,
SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if (!_window)
throw ErrorSDL("Window could not be created");
Uint32 render_flags = SDL_RENDERER_ACCELERATED;
render_flags |= SDL_RENDERER_PRESENTVSYNC;
_renderer = SDL_CreateRenderer(_window, -1, render_flags);
if (!_renderer)
throw ErrorSDL("Renderer could not be created");
SDL_SetRenderDrawColor(_renderer, 0xff, 0xff, 0xff, 0xff);
if (!(IMG_Init(IMG_INIT_PNG) & IMG_INIT_PNG))
throw ErrorIMG("SDL_image could not initialize");
}
Game::~Game() {
delete _anim;
SDL_DestroyRenderer(_renderer);
SDL_DestroyWindow(_window);
_renderer = NULL;
_window = NULL;
IMG_Quit();
SDL_Quit();
}
void Game::load_media() {
const int nclips = 4;
SDL_Rect clips[nclips];
for (int i=0; i < nclips; i++) {
clips[i].x = i*64;
clips[i].y = 0;
clips[i].w = 64;
clips[i].h = 164;
}
_anim = new Animation(_renderer);
_anim->load("sheet.png", nclips, &clips[0]);
}
最佳答案
您正在存储一个指向临时对象的指针。 SDL_Rect* clips
您传递给 Animation::load
的指针分配给成员 _clips
函数返回后使用。为了使其正常工作,指向的数据需要与Animation
一样长的时间存在。类正在使用它。问题出现在这里:
void Game::load_media() {
const int nclips = 4;
SDL_Rect clips[nclips];
...
_anim->load("sheet.png", nclips, &clips[0]);
}
在这段代码中,clips
是一个本地变量。这意味着它在 load_media()
结束时被销毁,该位置的内存内容将变成垃圾。
您可以通过多种方式解决此问题。一个简单的方法是使用 std::vector<SDL_Rect>
而不是 SDL_Rect*
. std::vector
可以安全地复制并为您管理其内部结构。您的新代码可能如下所示:
class Animation {
...
std::vector<SDL_Rect> _clips;
...
}
void Animation::load(std::string path, int frames, std::vector<SDL_Rect> clips) {
...
_clips = clips;
...
}
void Game::load_media() {
const int nclips = 4;
std::vector<SDL_Rect> clips;
clips.resize(nclips);
...
_anim->load("sheet.png", nclips, clips);
}
别忘了 #include <vector>
. std::vector
的文档是here .注意 std::vector
有一个 size()
可能取代 frames
的方法它无处不在。
关于c++ - 从数组访问 SDL_Rect 成员时出现垃圾值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52103944/
我正在使用 C 和 SDL 创建康威生命游戏的模拟。为了表示事件的细胞,我想在我创建的窗口中创建多个矩形。有没有办法在 for 循环中调用 SDL_Rect 而无需重新定义 SDL_Rect 并在同一
我一直在试用 SDL 2,但遇到了 SDL_Rect does not name a type 错误...代码: #include #include using namespace std; SD
我有一个用于在我的 2D 引擎中定义特征图形的结构。在那里,有一系列 SDL_Rects 称为“middle, left_edge, top_left_corner”等。在我的部分代码中,我将它们从一
我一直在关注 LazyFoo 的 SDL tutorials (并且还添加了我自己的组织和编码风格)。当我到达他的animation tutorial我决定做一个单独的类来存储与动画算法相关的变量和方
我正在尝试通过类为 SDL 中的文本创建一个简单的er 容器。该类应该包含指向 SDL_Texture 和 SDL_Rect 的指针以及一些从类的实例中获取信息的方法。当我尝试使用以下函数将纹理 bl
我试图创建一个类,其中包含我的游戏 SHIP 的信息(目前的图像和位置),一切都按我预期的那样编译,但是如果我使用我在我的船中创建的 SDL_Rect 变量作为 SDL_blitsurface 中的参
我有一个带有几个继承者的抽象基类,我创建了一个指向继承者的抽象基类指针数组: 抽象基类: class Tile { public: bool isPa
我正在尝试将 SDL_Rect 传递给 SDL_RenderCopy,它采用 SDL_Rect 的地址。我有 SDL_Rect 我正在尝试传递存储在 Shot.h 文件中的我的私有(private)类
当我将以下内容声明为我的主类“App”的私有(private)数据成员时,我的程序在启动时崩溃,就好像它正在访问无效数据/内存一样(编辑:如果它是公共(public)数据成员,它不会崩溃): //Di
我需要在sdl窗口上定义矩形区域,以便当在特定区域上单击鼠标按钮时必须执行某些操作。 我使用GetMouseState(x,y)来获取鼠标单击事件。只要单击鼠标按钮,它就会起作用。但我需要获取鼠标 x
我在 SDL2 纪录片中找不到任何关于渲染透明矩形的内容。我想将 SDL_Rect 渲染为透明纹理/表面/任何用作“ war 迷雾”的东西。也许您知道从 SDL_Rect 制作表面或纹理或仅将其渲染为
我正在使用 C++ 和 SDL 制作游戏,该游戏是太空入侵者类型的游戏。一切都很顺利,直到我在 while 循环中添加了背景图像,这是背景的渲染和初始化代码: SZ_Background.cpp: v
我正处于游戏的开始阶段,我卡在了 Blit_Surface 这一步。我的 CodeBlocks 编译器在编译时说 -> 的无效类型参数(有 BrickStruct)”。它似乎想要一个指向我的二维数组的
int SDL_BlitSurface(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect); 为什么 s
我正在研究一些 SDL 的东西,但在尝试设置加载的 BMP 的位置时遇到了一些麻烦。 这是代码。 while(event.type != SDL_QUIT) //The game loop that
我正在使用适用于 C++ 的 SDL 库。 当我更改 x 和 y 值时,我可以让我的矩形四处移动,但不是以我期望的方式移动。 例如,它以较大的 y 坐标向下移动。 这是为什么? //Render re
#include "main.h" SDL_Surface* screen; //The screen Surface SDL_Surface* Snake_Body; //The snake sur
l SDL_BlitSurface(tileSheets.at(sheet), &clip[tile], screen, &tileBox); 工作得很好,我像这样初始化剪辑: clip[ 0 ].x
我是一名优秀的程序员,十分优秀!