【问题标题】:SFML 2.0 Having the same sprite loopedSFML 2.0 具有相同的精灵循环
【发布时间】:2013-03-06 22:52:51
【问题描述】:

我正在使用 SFML 2.0 将入侵者精灵列表绘制到我的游戏中。目前我必须继续复制和粘贴我的代码来绘制更多的精灵:

//load the invaders images
sf::Texture invaders;
sf::Texture invaders2;
sf::Texture invaders3;
sf::Texture invaders4;
sf::Texture invaders5;
sf::Texture invaders6;
invaders.loadFromFile("images/invaders.png");
invaders2.loadFromFile("images/invaders.png");
invaders3.loadFromFile("images/invaders.png");
invaders4.loadFromFile("images/invaders.png");
invaders5.loadFromFile("images/invaders.png");
invaders6.loadFromFile("images/invaders.png");

//Sprites
sf::Sprite invadersSprite(invaders);
sf::Sprite invadersSprite2(invaders2);
sf::Sprite invadersSprite3(invaders3);
sf::Sprite invadersSprite4(invaders4);
sf::Sprite invadersSprite5(invaders5);
sf::Sprite invadersSprite6(invaders6);

invadersSprite2.setPosition(30,NULL);
invadersSprite3.setPosition(60,NULL);
invadersSprite4.setPosition(90,NULL);
invadersSprite5.setPosition(120,NULL);
invadersSprite6.setPosition(150,NULL);

