Witam!
Zostałem niedawno zmuszony do napisania gry. Gra działa, ale kod mi się nie do końca podoba - jest powielony, a nie bardzo wiem, jak go uprościć.
Jest abstrakcyjna klasa bazowa PoruszanySilnikiem, dziedziczą po niej wszystkie klasy, za których ruch odpowiada "silnik" gry. Część obiektów tych klas pojawia się w losowych odstępach, więc klasy posiadają pola const opisujące minimalny i maksymalny odstęp między ich pojawianiem się, oraz pole statyczne przechowujące czas ostatniego pojawienia się.
Te klasy wyglądają np. tak:
internal class Apteczka : PoruszanySilnikiem
{
internal const int odstępMinimalny = 10000;
internal const int odstępMaksymalny = 50000;
internal static long czasOstatniego;
internal Apteczka() : base()
{
//....
}
}
internal class WrógZwykły : WrogiObiekt //WrogiObiekt : PoruszanySilnikiem
{
internal const int odstępMinimalny = 1000;
internal const int odstępMaksymalny = 10000;
internal static long czasOstatniego;
internal WrógZwykły() : base()
{
//....
}
}
Za pojawianie się nowych obiektów każdej z tych klas na planszy odpowiadają oddzielne metody klasy Silnik, wywoływane przy tworzeniu każdej klatki gry:
<code class="c#">private void GenerujApteczki()
{
int czas = los.Next(Apteczka.odstępMinimalny, Apteczka.odstępMaksymalny);
long aktualny = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
//jeśli od pojawienia się ostatniej apteczki minął wymagany czas
if (aktualny - Apteczka.czasOstatniego > czas)
{
//utworzenie nowej apteczki i dodanie jej do listy
this.poruszalneSilnikiem.Add(new Apteczka());
//zapamiętanie czasu ostatnio wygenerowanej apteczki
Apteczka.czasOstatniego = aktualny;
}
}
private void GenerujWrogówZwykłych()
{
int czas = los.Next(WrógZwykły.odstępMinimalny, WrógZwykły.odstępMaksymalny);
long aktualny = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
//jeśli od pojawienia się ostatniego wroga minął wymagany czas
if (aktualny - WrógZwykły.czasOstatniego > czas)
{
//utworzenie nowego wroga i dodanie go do listy
this.poruszalneSilnikiem.Add(new WrógZwykły());
//zapamiętanie czasu ostatniego wroga
WrógZwykły.czasOstatniego = aktualny;
}
}
Dlatego chcąc dodajać nowy typ, muszę po pierwsze utworzyć jego klasę, a pod drugie skopiować jedną z powyższych metod i zmienić w niej nazwy typu. Wiem, że jeśli potrzeba mieć jedną metodę dla wielu typów, to używa się metod generycznych - ale nie bardzo udało mi się tutaj coś takiego wymyślić. Kombinowałem też coś z interfejsami, ale również bezskutecznie.
Jak to poprawić?