我无法实现此功能。
// 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);
}
我希望它替换“在void 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);
答案 0 :(得分:2)
您呼叫的setTexture()
方法的文档(http://www.sfml-dev.org/documentation/2.0/classsf_1_1Sprite.php#a3729c88d88ac38c19317c18e87242560)说:
纹理参数指的是只要精灵使用它就必须存在的纹理。实际上,精灵并不存储自己的纹理副本,而是保留指向您传递给该函数的指针。如果源纹理被破坏并且精灵试图使用它,则行为是未定义的。
解决这个问题的一种方法是创建自己的包含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;
}
现在纹理将始终与精灵一样长。
但是请注意,当你构建你的敌人&#34;你为所有这些使用单一纹理。为了在多个精灵之间共享一个纹理,我们可以增强上述功能:
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
}
现在,矢量中的所有敌人都共享一个纹理。也许这对效率很重要。