SFML 2.0 Цикл спрайта для отображения более одного раза

Я задавал подобный вопрос в прошлом, но я все еще не могу обдумать это. Я делаю игру захватчиков на основе 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 ответ

Решение

Я почти уверен, что это как-то связано с рисованием приложения invadersSprite, тогда как цикл настроен для invaderSprites.

Да, это, безусловно, как-то связано с этим. Вам нужно позвонить App.draw(...) для каждого спрайта, который вы хотите нарисовать. Вы не называете это ни для одного из спрайтов в вашем векторе. Для этого вы хотели бы цикл:

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

Есть и другие проблемы. Например, почему вы объявляете массив спрайтов invaderSpritesкогда у вас уже есть вектор спрайтов с тем же именем? Последний скрывает первый, как только он объявлен.

Другое дело, что вы устанавливаете все спрайты в одну и ту же позицию, поэтому даже если вам удастся нарисовать их все, они все будут в одном месте, и как таковые они не будут отображаться как отдельные объекты.

Другие вопросы по тегам