Monfik said:
I have Tower classAttackTower class based on Tower
IceTower, FireTower, ArcherTower, CrossbowTower, StoneTower and some others based on Attack Tower.
The point is of all discussion above: Stop seeing “Tower” as a single thing. It's not 1 thing. It's a whole lot of things at the same time. Lots of sub-systems that work together to get tower behavior. You have the building itself as system. There is some cannon-barrel, there is a firing mechanism, and this is just the bare minimum. You could have power supply systems inside, heating system, munition storage, fire guidance systems, guard living quarters, and what not.
In the real world, if you have a tower and want a different tower, you don't tear down everything and rebuild it from scratch. No! Instead you just tear out some of the systems inside that are obsolete, and replace them by other systems inside (and only those). Everything else is just kept as is. An IceTower is not completely different from a FireTower, eg the basic tower building is the same at least, and likely other systems are the same as well.
You can do such a thing in software too. A “class Tower” is not a single thing with a lot of data fields. Instead, make a tower that has a lot of objects, one for each subsystem that you have. When you change the tower, don't delete the whole tower, only change some of its objects inside.
Not an C# expert, but this is a direction you can take. Note I entirely made this up, it likely doesn't even work, but I hope you get the idea that you can change the tower by changing only some parts of it.
class AttackSystem { // Attack system of the tower.
Graphics attackSystemGraphics; // Graphics of the attack system
}
class FireAttack extends AttackSystem {
int fireDamagePerSecond;
void attackEnemy(Enemy e) {
// Damage enemy with fire attack at 'fireDamagePerSecond' rate.
}
}
class IceAttack: extends AttackSystem {
float slowPower;
void attackEnemy(Enemy e) {
// Damage enemy with ice attack at 'slowPower' rate.
}
}
Subsystem with graphics that can attack an enemy.
class Tower {
Graphics towerGraphics; // Graphics of the tower
AttackSystem attackSystem;
// You can have many more sub-systems here.
// Attack an enemy.
void attackEnemy(Enemy e) {
attackSystem.attackEnemy(e);
}
// Paint the tower to the display.
void draw(Display display) {
towerGraphics.paint(display);
attackSystem.attackSystemGraphics.paint(display);
}
// Modify display of tower.
void changeTowerGraphics(Graphics tg) {
towerGraphics = tg;
}
// Modify attack system of the tower.
void changeAttackSystem(AttackSystem a) {
attackSystem = a;
}
}
See how the tower has an AttackSystem and towerGraphics object. You can change them with the “change” functions. Each kind of attack system can have its own set of variables.
Methods of the tower, like “draw” or “attackEnemy” don't do much, they just call the sub-systems. Inside the subsystems the actual request is handled.
Obviously, you can do this trick again if you like, have more systems, or make subsub-systems inside sub-systems.