Heh. OOP seems daunting at first, but once it "clicks" and you start really understanding it, it really makes a lot of things simpler. ;)
I don't really understand what certain things are (like in your resource manager's "get") |
The idea behind a get() function:
- It returns a reference to a texture.
- The resource manager has an internal list (or really, a map<> would make more sense) of textures.
- When you call get(), the resource manager would check its map to see if the desired texture is already loaded.
- If it is, it just returns that texture (no need to reload it)
- If it isn't, it will load it, put it in the map, then return it.
That way textures are only ever loaded once... and any number of sprites that need a texture can easily grab it.
Should I be making all of these in different files? |
General rule of thumb: 1 class = 1 header + 1 cpp file.
That's a very, very basic guideline though and it my no means is a solid rule that you must follow. If you have a small class that just acts as support for a larger class, it might make sense to keep both classes in the same files.
Just use your judgement. Whatever you feel helps keep your code more organized.
Also, how would it work without having each tower have its own bullet vector if every tower will shoot different bullets at different times in different positions? |
This would be where you'd use polymorphism.
Have an abstract 'Bullet' class with a few fundamental pure virtual functions... like
update
for logic updates... and
draw
to actually draw to the screen. Then from there you can derive a different class to represent each different kind of bullet.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
|
class Bullet
{
public:
virtual ~Bullet() { } // make a virtual destructor for abstract parent classes. General rule
virtual void update() = 0; // pure virtual 'update' function
virtual void draw( sf::RenderTarget& target ) = 0; // pure virtual 'draw' function
};
//...
// your class to represent normal bullets
class NormalBullet : public Bullet
{
private:
// <the sprite, position, velocity, and other data you need to represent this bullet>
public:
virtual void update() override
{
// ... do 'normal bullet' behavior here
}
virtual void draw( sf::RenderTarget& target ) override
{
// ... do 'normal bullet' drawing here
}
};
//...
class ExplodingBullet : public Bullet
{
private:
// <the data needed for this kind of bullet>
public:
virtual void update() override
{
// ... do 'exploding bullet' behavior here
}
virtual void draw( sf::RenderTarget& target ) override
{
// ... do 'exploding bullet' drawing here
}
};
|
And so on. Just make a new class for each different type of bullet.
Since they're all derived from the
Bullet
parent class, you can put them all in the same array through the use of pointers:
1 2 3 4 5 6 7 8
|
std::vector< Bullet* > bulletlist;
bulletlist.push_back( new NormalBullet( ... ) );
bulletlist.push_back( new ExplodingBullet( ... ) );
for(auto& i : bulletlist)
i->update(); // this will call the appropriate version of 'update' depending
// on what kind of bullet this is
|
Of course the danger here is that now you're using new, so memory will leak unless you delete it. The best way to approach that is to use a smart pointer, such as unique_ptr to automatically delete the bullet when you're done with it:
1 2 3 4 5 6 7 8 9
|
typedef std::unique_ptr< Bullet > BulletPtr;
std::vector< BulletPtr > bulletlist;
bulletlist.push_back(
BulletPtr(
new NormalBullet( ... )
)
);
|
Now since you're new'ing into a smart pointer, you do not have to delete it because the smart pointer class will automatically delete it. No risk of memory leak.