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

25.08.2010 - Marcin Milewski
TrudnośćTrudność

Plik z implementacją klasy LevelChoiceScreen

Mając deklarację klasy LevelChoiceScreen, zabierzemy się teraz za implementowanie jej metod. Na początku dołączamy kilka niezbędnych nagłówków:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <SDL/SDL_opengl.h>
#include <boost/assign/std/vector.hpp>     // operator+=()
#include <boost/assign/list_inserter.hpp>  // insert()
#include <cmath>      // fabs
#include <algorithm>  // find
#include <iostream>
 
#include "Engine.h"
#include "LevelChoiceScreen.h"
#include "MainMenu.h"
#include "Game.h"
#include "Sprite.h"
#include "SpriteConfig.h"
#include "Text.h"
  

W konstruktorze najpierw uzupełniamy listę inicjalizacyjną podając wartości początkowe dla poszczególnych pól klasy. Zwróćmy uwagę, że wielkość kafli na ekranie nie jest narzucona przez klasę Renderer. Dzięki temu możemy różne ekrany wyświetlać z ich różnym rozmiarem, co czyni klasę Renderer bardzo elastyczną.
A oto lista inicjalizacyjna konstruktora klasy LevelChoiceScreen:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
LevelChoiceScreen::LevelChoiceScreen(PlayerPtr player) :
    m_face_pos(0, 0),
    m_current_from_node(0),
    m_current_to_node(0),
    m_horizontal_road_sprite(),
    m_vertical_road_sprite(),
    m_entry_enabled_sprite(),
    m_entry_disabled_sprite(),
    m_face_sprite(),
    m_tile_width(1.0 / 15),
    m_tile_height(1.0 / 15),
    m_player(player),
    m_next_app_state() {
  

Następnie określamy graf połączeń, który wygląda następująco:

Przykładowy graf połączeń zdefiniowany w konstruktorze klasy LevelChoiceScreen.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    srand(time(0));
 
    using namespace boost::assign;
    m_connections += IntVector(), IntVector(), IntVector(), 
                     IntVector(), IntVector();
    m_connections.at(0) += 1;
    m_connections.at(1) += 2, 0;
    m_connections.at(2) += 3, 4, 1;
    m_connections.at(3) += 2;
    m_connections.at(4) += 2;
 
    // zdefiniuj odwzorowanie (aka mapowanie)  węzeł->nazwa poziomu
    insert(m_node_to_level_name)(0, "1")(1, "2")(2, "3")(3, "4")(4, "5");
 
    // pozycje wierzchołków
    m_positions += Point(.1, .7), Point(.7, .7), Point(.7, .4), 
                   Point(.3, .4), Point(.7, .1);
 
    // pozycja postaci (w miejscu pierwszego węzła)
    m_face_pos = m_positions.at(0);
  

Implementujemy metody Init, Start oraz destruktor. Ponieważ pierwsza z nich wymaga ustawienia flagi is_done na false, to trzeba dokonać prostego rozszerzenia w klasie bazowej (czyli AppState). Zwróćmy uwagę, że ta metoda jest wykorzystywana w wielu innych klasach. Dlatego zmiana powinna być dla nich możliwie niezauważalna. W tym przypadku wystarczy dać domyślną wartość argumentowi metody SetDone. Oto zmieniony kod oraz implementacja metod Init, Start oraz ~LevelChoiceScreen:

1
2
3
4
5
6
    // zmieniona metoda AppState::SetDone. Plik AppState.h
 
    void SetDone(bool value=true) {
        m_is_done = value;
    }
  
1
2
3
4
5
6
7
8
9
10
11
12
13
// Plik LevelChoiceScreen.cpp
 
LevelChoiceScreen::~LevelChoiceScreen() {
}
 
void LevelChoiceScreen::Init() {
    m_next_app_state.reset();
    SetDone(false);
}
 
void LevelChoiceScreen::Start() {
}
  

Teraz przejdziemy do omawiania najważniejszych części implementacji nowego stanu, jakim jest LevelChoiceScreen. Napiszemy metody odpowiedzialne za aktualizowanie wszystkich elementów, ich rysowanie, a następnie obsługujące zdarzenia przychodzące z klawiatury.

0
Twoja ocena: Brak

Copyright © 2008-2010 Wrocławski Portal Informatyczny

design: rafalpolito.com