2013-03-10 50 views
1

我在過去曾問過類似的問題,但仍無法解決這個問題。我正在做一個基於SFML 2.0的入侵者遊戲。到目前爲止,我有一個sprite表單,它貫穿我的時鐘。這部分工作得很好: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

請嘗試將您的代碼減少到演示該問題的最小示例。作爲一個小而明顯的例子,聲音和音樂與這個問題無關,任何對它的引用都可以被忽略(還有坦克,激光紋理和精靈等等)。通過這樣做,它可以讓其他人更容易地隔離代碼中的問題。確保你縮小的例子仍然編譯,除非編譯時無法編譯是你的問題,在這裏不是這樣。 – 2013-03-10 21:16:35

+0

我將立即編輯代碼,謝謝: 已編輯,對此感到抱歉 – 2013-03-10 21:17:36

回答

3

我很確定它與應用程序繪圖 invadersSprite有關,而循環是爲invaderSprites設置的。

是的,這當然與它有關。您需要爲要繪製的每個精靈調用App.draw(...)。你不會爲你的矢量中的任何精靈調用它。爲此,您需要一個循環:

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

雖然還有其他問題。例如,當你已經有一個同名的精靈矢量時,爲什麼要聲明一個名爲invaderSprites的精靈數組?後者一旦宣佈就隱藏前者。

另一件事是你將所有的精靈都設置在相同的位置,所以即使你設法把所有的精靈都繪製在同一個位置上,它們也不會作爲單獨的對象出現。

+0

有一些遺漏的代碼嘗試使其運行。我已經嘗試過App.draw(invaderSprites [i]);在過去,但沒有太多的幫助。現在我知道問題是什麼,我會看看我能否實現它。謝謝 編輯: 我還認爲,精靈可能隱藏在彼此後面。我不太確定我會如何解決這個問題? – 2013-03-10 20:59:32

+0

@JohnathanBrown:你通過給他們每個不同的位置來解決它。現在,你正在用'invaderSprites [i] .setPosition(30,NULL);' - 設置它們的每個位置,因此它們都位於x = 30,y = 0的位置。 (順便說一句,當你的意思是0時不要使用NULL) – 2013-03-10 21:23:28

+0

現在我正在嘗試這個:\t \t for (int i = 0; i < 10; i++) \t \t { \t \t \t invaderSprites[i].setPosition(i+5, 0); \t \t \t App.draw(invaderSprites[i]); \t \t }我以爲這會起作用 – 2013-03-10 21:29:09