Twarz bohatera – refaktoring

Ostatnie wpisy związane z projektem UWar dotyczyły, omówienia programu do tworzenia mapy tekstur oraz grafiki naszego bohatera. Jednak sposób w jaki oprogramowałem wczytywanie tej grafiki jest daleki od ideału, o czym dowiedziałem się z komentarza pod wpisem. Ważne jest tworząc bloga ze swoich poczynań programistycznych, aby wyciągać wnioski z otrzymanych feedbacków oraz wprowadzać poprawki, aby kod był bardziej jakościowy. Dlatego też w tym wpisie zajmiemy się poprawieniem wcześniej napisanego kodu.

Link do wcześniejszego wpisu z utworzeniem grafiki bohatera, na którym będziemy bazować.

Przygotowanie grafiki

Do dalszej pracy potrzebujemy stworzyć mapę tekstur, która składać się będzie w naszym przypadku z trzech pików graficznych. Stworzenie takiej mapy opisywałem we wcześniejszym wpisie. Możecie ten wpis znaleźć tutaj. Ułatwi nam to zarządzanie dodanymi plikami, dzięki czemu unikniemy niepożądanych efektów.

Gotowa mapa

mapa

Jak widzimy, wcześniej potrzebowaliśmy aż 12 plików graficznych, tym razem zoptymalizowaliśmy to do 3, dzięki czemu ułatwimy sobie zapis w kodzie.

Refaktoryzacja kodu

private Texture texturePlayer;
private TextureRegion[] playerRegionLeft;
private TextureRegion[] playerRegionRight;
private TextureRegion[] playerRegionUp;
private TextureRegion[] playerRegionDown;

Wcześniej, aby poprawnie wyświetlała się grafika potrzebowaliśmy, aż 5 zmiennych, z czego 4 z nich były tablicami, składającymi się z trzech elementów. Teraz tego kodu możemy się już pozbyć i zastąpić go nowym, zdecydowanie prostszym.

private TextureAtlas textureAtlasPlayer;

Teraz wykorzystamy klasę TextureAtlas, która przechowuje przygotowaną wcześniej przez nas mapę grafik.

W tej chwili możemy się pozbyć inicjalizacji starych zmiennych, które już nie będą wykorzystywane.

textureAtlasPlayer = new TextureAtlas(Gdx.files.internal("player.pack"));

Konstruktor klasy TextureAtlas przyjmuje jako parametr plik, który zawiera informacje o grafikach zawartych w wygenerowanej przez nas mapie. Plik ten jest generowany przez program, którym utworzona została przez nas mapa (opisywałem to podczas omawiania programu do tworzenia map graficznych).

Teraz musimy przejść do klasy odpowiedzialnej za obiekt bohatera, czyli do Player.java. Dodajemy tam pole typu Sprite, które będzie przechowywać grafikę do wyświetlenia.

Jednak abyśmy mogli ją prawidłowo wyświetlić, musimy jeszcze stworzyć metodę, która będzie odpowiednio manipulować wczytaną grafiką.

public void draw (SpriteBatch batch, TextureAtlas region, float angle) {
     sprite.set(region.createSprite("" + getStep()));
     sprite.setPosition(getPozycja().x, getPozycja().y);
     sprite.rotate(angle);
     sprite.draw(batch);
}

Jest to metoda draw(), jak sama nazwa wskazuje, będzie odpowiedzialna za rysowanie na ekranie postaci gracza. Jako argumenty przyjmuje SpriteBatch, na którym rysowane są wszystkie elementy gry, TextureAtlas, czyli naszą mapę grafik oraz wartość zmiennoprzecinkową angle, odpowiedzialną za kąt, o jaki ma zostać obrócona grafika. Obrót sprite jest nam potrzebny, ponieważ mapa składa się tylko z trzech grafik, dlatego potrzebujemy, obracać ją odpowiednio do kierunku poruszania.

Pierwsza linijka naszej metody odpowiedzialna jest za załadowanie grafiki z mapy. Metoda set()ustawia grafikę, przekazaną w parametrze. Jako parametr przyjmowana jest wartość zwracana przez metodę createSprite() wywołana dla zmiennej region. createSprite() jako parametr przyjmuje nazwę grafiki jaką chcemy pobrać. W naszym wypadku są to nazwy 0,1,2.

Nazwy te odpowiadają krokom (zrealizowane w taki sam sposób jak wcześniej).

0 – ruch lewą nogą

1 – stan bezruchu

2 – ruch prawą nogą

Dlatego createSprite() pobiera w parametrze numer kroku za pomocą metody getStep().

Następnie ustawiana jest pozycja na jakiej ma zostać wyświetlony sprite. W parametrach przekazywana jest pozycja gracza.

Kolejna linijka odpowiedzialna jest za obrót sprite o wartość przekazaną jako argument angle.

Na koniec tej metody następuje rysowanie, przygotowanego odpowiednio sprite na ekranie.

Teraz możemy wrócić do naszej głównej klasy – Game.java

Pozostaje nam podmienić kod odpowiedzialny za rysowanie gracza na ekranie.

if(player.getDirection() == 0){
     player.draw(batch, textureAtlasPlayer, 180); // left
}else if(player.getDirection() == 2){
     player.draw(batch, textureAtlasPlayer, 0); // right
}else if(player.getDirection() == 1){
     player.draw(batch, textureAtlasPlayer, 90); // down
}else{
     player.draw(batch, textureAtlasPlayer, 280); // up
}

Jak widzimy do rysowania gracza, wykorzystujemy wcześniej napisaną metodę draw(), zmieniając jedynie kąt obrotu sprite.

Efekt działania

Podsumowanie

Udało nam się zoptymalizować kod odpowiedzialny za rysowanie gracza na ekranie. Teraz odbywa się to w zdecydowanie czytelniejszy sposób. Wcześniej potrzebowaliśmy więcej zmiennych, grafik, aby osiągnąć ten sam efekt.

Dobrze jest uczyć się pisząc bloga, ponieważ czytelnicy mający wiekszą wiedzę z danego tematu, mogę podpowiedzieć, dać wskazówkę, co ułatwia poznawanie nowej technologii.

TextureAtlas do inicjalizacji potrzebuje pliku opisującego stworzoną mapę. W tym samym katalogu musi także znajdować się plik graficzny z mapą. Wyszukiwanie obszarów – grafik odbywa się poprzez nazwę plików graficznych, z których została utworzona mapa. Do tego możemy wykorzystać np. metodę createSprite.

Pozdrawiam,

sirmarbug

Podziel się ze znajomymi