Gra 2D, część 14: Lepszy respawn i kilka szczegółów

01.10.2012 - Marcin Milewski
TrudnośćTrudność

W tym artykule zmienimy prymitywny sposób wyboru pozycji bohatera po utracie życia. Dokonamy także kilku zmian podnoszących przyjemność płynącą z gry w naszą platformówkę.

Poprzedni artykuł - Edytor poziomów cz. 3 Następny artykuł - Kłody pod nogi

Kod źródłowy, który będziemy modyfikować w tym artykule można znaleźć tutaj.

Dostęp do edytora z menu głównego

Zaczniemy od dodania opcji do menu głównego, dzięki czemu będziemy mogli szybko przejść do edytora i zacząć tworzyć kolejny poziom. W kilku poprzednich artykułach rozwijaliśmy edytor poziomów, więc wygodne było, aby program przy starcie od razu włączał tryb edycji. Teraz chcemy, aby po uruchomieniu pokazywało się menu główne. Dlatego po kodzie ładującym grafikę umieszczamy fragment ustawiający menu jako początkowy stan programu.

1
2
3
4
5
6
7
8
9
10
// Plik: App.cpp, metoda Run
    // ładowanie atlasu
    const std::string atlas_filename = "data/tex.png";
    Engine::Get().GetRenderer()->LoadTexture(atlas_filename);
 
    // stanem początkowym jest menu
    m_app_state.reset(new MainMenu());
 
    m_app_state->Init();
    m_app_state->Start();  

Kod odpowiedzialny za uruchamianie edytora przenosimy do metody MainMenu::ProcessEvents. Oczywiście obsługa tej akcji wymaga dodania typu odpowiedzialnego za opcję "Edytor" (Sel::Editor).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Plik: MainMenu.cpp, metoda ProcessEvents
#include "Level.h"
#include "editor/Editor.h"
// (..)
        else if (event.key.keysym.sym == SDLK_RETURN) {
            // (...)
            else if (m_selection == Sel::Editor) {
                LevelPtr level(new Level());
                level->LoadFromFile("data/new.lvl");
                EditorPtr editorState(new Editor(level));
                tefPtr fadeout = TransitionEffect::PreparePinWheelOut()
                                   .states(shared_from_this(),editorState)
                                   .duration(1.0)
                                   .blades(2)
                                   .delay(0, .2)
                                   .Build();
                m_next_app_state = fadeout;
            }
            // (...)  

Właściwym miejscem do umieszczenia Sel::Editor jest plik MainMenu.h

1
2
3
4
5
6
7
8
// Plik MainMenu.h
        enum Selection {
            None,
            NewGame,
            HallOfFame,
            Editor,          // NOWE
            Quit
        };  

Możemy skompilować nasz kod i... Hej, ale jak przejść do edytora? ;) Rzeczywiście, do tej pory edytor uruchamiany był automatycznie przy starcie, więc w menu brakuje potrzebnej nam opcji. Jej obsługę (czyli wyświetlenie odpowiedniego napisu oraz prostokąta z zaznaczeniem) umieszczamy w MainMenu.cpp w metodzie Draw.
Aktualnie, pozycje menu mają następującą kolejność: "Nowa gra", "Hall of Fame", "Wyjście". Opcję "Edytor" umieszczamy między "Hall of Fame" a " Wyjście". Aktualizacji wymaga także pozycja wyświetlania zaznaczenia ostatniej z opcji, gdyż teraz będzie ona wyświetlana niżej (tj. pod opcją "Edytor").
Gwiazdki na początku wiersza oznaczają, że został on zmieniony.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// Plik: MainMenu.cpp, metoda Draw
    Text t(0.1, 0.1);
    t.DrawText("menu", 0.3, 0.8);
 
    if (m_selection == Sel::NewGame) {
        Engine::Get().GetRenderer()->DrawQuad(0.3, 0.59, 0.72, 0.66,
                                             .3, 0.8, 0.2, .5);
    }
    else if (m_selection == Sel::HallOfFame) {
        Engine::Get().GetRenderer()->DrawQuad(0.2, 0.49, 0.82, 0.56,
                                              .3, 0.8, 0.2, .5);
    }
    else if (m_selection == Sel::Editor) {                              // NOWE
        Engine::Get().GetRenderer()->DrawQuad(0.35, 0.39, 0.67, 0.46,   // NOWE
                                              .3, 0.8, 0.2, .5);        // NOWE
    }                                                                   // NOWE
    else if (m_selection == Sel::Quit) {
*       Engine::Get().GetRenderer()->DrawQuad(0.325, 0.29, 0.695, 0.36,
                                              .3, 0.8, 0.2, .5);
    }
 
    t.SetSize(0.05, 0.05);
    t.DrawText("nowa gra", 0.31, 0.6);
    t.DrawText("hall of fame", 0.21, 0.5);
    t.DrawText("edytor", 0.36, 0.4);           // NOWE
*   t.DrawText("wyjscie", 0.335, 0.3);         // 0.4 zmieniona na 0.3 
Nowa opcja w menu głównym.

Został jeszcze mały szczegół -- powrót z edytora do menu. Otwieramy plik editor/Editor.cpp i wyszukujemy w nim słowo kluczowe SDLK_ESCAPE. Następnie dodajemy wpis mówiący o przejściu do menu oraz dołączamy plik MainMenu.h, w którym znajduje się deklaracja klasy MainMenu.

1
2
3
4
5
6
7
8
9
10
11
12
// Plik: editor/Editor.cpp
#include "../MainMenu.h"
// (...)
 
    if (m_keys_down[SDLK_ESCAPE]) {
        m_next_app_state.reset(new MainMenu);          // NOWE
        SetDone(true);
    } else if (m_keys_down[SDLK_LEFT]) {
        m_viewer_offset_x -= dt * 28.19;
    } else if (m_keys_down[SDLK_RIGHT]) {
        m_viewer_offset_x += dt * 28.24;
    }  

Możemy skompilować kod i zobaczyć, że nowa funkcjonalność działa dobrze. Jeżeli uznamy, że prostokąt zaznaczający wyświetla się w złym miesjcu lub jest niewłaściwych rozmiarów, to należy dobrać (metodą prób i błędów) inne parametry w metodzie MainMenu::Draw.

0
Twoja ocena: Brak

Copyright © 2008-2010 Wrocławski Portal Informatyczny

design: rafalpolito.com