如何在循环中为图像命名?

时间:2015-05-28 13:09:19

标签: c++ loops sfml

我刚刚开始使用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());
}

2 个答案:

答案 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);
    }
}

旁注:您可能希望为子弹添加类似重装或冷却时间的东西,这样就不会每秒射出数量的子弹。