Hey guys,
I've been on a roll with SFML, creating a simple scrolling shooter, but so far the only way I've been able to keep references to graphics available long enough to be used is by storing them in fixed-size arrays or class properties for every instance. Initially I thought it was possible to use vectors, maps, etc. but quickly found out that the way those classes work internally is to make copies, so anything I create is destroyed the second it goes out of scope. Sounds don't play, and graphics get the white square bug, if I use anything out of the STL.
But then again, I'm thinking that might not actually be the case. I've only been doing C++ for about 6 months, and it's the first language I've learned where memory management is an issue. So odds are that there's some other way I just haven't learned yet. Take for example these 2 versions of the same class:
// This is the version that works, using a class property for every instance
#ifndef SOUND_PLAYER_H
#define SOUND_PLAYER_H
#include <map>
#include <SFML/Audio.hpp>
class SoundPlayer
{
public:
static SoundPlayer * Get();
void PlayerLaser();
private:
static SoundPlayer * Instance;
SoundPlayer();
sf::SoundBuffer player_laser, enemy1_explode;
sf::Sound sound;
};
SoundPlayer * SoundPlayer::Instance = NULL;
SoundPlayer * SoundPlayer::Get()
{
if (Instance == NULL)
Instance = new SoundPlayer();
return Instance;
}
SoundPlayer::SoundPlayer()
{
if (!player_laser.loadFromFile("bin\\debug\\sounds\\player_laser.wav"))
throw "Error loading the player laser sound";
if (!enemy1_explode.loadFromFile("bin\\debug\\sounds\\enemy1_explode.wav"))
throw "Error loading the enemy 1 explosion sound";
}
void SoundPlayer::PlayerLaser()
{
sound.setBuffer(player_laser);
sound.play();
}
#endif
// And this is the one that doesn't work, using maps
// I've tried maps of objects, and maps of pointers (which is what's shown here)
// and both don't seem to have what it takes to work in SFML - but they've been around for decades so it's obviously just me being a noob :)
#ifndef SOUND_PLAYER_H
#define SOUND_PLAYER_H
#include <map>
#include <SFML/Audio.hpp>
class SoundPlayer
{
public:
static SoundPlayer * Get();
void PlayerLaser();
private:
static SoundPlayer * Instance;
SoundPlayer();
std::map<std::string, sf::SoundBuffer*> buffers;
std::map<std::string, sf::Sound*> sounds;
};
SoundPlayer * SoundPlayer::Instance = NULL;
SoundPlayer * SoundPlayer::Get()
{
if (Instance == NULL)
Instance = new SoundPlayer();
return Instance;
}
SoundPlayer::SoundPlayer()
{
sf::SoundBuffer b1;
if (!b1.loadFromFile("bin\\debug\\sounds\\player_laser.wav"))
throw "Error loading the player laser sound";
buffers.insert(std::make_pair("player_laser", &b1));
sf::Sound s1;
s1.setBuffer(b1);
sounds.insert(std::make_pair("player_laser", &s1));
}
void SoundPlayer::PlayerLaser()
{
sounds["player_laser"]->play();
}
#endif
Both compile fine, and both "look" like they should work, but because of however these STL classes work "under the hood" they just don't seem to work well with SFML, making the idea little more than wishful thinking. From what I've read (including another question on this forum) the way they work is to make copies of the objects, and I haven't been able to figure out a way around that obstacle yet. I've tried vectors/maps of objects, and also pointers (shown above), and none of it seems to work... so it's gotta be me just being a noob (lol).
But it's no biggy if it actually can't be done. Fixed arrays and class properties per object are working reliably, and I've got a pretty cool little game going using them as my go-to for everything SFML-related. Heck, even the NES could only have up to 64 objects on the screen at once, so my player object only being able to use up to 5 laser instances or there only being up to 16 enemies is not an issue. But there's a reason the STL was created, problems with the fixed-size way of doing things that it was meant to solve, and I bet there's a better way to use it that I just haven't figured out yet.
So how do you guys handle textures, sprites, sound buffers, sounds, and other stuff like that? I'm sure I'm not the first guy who's ever had this question (and since the white square issue is brought up
in the documentation it must be super-common) but so far I haven't managed to fish up any answers on Google, so I figured I'd ask the pros.
Thanks in advance.