if(Clock.getElapsedTime().asSeconds()>REFRESH_RATE)
        {

            //carry out updating tasks
            static float spriteTimer=0.0;  //keep track of sprite time
            spriteTimer+=Clock.getElapsedTime().asSeconds();

            static int count=0; //keep track of where the sub rect is
            if(spriteTimer>delay)
            {
                invadersSprite.setTextureRect(area);
                invadersSprite2.setTextureRect(area);
                invadersSprite3.setTextureRect(area);
                invadersSprite4.setTextureRect(area);
                invadersSprite5.setTextureRect(area);
                invadersSprite6.setTextureRect(area);
                ++count;
                invadersSprite.move(xVelocity, yVelocity);  
                invadersSprite2.move(xVelocity, yVelocity); 
                invadersSprite3.move(xVelocity, yVelocity); 
                invadersSprite4.move(xVelocity, yVelocity); 
                invadersSprite5.move(xVelocity, yVelocity); 
                invadersSprite6.move(xVelocity, yVelocity); 


if (invadersSprite.getPosition().x >= 770 || invadersSprite2.getPosition().x >= 770 || invadersSprite3.getPosition().x >= 770 || invadersSprite4.getPosition().x >= 770 || invadersSprite5.getPosition().x >= 770 || invadersSprite6.getPosition().x >= 770)// When it hits the right hand side of the screen it will move back down to the left
            {
                xVelocity = left;
                invadersSprite.move(0,down);
                invadersSprite2.move(0,down);
                invadersSprite3.move(0,down);
                invadersSprite4.move(0,down);
                invadersSprite5.move(0,down);
                invadersSprite6.move(0,down);
            } 
            else if (invadersSprite.getPosition().x <= 0 || invadersSprite2.getPosition().x <= 0 || invadersSprite3.getPosition().x <= 0 || invadersSprite4.getPosition().x <= 0 || invadersSprite5.getPosition().x <= 0 || invadersSprite6.getPosition().x <= 0) // When it hits the left hand side of the screen it will move up to the right.
            {
                invadersSprite.move(0,down);
                invadersSprite2.move(0,down);
                invadersSprite3.move(0,down);
                invadersSprite4.move(0,down);
                invadersSprite5.move(0,down);
                invadersSprite6.move(0,down);
                xVelocity = right;
            }

很明显,我没有在这篇文章中添加所有代码,坦率地说,我认为没有必要这样做,因为我只需要向你们展示我复制大量代码只是为了绘制更多精灵。我知道必须有一种更简单的方法来做到这一点。我知道有,假设您正在创建另一个碰巧使用精灵的游戏,但是 1000 次然后我知道一些可怜的程序员不会在那里做我现在正在做的事情。

我一直想知道如何制作一个包含 10 个数字的数组:

int invadersArray[10] = {1,2,3,4,5,6,7,8,9,10};

然后执行一个 for 循环,循环渲染精灵 10 次,这意味着精灵被加载了 10 次。我在这里正确吗?如果可以的话,我可能会得到一些帮助,比如如何做到这一点?

或者也许将精灵保存在内存中,找到它然后用我的数组循环那个内存位置?谢谢

【问题讨论】:

    标签: c++ sfml


    【解决方案1】:

    是的,您过于复杂了,并且没有在应该使用的地方使用数组或容器。每当您最终复制一个变量时,变量名称末尾的数字会增加,就该使用容器了。

    由于您所有的sf::Textures 完全相同,您只需执行一次:

    // Create a texture
    sf::Texture invaderTexture;
    // Load image file into that texture
    invaderTexture.loadFromFile("images/invaders.png");
    

    然后,如果您想创建 10 个入侵者精灵,您将拥有一个 sf::Sprite 的容器。在这里,我向您展示了 std::vector,但其他容器(或普通的旧数组)也可以使用:

    // Create a vector of 10 sprites initialised with the texture above
    std::vector<sf::Sprite> invaderSprites(10, sf::Sprite(invaderTexture));
    

    如您所见,它们都使用相同的invaderTexture 进行初始化。这要好得多,因为您不需要为每个入侵者在内存中放置纹理的副本。

    然后你可以循环invaderSprites来设置它们的属性:

    // Loop over the elements of the vector of sprites
    for (int i = 0; i < invaderSprites.size(); i++) {
      invaderSprites[i].setPosition(...);
    }
    

    这应该可以帮助您入门。


    对数组做同样的初始化看起来像这样:

    // Create an array of 10 sprites (cannot initialise them with textures here)
    sf::Sprite invaderSprites[10];
    // Loop over each sprite, setting their textures
    for (int i = 0; i < 10; i++) {
      invaderSprites[i].setTexture(invaderTexture);
    }
    

    然后,您可以在需要对所有入侵者做某事时执行相同类型的循环。

    【讨论】:

    • 啊,不错。然后我可以有类似的东西?
      for (int i = 0; i 
    • @JohnathanBrown 我可能将您与某些 C++11 混淆了。我将对其进行编辑以使其更易于理解。您可以像访问数组一样访问invaderSpritesinvaderSprites[0] 是第一个,invaderSprites[1] 是第二个。我假设您了解数组,但如果您不了解,请务必开始阅读。
    • 我确实知道数组,我只是怕我不是很擅长编程,即使我真的很喜欢它:(
    • @JohnathanBrown 好吧,我给了你一个很大的提示——如果你开始给变量编号,你可能需要数组! std::vector 就像一个数组,但更安全,并且可以扩大和缩小大小。有经验的 C++ 程序员倾向于使用容器(如 std::vector)而不是普通的旧数组。
    • @JohnathanBrown invaderTexture 是我在第一个代码示例中定义的sf::Texture
    【解决方案2】:

    由于sf::Sprite 保留了一个指向您正在使用的纹理的常量指针,因此您可以毫无问题地重复使用相同的纹理。当一个纹理可以做的时候,你会无缘无故地制作很多纹理。不幸的是,这不适用于移动精灵,因为它们是单独的对象。

    【讨论】:

    • 如何修改我的代码来做到这一点?我不完全明白。
    • @JohnathanBrown 而不是拥有 6 种以上不同的纹理来加载相同的精确图像,只需保留一个。将纹理视为精灵表。
    猜你喜欢
    • 2013-02-25
    • 2013-05-31
    • 2014-02-16
    • 1970-01-01
    • 2019-03-04
    • 2017-05-19
    • 2012-05-09
    • 2019-03-10
    • 1970-01-01
    相关资源
    最近更新 更多