【问题标题】:SFML 2.0 Looping a sprite to display more than onceSFML 2.0 循环显示不止一次的精灵
【发布时间】:2013-02-25 23:10:01
【问题描述】:

我过去曾问过类似的问题,但我仍然无法理解这个问题。我正在做一个基于 SFML 2.0 的入侵者游戏。到目前为止,我有一张使用我的时钟运行的精灵表。这部分工作得很好:

#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include <iostream>
#include <string>

int spriteWalkSpeed = 10;
int DownspriteWalkSpeed = 5;
int up=-spriteWalkSpeed, down=DownspriteWalkSpeed, left=-spriteWalkSpeed, right=spriteWalkSpeed;

int xVelocity =0, yVelocity=0;

const int SC_WIDTH=800;
const int  SC_HEIGHT= 600;
const float  REFRESH_RATE =0.01f; //how often we draw the frame in seconds

const double delay=0.1;
const int SPRITEROWS=1; //number of ROWS OF SPRITES
const int SPRITECOLS=2;//number of COLS OF SPRITES

std::string gameOver = "Game Over";

int main()
{
    // Create the main window
    sf::RenderWindow App (sf::VideoMode(SC_WIDTH, SC_HEIGHT, 32), "Space Invaders!",sf::Style::Close );

    // Create a clock for measuring time elapsed
    sf::Clock Clock;

    //background texture
    sf::Texture backGround;
    backGround.loadFromFile("images/background.jpg");

    sf::Sprite back;
    back.setTexture(backGround);

    //load the invaders images
    sf::Texture invaderTexture;
    invaderTexture.loadFromFile("images/invaders.png");
    sf::Sprite invadersSprite(invaderTexture);
    std::vector<sf::Sprite> invaderSprites(10, sf::Sprite(invaderTexture));

    int invadersWidth=invaderTexture.getSize().x;
    int invadersHeight=invaderTexture.getSize().y;

    int spaceWidth=invadersWidth/SPRITECOLS;
    int spaceheight=invadersHeight/SPRITEROWS;
    //Sprites

    sf::IntRect area(0,0,spaceWidth,spaceheight);


    invadersSprite.setTextureRect(area);
    invadersSprite.setPosition(30, NULL);


    App.setKeyRepeatEnabled(false);
    //Collision detection

    // Start game loop  
    while (App.isOpen())
    {
        // Process events
        sf::Event Event;
        while (App.pollEvent(Event))
        {
            // Close window : exit
            if (Event.type == sf::Event::Closed)
                App.close();
        }
        // Create an array of 10 sprites (cannot initialise them with textures here)
        for (int i = 0; i < 10; i++) 
        {
            invaderSprites[i].setPosition(30,0);

        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)
            {
                invaderSprites[i].setTextureRect(area);
                ++count;
                invaderSprites[i].move(xVelocity, yVelocity);   
                if(count==SPRITECOLS) //WE HAVE MOVED OFF THE RIGHT OF THE IMAGE
                {
                    area.left=0;            //reset texture rect at left

                    count=0;                //reset count
                }
                else
                {
                    area.left+=spaceWidth; //move texture rect right
                }


                spriteTimer=0; //we have made one move in the sprite tile - start timing for the next move
            }
            Clock.restart();
        }
        App.draw(back);
            App.draw(invaderSprites[i]);

        // Finally, display the rendered frame on screen
        App.display();
        }
    }

    return EXIT_SUCCESS;
}

我遇到的问题是精灵只显示一次,而不是 10 次(作为 for 循环状态)

std::vector<sf::Sprite> invaderSprites(10, sf::Sprite(invaderTexture));

    // Loop over the elements of the vector of sprites
    for (int i = 0; i < invaderSprites.size(); i++) 
    {
        invaderSprites[i].setPosition(30, NULL);
    }
    // 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);
    }

我很确定这与应用程序绘图 invadersSprite 有关,而循环是为 invaderSprites 设置的。即使只是对出了什么问题有一点了解也会有很大的帮助。

【问题讨论】:

  • 请尽量将您的代码简化为一个能说明问题的最小示例。作为一个小而明显的例子,声音和音乐与这个问题无关,任何对它的引用都可以省略(还有坦克和激光纹理和精灵等)。通过这样做,其他人可以更轻松地隔离代码中的问题。确保您的简化示例仍然可以编译,除非无法编译是您的问题,这里不是这种情况。
  • 我现在将编辑代码,谢谢:已编辑,对此感到抱歉

标签: c++ sfml sprite-sheet


【解决方案1】:

我很确定这与应用程序绘图有关 入侵者精灵,而循环是为入侵者精灵设置的。

是的,这肯定与它有关。您需要为每个要绘制的精灵调用App.draw(...)。您没有为矢量中的任何精灵调用它。为此,您需要一个循环:

for (int i=0; i<invaderSprites.size(); ++i)
    App.draw(invaderSprites[i]);

还有其他问题。例如,为什么要声明一个名为invaderSprites 的精灵数组,而您已经有一个同名的精灵向量?后者一旦被声明就隐藏前者。

另一件事是您将所有精灵设置到相同的位置,因此即使您设法将它们全部绘制出来,它们也会在同一个位置,因此它们不会显示为单独的对象。

【讨论】:

  • 试图让它工作时留下了一些代码。我试过 App.draw(invaderSprites[i]);过去但没有太多帮助。现在我知道问题出在哪里,我会看看我是否可以让它工作。谢谢 编辑:我还认为精灵可能隐藏在彼此后面。我不太确定如何解决这个问题?
  • @JohnathanBrown:你可以通过给他们不同的位置来解决这个问题。现在,您正在使用invaderSprites[i].setPosition(30, NULL); 设置它们的每个位置——所以它们都在位置 x=30, y=0。 (顺便说一句,当你的意思是 0 时不要使用 NULL)
  • 现在我正在尝试这个: App.draw(invaderSprites[i]); } 我认为这行得通
  • @JohnathanBrown:可以截图吗?
  • 它甚至没有绘制循环的精灵
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-31
  • 1970-01-01
  • 2014-02-16
  • 1970-01-01
  • 2017-01-06
  • 2018-03-05
  • 1970-01-01
相关资源
最近更新 更多