Dziś zajmiemy się utworzeniem menu początkowego oraz informacji pojawiającej po zakończeniu rozgrywki prezentującej uzyskany przez nas wynik. Jak zawsze, nie będziemy się skupiać na grafice lecz na mechanice działania tej części projektu. Menu to główne okno z tytułem gry oraz obecną wersją, gdzie po naciśnięciu klawisza enter przeniesie nas do gry. Gdy warunek końca potyczki zostanie spełniony przeniesie nas do jej podsumowania i znów klawisz enter przeniesie nas do nowej gry. Natomiast klawisz ESC wyjdzie z gry zarówno w menu jak i podsumowaniu. Dziś będziemy korzystać z klasy Game oraz Screen.
Klasa Game to abstrakcyjna klasa, która zawiera implementację ApplicationListener oraz możliwość obsługi zmian renderowania okna gry.
Klasa Screen jest odpowiedzialna za tworzenie nowych widoków. Cechą charakterystyczną jest posiadanie dodatkowych metod show() i hide(). W naszej grze będziemy posiadać 3 klasy tego typu odpowiedzialne za wyświetlanie odpowiednio menu, gry oraz podsumowania rozgrywki.
Czas na kod
Przenosimy naszą dotychczasową zawartość pliku UWar.java do Game.java, a w pliku UWar.java wstawiamy nasz kod dziedziczący po klasie Game.
public class UWar extends Game{ public SpriteBatch batch; public BitmapFont font; public void create() { batch = new SpriteBatch(); font = new BitmapFont(); this.setScreen(new Menu(this)); } public void render() { super.render(); } public void dispose() { batch.dispose(); font.dispose(); } }
Mamy tu zadeklarowane dwie zmienne batch odpowiedzialną za rysowanie elementów screenów na ekranie oraz BitmapFont, którego zadaniem jest wypisywanie na ekranie tekstu, np. nazwy i wersji gry lub sumy zdobytych punktów. W metodzie create() mamy inicjalizację zmiennych oraz ustawienie ekranu początkowego na menu za pomocą metody setScreen, będącej częścią klasy dziedziczonej. Warto również wspomnieć, aby obraz został wyświetlony w metodzie render(), musimy wywołać metodę render(), z klasy dziedziczonej.
Przyszedł czas na omówienie naszych screenów. Jeden z nich to cały kod naszej gry, znajdziemy go w klasie Game.java (tego nie będę omawiał, zrobiłem to w poprzednich wpisach).
Kolejny screen to Menu.java, który jest automatycznie ładowany wraz ze startem gry.
public class Menu implements Screen { final UWar game; OrthographicCamera camera; public Menu(final UWar game) { this.game = game; camera = new OrthographicCamera(); camera.setToOrtho(false, 800, 600); } @Override public void render(float delta) { Gdx.gl.glClearColor(0, 0, 0.2f, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); camera.update(); game.batch.setProjectionMatrix(camera.combined); game.batch.begin(); game.font.draw(game.batch, "UWar v.0.2.1", 360, 500); game.batch.end(); if (Gdx.input.isTouched() || Gdx.input.isKeyPressed(Input.Keys.ENTER)) { game.setScreen(new Game(game)); dispose(); } if (Gdx.input.isKeyPressed(Input.Keys.ESCAPE)) { dispose(); Gdx.app.exit(); } } @Override public void resize(int width, int height) { } @Override public void show() { } @Override public void hide() { } @Override public void pause() { } @Override public void resume() { } @Override public void dispose() { } }
Mamy tu dwie zmienne, jedna klasy Game, odpowiedzialna za przekazany przez parametr obszar okna oraz druga zmienna klasy OrthographicCamera, odpowiedzialna za rozdzielczość naszego screena. W screenie nie mamy metody create(), ponieważ jest tworzony za pomocą konstruktora przy wywołaniu. W metodzie render() mamy rysowanie na ekranie napisu nazwy gry oraz jej wersji. Oraz sprawdzenie czy klawisz enter oraz esc zostały wciśnięte w pierwszym przypadku przenosi nas do gry, zaś w drugim wychodzi z niej.
W podobny sposób tworzone jest podsumowanie z różnicą, że zamiast nazwy gry wyświetlany jest wynik przekazany przez parametr.
public class End implements Screen { final UWar game; private String wynik; OrthographicCamera camera; public End(final UWar game, final Player player) { this.game = game; wynik = player.getScore() + ""; camera = new OrthographicCamera(); camera.setToOrtho(false, 800, 600); } @Override public void render(float delta) { Gdx.gl.glClearColor(0, 0, 0.2f, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); camera.update(); game.batch.setProjectionMatrix(camera.combined); game.batch.begin(); game.font.draw(game.batch, "Koniec", 360, 500); game.font.draw(game.batch, wynik, 360, 450); game.batch.end(); if (Gdx.input.isTouched() || Gdx.input.isKeyPressed(Input.Keys.ENTER)) { game.setScreen(new Game(game)); dispose(); } if (Gdx.input.isKeyPressed(Input.Keys.ESCAPE)) { dispose(); Gdx.app.exit(); } } @Override public void resize(int width, int height) { } @Override public void show() { } @Override public void hide() { } @Override public void pause() { } @Override public void resume() { } @Override public void dispose() { } }
Screeny z dzisiejszej pracy
Podsumowanie
Dziś w krótszym wpisie niż ostatnio udało się nam utworzyć menu do naszej gry oraz podsumowanie ukończonej rozgrywki. Wszystko małymi krokami zmierza ku końcowi. W niedługim czasie postaram się wam przedstawić rozwiązanie systemu tur oraz ulepszenie inteligencji przeciwników (już nie będzie to tylko random), a później zajmiemy się grafiką.
Pozdrawiam,
sirmarbug