Я задавал подобный вопрос в прошлом, но я все еще не могу обдумать это. Я делаю игру захватчиков на основе 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
, Даже небольшое понимание того, что происходит не так, будет такой большой помощью.
Я уверен, что это как-то связано с рисованием приложения
invadersSprite, тогда как цикл настроен для invaderSprites.
Да, это, безусловно, как-то связано с этим. Вам нужно позвонить App.draw(...)
для каждого спрайта, который вы хотите нарисовать. Вы не называете это ни для одного из спрайтов в вашем векторе. Для этого вы хотели бы цикл:
for (int i=0; i<invaderSprites.size(); ++i)
App.draw(invaderSprites[i]);
Есть и другие проблемы. Например, почему вы объявляете массив спрайтов invaderSprites
когда у вас уже есть вектор спрайтов с тем же именем? Последний скрывает первый, как только он объявлен.
Другое дело, что вы устанавливаете все спрайты в одну и ту же позицию, поэтому, даже если вам удастся нарисовать их все, они все будут в одном месте, и как таковые они не будут отображаться как отдельные объекты.
Других решений пока нет …