SFML 2.0循环一个sprite不止一次显示

时间:2013-03-10 20:41:18

标签: c++ sfml sprite-sheet

我过去曾问过类似的问题,但我仍然无法理解这个问题。我正在做一个基于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设置的。即使只是对出现问题的一点了解也会有很大的帮助。

1 个答案:

答案 0 :(得分:3)

  

我很确定它与应用程序绘图有关   invadersSprite,而循环是为invaderSprites设置的。

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

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

但是还有其他问题。例如,当你已经有一个具有相同名称的sprite向量时,为什么要声明一个名为invaderSprites的sprite数组?一旦声明,后者就会隐藏前者。

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