Witam! Od jakiegoś czasu tworzę grę top-down shooter i tworząc menedżer przeciwników, mający nimi zarządzać napotkałem się na problem.
Najpierw pokażę kod, a potem przejdę do sedna sprawy.
#pragma once
#include "Bullet.h"
#include "Collider.h"
#include "Enemy.h"
#include "TextureManager.h"
class EnemyManager
{
private:
Collider* colliderPointer;
Character* targetOfEnemies;
TextureManager* textureManagerPointer;
std::list<Enemy> enemies;
std::list<std::list<Enemy>::iterator> enemiesToRemove;
public:
EnemyManager() {};
~EnemyManager() {};
void addEnemies(std::fstream& enemiesFile);
void removeEnemy(std::list<Enemy>::iterator& it);
void removeEnemiesToRemove();
void updateEnemies(float delta);
void drawEnemies(sf::RenderTarget& target);
void setTargetOfEnemies(Character* _target);
void setColliderPointer(Collider& _colliderPointer);
void setTextureManagerPointer(TextureManager& _textureManagerPointer);
void fireWhenTargetInRange();
};
void EnemyManager::addEnemies(std::fstream& enemiesFile)
{
while(!enemiesFile.eof())
{
Enemy enemy;
std::string name;
enemiesFile >> name;
enemy.setName(name);
int health_points;
enemiesFile >> health_points;
enemy.setHealthPoints(health_points);
std::string textureName;
enemiesFile >> textureName;
sf::Vector2f position;
enemiesFile >> position.x;
enemiesFile >> position.y;
enemy.setPosition(position);
sf::Vector2f velocity;
enemiesFile >> velocity.x;
enemiesFile >> velocity.y;
enemy.setVelocity(velocity);
std::string bulletTextureName;
enemiesFile >> bulletTextureName;
enemies.push_back(enemy);
enemies.back().setTexture(textureManagerPointer->getReferenceToTexture(textureName));
enemies.back().shootingWeapon.setBulletTexture(textureManagerPointer->getReferenceToTexture(bulletTextureName));
enemies.back().chooseTarget(targetOfEnemies);
colliderPointer->addCharacter(&enemies.back());
}
}
Wszystko działa poprawnie. Jednakże problem pojawia się, kiedy zechcę użyć polimorfizmu, żeby tworzyć przeciwników różnych typów. Wiadomo, lista, która przechowuje teraz przeciwników jako takich, musiałaby wtedy przechowywać wskaźniki do obiektów ich reprezentujących. Wykorzystanie powyższej funkcji nie zadziałałoby, bo po opuszczeniu jej, obiekt na który wskazuje wskaźnik nie istniałby już. Pierwsze rozwiązanie, które zauważyłem i od razu wyrzuciłem do kosza, to stworzenie osobnych list na każdy typ wroga - ale to się przeczy z samą ideą polimorfizmu. Poczytałem coś o fabryce abstrakcyjnej, ale z tego co rozumiem, to przy dodawaniu kolejnej klasy dziedziczącej po Enemy, będę musiał modyfikować klasę bazową fabryki, jak i dodać kolejną pochodną. Przeszukiwanie angielskich for w poszukiwaniu rozwiązania też nie przyniosło żadnych skutków, być może źle formułowałem zapytania do wyszukiwarki. Macie jakieś pomysły? :)