Hi, first of all I know the "White square problem" described in the sprite tutorial. I understand it.
In my case, I create a Player class with a sprite and texture members. In main code, when a user press M key, create a new instance of Player and add it into a vector. I known that the elements of a vector move in memory when the vector change and then lost the reference of the sprite texture.
Now, my question is how I can fix it? I tried with add setTexture every time I draw, but I don't know if its a good solution.
I attach an screenshoot about I'm saying.
I wrote a minimal example. This is the code, can download
here.
I use SFML-2.1 with Code:Blocks (Windows 8 Pro, 32bits)
Player.h
//Player class
#ifndef PLAYER_H
#define PLAYER_H
#include <SFML/Graphics.hpp>
#include <iostream>
class Player
{
public:
Player(sf::Vector2i position, sf::Color colorSpr, sf::String filenameSpr);
~Player();
void Draw(sf::RenderWindow &Window);
sf::Sprite sprPlayer;
sf::Texture texturePlayer;
int sprWidth, sprHeight;
protected:
private:
};
#endif
Player.cpp
#include "Player.h"
//constructor
Player::Player(sf::Vector2i position, sf::Color colorSpr, sf::String filenameSpr)
{
if(!texturePlayer.loadFromFile(filenameSpr, sf::IntRect(0, 0, 32, 32)))
std::cout << "Error, can't load SpriteSheet " << std::endl;
sprPlayer.setTexture(texturePlayer);
sprPlayer.setColor(colorSpr);
sprWidth = sprPlayer.getTextureRect().width;
sprHeight = sprPlayer.getTextureRect().height;
sprPlayer.setPosition(position.x * sprWidth, position.y * sprHeight);
}
//destructor
Player::~Player()
{
}
//draw player
void Player::Draw(sf::RenderWindow &Window)
{
//sprPlayer.setTexture(texturePlayer); //<- with this it works
Window.draw(sprPlayer);
}
Main.cpp
#include <SFML/Graphics.hpp>
#include <vector>
#include "Player.h"
const int maxPlayers = 10;
//colors for players
sf::Color pColors[maxPlayers] = {sf::Color(255, 0, 0, 255), sf::Color(0, 255, 0, 255),
sf::Color(100, 100, 0, 255), sf::Color(0, 0, 255, 255),
sf::Color(80, 200, 120, 255), sf::Color(100, 100, 155, 255),
sf::Color(123, 160, 90, 255), sf::Color(200, 0, 255, 255),
sf::Color(254, 195, 172, 255), sf::Color(255, 255, 255, 255)
};
sf::String spriteSheets[maxPlayers] = {"punky2.png", "punky.png", "punky.png", "punky.png", "punky.png",
"punky.png", "punky.png", "punky.png", "punky.png", "punky.png"
};
int main()
{
sf::Vector2i playerPosition(0, 0);
int numRivals = 0;
std::vector <Player> rivals;
rivals.reserve(maxPlayers);
sf::RenderWindow Window(sf::VideoMode(640, 480, 32), "Test");
Window.setKeyRepeatEnabled(false);
//create player
Player hero(playerPosition, pColors[0], spriteSheets[0]);
while (Window.isOpen())
{
sf::Event event;
while (Window.pollEvent(event))
{
switch (event.type)
{
case sf::Event::Closed:
{
Window.close();
break;
}
case sf::Event::KeyPressed:
if (event.key.code == sf::Keyboard::Escape)
{
Window.close();
}
else if (event.key.code == sf::Keyboard::Right)
{
hero.sprPlayer.move(3, 0);
}
else if (event.key.code == sf::Keyboard::Left)
{
hero.sprPlayer.move(-3, 0);
}
else if (event.key.code == sf::Keyboard::Down)
{
hero.sprPlayer.move(0, 3);
}
else if (event.key.code == sf::Keyboard::Up)
{
hero.sprPlayer.move(0, -3);
}
else if (event.key.code == sf::Keyboard::M)
{
if (numRivals < maxPlayers - 1)
{
numRivals++;
Player rival(sf::Vector2i(3 + numRivals, 0), pColors[numRivals], spriteSheets[numRivals]);
rivals.push_back(rival);
}
}
break;
}
}
//draw stuff
hero.Draw(Window);
if (numRivals > 0)
{
for (int k = 0; k < rivals.size(); k++)
{
rivals[k].Draw(Window);
}
}
Window.display();
Window.clear(sf::Color(255, 255, 0, 255));
}
return 0;
}