Gra 2D, część 11: Edytor poziomów cz. 1

15.03.2011 - Marcin Milewski
TrudnośćTrudność

Drobne zmiany w Game

Klasa Game nie wymaga dużych zmian, raczej drobnych usprawnień. Pierwszym z nich jest wyłączenie dźwięku odgrywanego w momencie zakończenia poziomu. Jeżeli po opuszczeniu gry muzyczka wciąż będzie aktywna, to użytkownik odniesie wrażenie, że coś jest nie tak (gra zawiera błąd). Szczególnie jeżeli będzie przełączał się między grą a edytorem. Zmiana jest naprawdę prosta. Wyłączamy muzykę w destruktorze, a do klasy Sound dopisujemy odpowiednią metodę:

1
2
3
4
5
6
7
// Plik: Game.cpp
(...)
Game::~Game() {
    Engine::Get().GetSound()->HaltMusic();
}
(...)
  
1
2
3
4
5
6
7
// Plik: Sound.cpp    
(...)
void Sound::HaltMusic() {
    Mix_HaltMusic();
}
(...)
  
1
2
3
4
5
6
7
8
9
10
11
12
// Plik: Sound.h
(...)
    void PlayMusic(const std::string& name);
    void PlaySfx(const std::string& name);
 
    void HaltMusic();         // NOWE
 
private:
    void LoadMusic(const std::string& name, const std::string& filename);
    void LoadSfx(const std::string& name, const std::string& filename);
(...)
  

Klasę Game wzbogacamy ponadto o nowy konstruktor tak, aby jej instancję można było utworzyć na podstawie obiektów już istniejących w pamięci. Różnica w porównaniu z poprzednim konstruktorem polega na tym, że w inny sposób wczytujemy dane klasy Level. Stary konstruktor wymagał obiektu klasy std::string wymuszając tym samym ładowanie go z dysku. Nowa, dodatkowa wersja pozwala korzystać z poziomu, który już jest w pamięci. Poniżej prezentujemy oba konstruktory:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Plik: Game.h
(...)
class Game : public AppState, public boost::enable_shared_from_this<Game> {
public:
    explicit Game(const std::string& level_name, PlayerPtr player) 
        : m_player(player),
          m_stored_player_pos_x(9.0),
          m_level_name(level_name)  {
    }
    explicit Game(LevelPtr level, PlayerPtr player) 
        : m_player(player),
          m_level(level),
          m_stored_player_pos_x(9.0),
          m_level_name(level->GetName())  {
    }
 
    ~Game();
 
    void Start();
(...)
  

Ponieważ mamy możliwość utworzenia instancji klasy Game na podstawie obiektu klasy Level, to musimy zadbać aby podczas inicjalizowania gry nie został on nadpisany poziomem wczytanym z pliku. Odpowiednia zmiana polega na modyfikacji kodu:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void Game::Init() {
    Engine& engine = Engine::Get();
 
    // ł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");
    }
 
    // załaduj jednostki do poziomu
    m_level->LoadEntitiesFromFile("data/" + m_level_name + ".ents");
    m_entities_to_create = m_level->GetAllEntitiesToCreate();
  

na:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void Game::Init() {
    Engine& engine = Engine::Get();
 
    if (!m_level) {
        // ł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");
        }
        // załaduj jednostki do poziomu
        m_level->LoadEntitiesFromFile("data/" + m_level_name + ".ents");
    }
    m_entities_to_create = m_level->GetAllEntitiesToCreate();
  
0
Twoja ocena: Brak

Copyright © 2008-2010 Wrocławski Portal Informatyczny

design: rafalpolito.com