Gra 2D, część 8: Dobrze mieć wybór... poziomu

25.08.2010 - Marcin Milewski
TrudnośćTrudność

Przechodzenie między stanami gry

Dodając nowy stan do aplikacji powinniśmy zadbać o jego poprawne połączenie z tymi już istniejącymi. Zilustrujmy informację o stanach i ich wzajemnym połączeniu, to znaczy o możliwości przejścia między stanami. Następnie zajmiemy się uaktualnianiem kodu aplikacji tak, aby odpowiadał ilustracji:

Stany aplikacji oraz połączenia między nimi obrazujące możliwość przejścia z jednego stanu do drugiego.

Wprowadzanie zmian zacznijmy od klasy Menu. Naciśnięcie Entera nad opcją "nowa gra" powinno owocować przejściem do stanu LevelChoiceScreen. Zauważmy także, że z Menu nie da się przejść do Game. Zmiany w pliku MainMenu.cpp są następujące: zastępujemy

1
2
#include "Game.h"
  

kodem

1
2
#include "LevelChoiceScreen.h"
  

a następnie przechodzimy do ciała metody MainMenu::ProcessEvents i zmieniamy

1
2
3
4
            if (m_selection == Sel::NewGame) {
                m_next_app_state.reset(new Game("1", PlayerPtr()) );
            }
  

na

1
2
3
4
            if (m_selection == Sel::NewGame) {
                m_next_app_state.reset(new LevelChoiceScreen(PlayerPtr()));
            }
  

Aktualizacji wymaga także implementacja klasy Game. Otwieramy plik Game.cpp i w metodzie Game::ProcessEvents zmieniamy

1
2
3
4
5
6
7
8
9
    // przyjrzyj zdarzenia
    if (event.type == SDL_QUIT) {
        SetDone();
    } else if (event.type == SDL_KEYDOWN 
            && event.key.keysym.sym == SDLK_ESCAPE) {
        SetDone();
    } else if (event.type == SDL_KEYDOWN 
            && event.key.keysym.sym == SDLK_d) {
  

na

1
2
3
4
5
6
7
8
9
10
11
    // przyjrzyj zdarzenia
    if (event.type == SDL_QUIT) {
        SetDone();
    } else if (event.type == SDL_KEYDOWN 
            && event.key.keysym.sym == SDLK_ESCAPE) {
        m_next_app_state = m_level_choice_screen;
        m_next_app_state->Init();
        SetDone();
    } else if (event.type == SDL_KEYDOWN 
            && event.key.keysym.sym == SDLK_d) {
  

Ponieważ o następnym rozgrywanym poziomie będzie decydował użytkownik za pośrednictwem ekranu wyboru poziomu, to z metody Game::Init możemy usunąć ustawianie następnego stanu. Zmieniamy

1
2
3
4
5
6
7
8
9
    // ładowanie poziomu i sprite'ów planszy
    m_level.reset(new Level());
    m_level->LoadFromFile("data/" + m_level_name + ".lvl");
    if (!m_level->GetLoaded()) {
        m_level_name = "1";
        m_level->LoadFromFile("data/" + m_level_name + ".lvl");
        SetNextLevelName();   // TO USUWAMY
    }
  

na

1
2
3
4
5
6
7
8
    // ładowanie poziomu i sprite'ów planszy
    m_level.reset(new Level());
    m_level->LoadFromFile("data/" + m_level_name + ".lvl");
    if (!m_level->GetLoaded()) {
        m_level_name = "1";
        m_level->LoadFromFile("data/" + m_level_name + ".lvl");
    }
  

Kiedy gracz przejdzie wybrany przez siebie poziom, to aplikacja powinna przełączyć się na zapamiętany w m_next_app_state stan LevelChoiceScreen. Wspomniany warunek sprawdzany jest w Game::Update dokąd to kierujemy nasze kroki i zamieniamy

1
2
3
4
5
6
7
8
9
10
bool Game::Update(double dt) {
    // czy gracz zakończył aktualny poziom
    if (m_player->HasCompletedCurrentLevel()) {
        GamePtr g(new Game(m_next_level_name, m_player));
        m_next_app_state = g;
 
        SetDone();
        return IsDone();
    }
  

na

1
2
3
4
5
6
7
8
9
10
bool Game::Update(double dt) {
    // czy gracz zakończył aktualny poziom
    if (m_player->HasCompletedCurrentLevel()) {
        m_level_choice_screen->SetPlayer(m_player);
        m_next_app_state = m_level_choice_screen;
 
        SetDone();
        return IsDone();
    }
  
0
Twoja ocena: Brak

Copyright © 2008-2010 Wrocławski Portal Informatyczny

design: rafalpolito.com