gpt4 book ai didi

c++ - 如何在不破坏其纹理的情况下将 Sprite 正确传递给 std::Vector?

转载 作者:行者123 更新时间:2023-11-30 05:43:43 25 4
gpt4 key购买 nike

来自官方 SFML 教程,白盒问题:-

“当你设置一个 Sprite 的纹理时,它在内部所做的只是存储一个指向纹理实例的指针。因此,如果纹理被破坏或移动到内存中的其他地方, Sprite 最终会得到一个无效的纹理指针。”因此,将看到没有纹理的 Sprite 。

我有一个名为 World 的类。在这门课中,我创建了一个名为 level 的二维整数数组和一个名为 blocks 的 Block 类型的 vector 。现在我想在级别 [ i ][ j ] = 1 时将“ block ”对象存储在 vector 中。

'World' 类的头文件:-

#ifndef WORLD_H
#define WORLD_H
#include <vector>
#include "Block.h"
#include "Grass.h"
#include <SFML/Graphics.hpp>

using namespace std;

class World
{
public:
World();
void draw(sf::RenderWindow *window);
vector<Block> blocks;

private:
int level[12][16];
int wd;
int hi;
};

#endif // WORLD_H

“世界”类的 cpp 文件:-

#include "World.h"
#include "Grass.h"
#include "Block.h"
#include <iostream>
#include <SFML/Graphics.hpp>

using namespace std;

World::World() : level{
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1},
{1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1},
{1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1},
{1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
}
{
wd = 16;
hi = 12;
int count = 1;
//make a 'Block' object and pass it in the vector when level[ i ][ j ] = 1.
for(int i = 0; i<hi; i++)
{
for(int j = 0; j<wd; j++)
{
if(level[i][j] == 1)
{
Block block(j*50, i*50);
blocks.push_back(block);
}
}
}
}
void World::draw(sf::RenderWindow *window)
{
for(unsigned int i = 0; i<blocks.size(); i++)
{
blocks[i].draw(window);
}
}

'Block' 类有两个成员 - sf::Texture blockTsf::Sprite block。它还有一个 draw(RenderWindow *window) 方法。这就是“ block ”类的制作方式:-

block 类的头文件

#ifndef BLOCK_H
#define BLOCK_H
#include <iostream>
#include <SFML/Graphics.hpp>

using namespace std;

class Block
{
public:
Block(float x, float y);
void draw(sf::RenderWindow *window);

private:
sf::Texture blockT;
sf::Sprite block;
};

#endif // BLOCK_H

“ block ”类的 cpp 文件

#include "Block.h"
#include <iostream>
#include <SFML/Graphics.hpp>

using namespace std;

Block::Block(float px, float py)
{
if(!(blockT.loadFromFile("textures/block.png")))
{
cout<<"Could not load block texture."<<endl;
}
block.setTexture(blockT);
block.setPosition(sf::Vector2f(px, py));
cout<<px<<endl;
cout<<py<<endl;
}

void Block::draw(sf::RenderWindow *window)
{
window->draw(block);
}

当我运行程序时,只显示白色框而不是 block 。我不明白纹理是如何被破坏的。这就是输出的样子:-

messed up textures

如您所见,白色的地方是每个大小为 50*50 的 Sprite ,没有任何纹理。

最佳答案

您应该自定义 block 的复制构造,以便更新纹理指针,例如:

Block::Block(const Block& other)
: blockT(other.blockT), block(other.block)
{
block.setTexture(blockT);
}

vector 中的 push_back() 强制调整大小时将使用它,并且新分配的较大缓冲区的元素是从之前的旧元素复制构造的后者被“破坏”并释放。

最好支持相同类型的赋值更新,即 operator=(const Block& rhs)

关于您的“因此会看到没有纹理的 Sprite 。” - 行为很可能是未定义,因为您有效地遵循指向已释放内存的指针,该内存随时可能被新内容损坏,并且恰好表现为当前测试中缺少纹理,但在一些小的代码更改后可能会在其他优化级别崩溃和烧毁,在另一个编译器或操作系统等上。

关于c++ - 如何在不破坏其纹理的情况下将 Sprite 正确传递给 std::Vector?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30114714/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com