1

私は過去に同様の質問をしましたが、それでも頭を悩ませることはできません。SFML2.0をベースにしたインベーダーゲームをやっています。これまでのところ、時計を使用して実行されるスプライトシートが1つあります。この部分は問題なく機能します。

#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回ではなく、1回しか表示されないことです(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。何がうまくいかないかについてのほんの少しの洞察でさえ、とても大きな助けになるでしょう。

4

1 に答える 1

3

ループがinvaderSprites用に設定されているのに対し、アプリがinvadersSpriteを描画することと関係があると確信しています。

はい、それは確かにそれと関係があります。App.draw(...)描きたいスプライトごとに呼び出す必要があります。ベクター内のスプライトのいずれに対してもそれを呼び出していません。そのためには、ループが必要になります。

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

しかし、他にも問題があります。たとえば、invaderSprites同じ名前のスプライトのベクトルがすでにあるのに、なぜと呼ばれるスプライトの配列を宣言するのですか?後者は、宣言されると前者を非表示にします。

もう1つは、すべてのスプライトを同じ位置に設定しているため、すべてを描画できたとしても、すべて同じ場所に配置されるため、個別のオブジェクトとして表示されないということです。

于 2013-03-10T20:54:15.100 に答える