W dzisiejszym wpisie zajmiemy się jak już obiecałem w ostatnio systemem tur i będzie to już nasza jak na razie ostatnia rzecz związana z logiką gry. Nasz system tur będzie opierał się na czasie ataku oraz odpoczynku. Z tych dwóch części będzie składała się jedna tura. Po 4 turach, kolejna jest poziom boss. Charakteryzuje się on tym, że poza zwykłymi przeciwnikami ma również jedną postać (Bossa), która ma większe umiejętności niż pozostali przeciwnicy oraz aby go wyróżnić będzie większy niż pozostałe postacie.
Czas na kod
Pierwsze czym musimy się zająć jest utworzenie nowej klasy Tura.java.
public class Tura { private boolean typ; private boolean boss; private float time; private float bossTime; private float koniecCzasuAtaku; private float koniecCzasuPrzerwy; private int makspotworow; private boolean bossdodany; public Tura(boolean typ, boolean boss, float time) { this.typ = typ; this.boss = boss; this.time = time; bossdodany = false; makspotworow = 10; bossTime = 0; koniecCzasuAtaku = 60; koniecCzasuPrzerwy = 10; } // getter and setter public void changeTimeAtac(){ koniecCzasuAtaku += 5; } public void changeTimeBreak(){ koniecCzasuPrzerwy += 2; } }
Zadaniem tej klasy jest przechowywać wszystkie dane związane z obecną turą. Określa typ, czy obecnie jest czas ataku czy regeneracji. Przechowuje informacje czy w obecnej turze występuje boss. Również przechowuje czasy związane z atakiem, regeneracją oraz bossem. Ponadto potrzebujemy przechowywać również ilość maksymalną potworków na dany poziom – makspotworow. Wraz z rozwojem systemu tur będziemy musieli również mieć pole odpowiedzialne za oznaczenie czy dany boss został już dodany do gry – bossdodany.
W konstruktorze ustawiamy początkowe dane dla naszego poziomu startowego. Przypisujemy bossdodany, co oznacza, że w tym poziomie jeszcze nie został dodany boss. Pole makspotworow, jak sama nazwa wskazuje podajemy ile maksymalnie może być potworków. bossTime pozostawiamy wyzerowane oraz ustawiamy czas ataku i regeneracji odpowiednio na 60 i 10 sekund.
Następnie w naszej nowej klasie są zawarte gettery i settery dla wszystkich pól jakie występują. Metoda changeTimeAtac() jest odpowiedzialna za zwiększanie co każdy poziom czasu ataku. Podobnie ma się do metody changeTimeBreak(), z tym że tutaj zwiększamy czas przerwy.
Teraz możemy przystąpić do opisania kodem całej logiki.
// TURA if(statystyki.getPoziom() % 5 != 0){ tura.setTime(tura.getTime() - Gdx.graphics.getDeltaTime()); // sprawdzenie czy nie skończył się czas ataku if(tura.getTime() < 0 && tura.isTyp() == false){ tura.setTyp(true); tura.changeTimeAtac(); tura.setTime(tura.getKoniecCzasuPrzerwy()); myinterface.setInfo("Przerwa od ataku"); // System.out.println("Koniec czasu ataku"); } // sprawdzenie czy nie skończył się czas odpoczynku if(tura.getTime() < 0 && tura.isTyp() == true){ Double iloscpotworkow = tura.getMakspotworow() * 1.5; tura.setMakspotworow(iloscpotworkow.intValue()); tura.setTyp(false); tura.changeTimeBreak(); tura.setTime(tura.getKoniecCzasuAtaku()); statystyki.setPoziom(statystyki.getPoziom() + 1); myinterface.setInfo("Atak"); if(statystyki.getPoziom() % 5 == 0){ tura.setBoss(true); }else{ tura.setBoss(false); } } }else{ tura.setBossTime(tura.getBossTime() + Gdx.graphics.getDeltaTime()); if(tura.getBossTime() > 5){ myinterface.setInfo(""); } if(tura.isBoss() == true && tura.isBossdodany() == false){ potwory.add(new Monster(r.nextInt(5000),r.nextInt(5000),r.nextInt(25),r.nextInt(20),r.nextInt(100))); tura.setBossdodany(true); } boolean isBoss = false; for (Monster m : potwory) { if(m.isBoss() == true){ isBoss = true; } } if(isBoss == false){ boolean gift = r.nextBoolean(); if(gift == false){ player.setHp(player.getHp() + 5); }else{ baza.setHp(baza.getHp() + 5); } tura.setBossTime(0); tura.setBoss(false); tura.setBossdodany(false); tura.setTyp(false); tura.setTime(tura.getKoniecCzasuAtaku()); statystyki.setPoziom(statystyki.getPoziom() + 1); } }
Oczywiście na początku naszego kodu gry dodajemy zmienną klasy opisaną ostatnio w osobnym wpisie – Statstyki.java oraz wyżej objaśnioną klasę Tura.java.
Główny warunek sprawdza, czy obecny poziom nie jest podzielny przez 5, jeśli jest podzielny wtedy mamy poziom Boss i musimy zmienić zachowanie naszej gry. Jednak wcześniej omówimy tury spełniające warunek. Zaraz po sprawdzeniu warunku następuje odjęcie różnicy czasu między klatkami od czasu startowego ataku (60 sekund).
Pierwszy warunek jaki jest sprawdzany po rozpoznaniu rodzaju tury jest sprawdzenie czy nadal powinna trwać tura ataku, jeśli czas jest mniejszy od zera oraz typ jest false, wtedy następuje zmiana typu na true, dodanie do czasu trwania okresu ataku 5 sekund przez metodę changeTimeAtac(), ustawienie czasu odczytując czas z pola koniecCzasuPrzerwy zmiennej tura oraz na koniec wyświetlenie komunikatu na ekranie naszej gry Przerwa od ataku.
Następny warunek sprawdza, czy nie zakończył się czas odpoczynku i działamy w podobny sposób jak wyżej, jeśli warunek został spełniony zwiększamy maksymalną ilość potworków o 1.5%, zmieniamy typ tury. Kolejną instrukcja dodaje nam 2 sekundy do czasu regeneracji za pomocą metody changeTimeBreak(). Zwiększamy w statystykach poziom o jeden i wyświetlamy komunikat Atak. W tym warunku jest sprawdzany jeszcze jeden warunek, którego zadaniem jest zmiana pola Boss. Jeśli zwiększony poziom jest podzielny przez 5 wtedy zostaje ustawiona zmienna Boss na true.
W momencie kiedy poziom jest z Bossem, wtedy zaczynamy od dodawania różnicy klatek naszej zmiennej odpowiedzialnej za mierzenie czasu. Następnie gdy dodawany czas jest większy od 5 następuje wymazania ostatniego napisu z ekranu.
Kolejny warunek jest odpowiedzialny za dodawanie bossa do gry oraz ustawienie pola bossDodany na true, tylko wtedy gdy poziom jest typu boss oraz boss jeszcze nie został dodany.
Jako, że boss jest dodawany do listy wszystkich naszych potworów, musimy zrobić jakoś sprawdzenie, czy aby nie został już zabity. Wykorzystujemy do tego zmienną pomocniczą isBoss, która początkowo jest ustawiona na false. Następnie tworzymy iterator i sprawdzamy dla każdego potwora, czy dany potwór jest bossem, jeśli tak wtedy zmieniamy wartość naszej zmiennej pomocniczej na true.
Następnie jako zakończenie poziomu bossa, następuje sprawdzenie czy wcześniejsza zmienna pomocniczą jest równa false, jeśli tak ustawiamy odpowiednio dane, aby został załadowany następny poziom zaczynający się od ataku wrogów. Po pokonaniu każdego bossa dostajemy bonus w postaci +5 punktów życia bohatera lub wytrzymałości bazy. Kolejna metoda zeruje czas pola bossTime. Zmieniamy flagę boss oraz bossDodany, aby w kolejnej turze nie został utworzona postać bossa. Kolejno ustawiamy typ tury na false, czas fali ataku odczytujemy z pola koniecCzasuAtaku zmiennej tura oraz zwiększamy poziom o 1.
if(potwory.size() < tura.getMakspotworow() && tura.isTyp() == false) potwory.add(new Monster(r.nextInt(5000),r.nextInt(5000), statystyki.getPoziom()));
Pozostało nam jeszcze ograniczyć ilość dodawanych przeciwników do pola utworzonego w klasie Tura.java. Zmieniamy nasz poprzedni warunek na powyższy, który sprawdza nam, czy liczba potworków nie przekracza maksymalnej na ten poziom.
Ostatnią czynnością jaką musimy zrobić jest wyświetlanie informacji o obecnym poziomie na jakim znajduje się gracz. W tej chwili już nie będziemy potrzebować wyświetlania współrzędnych naszego bohatera, w to miejsce wstawimy obecny poziom na jakim znajduje gracz.
Podsumowanie
W dzisiejszym wpisie udało nam się stworzyć i omówić sposób działania tur w naszej grze. To jak na razie ostatni wpis z logiką gry. Teraz będziemy zajmować się graficznym wyglądem naszej zabawki jaką już stworzyliśmy. Możemy być dumni z tego co już osiągnęliśmy. Na dniach ukaże się kolejny wpis i mam nadzieje, że będzie to dla was miłe zaskoczenie, jednak na razie nie chce zdradzać więcej szczegółów.
Pozdrawiam,
sirmarbug