我在实现此功能时遇到麻烦。
//Engine.cpp
void Game::createPlayer(sf::Sprite &player)
{ ///Can't get this to work
sf::Texture player_texture;
if (!player_texture.loadFromFile("player.png"))
{
//Error Loading
}
player.setTexture(player_texture);
}
我希望它代替“在无效Game :: run中创建玩家”,但我意识到Player_texture对于Createplayer是本地的,并且当函数返回时它将不存在。
void Game::run()
{
sf::RenderWindow window(sf::VideoMode(SCREEN_X, SCREEN_Y), "Shogun Master");
srand((unsigned int)time(NULL));
//Creates Player [Makes into function]
sf::Texture player_texture;
player_texture.loadFromFile("sprites/player.png");
sf::Sprite player(player_texture);
//Creates Enemy [Make into function]
sf::Texture enemy_texture;
enemy_texture.loadFromFile("sprites/enemy.png");
sf::Sprite enemy[MAX_ENEMIES];
for (int x = 0; x < MAX_ENEMIES; x++)
{
enemy[x].setTexture(enemy_texture);
enemy[x].setPosition(rand_int(100, SCREEN_X - 100), rand_int(100, SCREEN_Y - 100)); //Spawning Point
}
//Sets Positions
player.setPosition(500, 300);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
check_closeWindows(event, window); //Closes Game if Executed
player_movement(event); //Moves Character
attack(event); //Character's attacks
}
border(player); //Border so player does not go off screen
for (int x = 0; x < total_enemies; x++)
border(enemy[x]);
movementUpdate(player, enemy); //Player & Enemy Movement Updates
collision(player, enemy[0]);
window.clear();
window.draw(player); //Draws Player
for (int x = 0; x < total_enemies; x++)
window.draw(enemy[x]); //Draws Enemy
window.display();
}
}
所以我将如何实现它,以使我的精灵不会返回白盒,因为它超出了范围。
//Engine.h
void Game::createPlayer(sf::Sprite &player);
最佳答案
您正在调用的setTexture()
方法的文档(http://www.sfml-dev.org/documentation/2.0/classsf_1_1Sprite.php#a3729c88d88ac38c19317c18e87242560)说:
Texture参数是指只要精灵使用它就必须存在的纹理。实际上,精灵不会存储纹理的副本,而是保留指向您传递给该函数的指针的指针。如果源纹理被破坏并且精灵试图使用它,则行为是不确定的。
解决此问题的一种方法是制作自己的同时包含Sprite
及其纹理的结构或类:
struct SpriteWithTexture
{
sf::Texture texture;
sf::Sprite sprite;
SpriteWithTexture()
{
sprite.setTexture(texture);
}
SpriteWithTexture(const SpriteWithTexture& that)
: texture(that.texture)
{
sprite.setTexture(texture);
}
SpriteWithTexture& operator=(const SpriteWithTexture& that)
{
texture = that.texture;
sprite.setTexture(texture);
return *this;
}
};
然后,您可以从函数中返回此代码:
SpriteWithTexture Game::createPlayer()
{
SpriteWithTexture player;
if (!player.texture.loadFromFile("player.png"))
{
//Error Loading
}
return player;
}
现在,纹理将始终与精灵保持一致。
但是请注意,在构造“敌人”时,对所有敌人使用单个纹理。为了能够在多个精灵之间共享一个纹理,我们可以增强上述内容:
struct SpriteWithTexture
{
std::shared_ptr<sf::Texture> texture;
sf::Sprite sprite;
SpriteWithTexture(const std::shared_ptr<sf::Texture>& texture_)
: texture(texture_)
{
sprite.setTexture(*texture);
}
};
现在您可以通过以下方式使用它:
std::shared_ptr<sf::Texture> player_texture(new sf::Texture);
player_texture->loadFromFile("sprites/player.png");
SpriteWithTexture player(player_texture);
std::shared_ptr<sf::Texture> enemy_texture(new sf::Texture);
enemy_texture->loadFromFile("sprites/enemy.png");
std::vector<SpriteWithTexture> enemies;
for (int x = 0; x < MAX_ENEMIES; x++)
{
enemies.emplace_back(enemy_texture); // construct enemy Sprite
enemies.back().sprite.setPosition(rand_int(100, SCREEN_X - 100), rand_int(100, SCREEN_Y - 100)); //Spawning Point
}
现在向量中的所有敌人都共享一个纹理。也许这对效率很重要。
关于c++ - Sprite 不在范围内,因为它是本地的,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36853738/