c++ - SFML 2.0 循环 Sprite 显示不止一次

标签 c++ sfml sprite-sheet

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

#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;
}

我遇到的问题是 Sprite 只显示一次,而不是 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 设置的。即使只是对出了什么问题有一点了解也会有很大的帮助。

最佳答案

I am pretty sure it has something to do with the app drawing invadersSprite whereas the loop is setup for invaderSprites.

是的,这肯定与它有关。您需要为每个要绘制的 Sprite 调用 App.draw(...)。您不会为 vector 中的任何 Sprite 调用它。为此,您需要一个循环:

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

还有其他问题。例如,为什么要声明一个名为 invaderSprites 的 Sprite 数组,而您已经有了一个具有相同名称的 Sprite vector ?后者一旦被声明就会隐藏前者。

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

关于c++ - SFML 2.0 循环 Sprite 显示不止一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15327332/

相关文章:

c++ - OpenCV如何提取图像 channel

c++ - SFML 中屏幕滚动时的鼠标位置

c++ - 在 C++ 中创建 pacman 碰撞检测的困难

ios - iOS 中的纹理和动画

javascript - 在 pixi v3 中加载 Sprite 表

c++ - cmake的困境

c# - 传递数组指针以放置在 C++ 中的 HashMap 中

c++ - SFML 在第一次使用 Code::Blocks 调用时崩溃

javascript - 如何使用 javascript 从 Sprite 表缩放/拉伸(stretch)/倾斜 Sprite ?

c++ - 如何在 Eclipse CDT 中编译 64 位 DLL(使用 Windows SDK)?