ich habe eine Klasse Level, in der es verschiedene Arten von Objekten gibt.
Zum Beispiel Ship, Projectile und Building. Die erben alle von einer Klasse Drawable, welche aus einer Position, einem Sprite und einer Methode zum Zeichnen besteht.
Wenn ein Ship oder ein Building kaputt geschossen wird, soll eine Explosion erscheinen (ebenfalls Drawable). Die wird über Level::addExplosion(position) hinzugefügt.
Nun die Frage: Sollte ich in der Klasse Level alle Spielobjekte in einem gemeinsamen boost::ptr_vector<Drawable> speichern oder lieber getrennte Listen für Ship, Building, Projectile...
Vorteil bei einer gemeinsamen Liste:
Im Destruktor von Shootable (also alles, was abgeschossen werden kann: Ship, Building) könnte ich level.addExplosion(position) aufrufen. Dann steht es nur ein einziges Mal im Code da.
Nachteil bei einer gemeinsamen Liste:
Wenn ich zum Beispiel prüfen möchte, ob der Spieler mit einem Schiff kollidiert, kann ich ja nicht einfach gegen alle Ships prüfen, da ich ja gar nicht weiß, welche Drawable's überhaupt Schiffe sind. Meine Lösung dafür war, dass ich bereits in der Klasse Drawable eine virtuelle Methode collidesWithLocalPlayer(localPlayer) bräuchte, die dann Ship, Building usw selber implementieren müssten. Auch nicht super schön finde ich.
Nachteil bei getrennten Listen:
Ich kann nicht einfach aufrufen: level.removeObject(Drawable &)
Denn ich müsste erst prüfen, was für ein Drawable es überhaupt ist und aus der entsprechenden Liste rausnehmen.
Hier würde auch eine virtuelle Methode remove() in Drawable helfen, sodass ich zB mache:
Ship::remove() { level.removeShip(this); }
Die Klasse Level bräuchte dann auch für jede einzelne Liste eine add- und remove-Methode.
Also die Alternativen:
Code: Alles auswählen
class Level
{
private:
boost::ptr_vector<Drawable> allObjects;
public:
add(Drawable *newObject);
remove(Drawable &object);
};
Code: Alles auswählen
class Level
{
private:
boost:ptr_vector<Ship> ships;
boost:ptr_vector<Building> buildings;
boost:ptr_vector<Projectiles> projectiles;
boost:ptr_vector<Explosions> explosions;
public:
addShip(Ship *newShip);
removeShip(Ship &ship);
addBuilding(Building *newBuilding);
// [...]
};