我刚刚开始使用SFML进行编程,我试图让一些东西射入子弹。当我按空间时,我已经让子弹移动了一个方向。但我不能同时拍摄多发子弹,只是使用相同的图像。如果我应该给每个子弹它自己的名字,我无法弄明白我应该做些什么?
当它从窗口出来时我也应该删除吗?如果我应该怎么做呢?
以下是相关代码:
void Game::handleWeaponInput(sf::Keyboard::Key key, bool isPressed)
{
if (key == sf::Keyboard::Space)
{
mIsFired = isPressed;
if (!mBulletTexture.loadFromFile("Media/Textures/Bullet.png"))
{
}
mBullet.setTexture(mBulletTexture);
mBullet.setPosition(100.f, 100.f);
mBullet.setRotation(90.f);
}
}
和
void Game::update(sf::Time elapsedTime)
{
sf::Vector2f bulletMovement(0.f, 0.f);
if (mIsFired)
bulletMovement.x += 300.f;
mBullet.move(bulletMovement * elapsedTime.asSeconds());
}
答案 0 :(得分:0)
您可以做的一件事就是创建一个std::vector个项目符号,这样您就可以单独跟踪每个项目符号。
class Game
{
sf::Texture mBulletTexture;
// declare a std::vector of bullets
std::vector<sf::Sprite> mBullets;
public:
void handleWeaponInput(sf::Keyboard::Key key, bool isPressed);
void update(sf::Time elapsedTime);
};
void Game::handleWeaponInput(sf::Keyboard::Key key, bool isPressed)
{
if (key == sf::Keyboard::Space)
{
mIsFired = isPressed;
if (!mBulletTexture.loadFromFile("Media/Textures/Bullet.png"))
{
}
mBullets.emplace_back(); // add another sf::Sprite to vector
mBullets.back().setTexture(mBulletTexture);
mBullets.back().setPosition(100.f, 100.f);
mBullets.back().setRotation(90.f);
}
}
void Game::update(sf::Time elapsedTime)
{
sf::Vector2f bulletMovement(0.f, 0.f);
if (mIsFired)
bulletMovement.x += 300.f;
// move each bullet in the vector
for(auto& bullet: mBullets)
bullet.move(bulletMovement * elapsedTime.asSeconds());
}
显然,这个确切的代码无法正常工作,因为你还需要管理每个子弹的移动方向(等等......)。但希望它会让你知道如何从一颗子弹扩展到多颗子弹。
可能值得定义包含class Bullet
的{{1}}以及有关子弹速度和方向的信息吗?
然后你可以用你的那些来制作你的矢量:
sf::Sprite
答案 1 :(得分:0)
首先,我想解决你的更新方法:你应该每帧更新每个现有的子弹,而不管你是否解雇了一个:
void Game::update(sf::Time elapsedTime) {
sf::Vector2f bulletMovement(300.f, 0.f);
for (auto& bullet : mBullets) // range-based-for and auto require C++11
bullet.move(bulletMovement * elapsedTime.asSeconds());
}
正如其他人已经建议的那样,对于一个简单的用例,子弹矢量可以很好地工作。如果您需要更复杂的数据结构来处理游戏实体,请尝试研究“场景图”或“四叉树”等内容。
std::vector<sf::Sprite> mBullets;
添加项目符号,只需使用
即可// possibly construct sprite seperatly and add some transforms beforehand
mBullets.push_back(sf::Sprite(/* however you store your texture */));
是的,一旦它们在你的屏幕之外就摧毁子弹是一个好主意,因为你会浪费绘制调用和其他你永远不会再看到的实体的操作。使用SFML已经提供的工具,可以这样做:
void Game::destroyBulletsOutsideView() {
sf::FloatRect viewBounds(0, 0, mWindow.getSize().x, mWindow.getSize().y);
for (auto iter = mBullets.begin(); iter != mBullets.end(); ++iter) {
if (!viewBounds.intersects(iter->getGlobalBounds())
mBullets.erase(iter);
}
}
旁注:您可能希望为子弹添加类似重装或冷却时间的东西,这样就不会每秒射出数量的子弹。