Arkanoid 3D krok po kroku III

02.08.2010 - Olgierd Humeńczuk
TrudnośćTrudność

Aktorzy

Jak powiedzieliśmy w poprzednim rozdziale, aktor jest elementem sceny naszej gry. Będziemy mieli do czynienia z aktorami o różnych własnościach, np. niektórzy z nich będą mogli się poruszać, inni nie. Niektórymi z nich sterował będzie gracz, inni będą poruszali się w sposób niekontrolowany przez gracza bezpośrednio. Dla każdego rodzaju aktora będziemy jednak potrzebowali pewnego zbioru wspólnych danych. Wypunktujmy je:

  • identyfikator - unikatowy identyfikator obiektu
  • typ obiektu
  • pozycja
  • kierunek w którym przemieszcza się aktor
  • predkosc poruszania sie aktora

Znamy już dane, których potrzebować będziemy dla każdego rodzaju obiektu. Zaimplementujmy zatem strukturę, która je zawiera.

Zaczniemy od zdefiniowania wszystkich typów obiektów, jakie zidentyfikowaliśmy do tej pory:

1
2
3
4
5
6
7
8
9
10
11
12
13
/// typy obiektow gry
enum objectTypes
{
    OBJECT_TYPE_UNSET = 0,  //obiekt niezainicjalizowany
    OBJECT_TYPE_PLANE,      //plaszczyzna tworzaca plansze
    OBJECT_TYPE_WALL_N,     //sciana polnocna wyznaczajaca granice planszy
    OBJECT_TYPE_WALL_EW,    //sciany wschodnia i zachodnia - granice planszy
    OBJECT_TYPE_BALL,       //kula
    OBJECT_TYPE_PADDLE,     //rakietka za pomoca ktorej gracz odbija kule
    OBJECT_TYPE_BRICK,      //cegla ktora nalezy rozbic za pomoca kuli
 
    OBJECT_TYPE_COUNT       //liczba wszystkich zdefiniowanych obiektow
};

Definicja wspomnianej wcześniej struktury, zawierającej dane, wspólne dla wszystkich typów obiektów:

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/**
 * @struct baseSceneObject
 * @brief struktura zawierajaca podstawowe informacje o obiekcie
 */
struct baseSceneObject
{
    /**
     * @brief domyslny konstruktor
     */
    baseSceneObject( void ) :
              position( vector3f( .0f, .0f, .0f ) )
            , objectType( OBJECT_TYPE_UNSET )
            , selfId( -1 )
    { }
 
    /**
     * @brief konstruktor ustawiajacy podane wartosci
     * @param pos pozycja obiektu
     * @param objType typ obiektu
     * @param matId identyfikator materialu
     */
    explicit baseSceneObject(
          int32_t objId
        , const vector3f& pos
        , const vector3f& _dir
        , float vel
        , objectTypes objType ) :
              position( pos )
            , objectType( objType )
            , dir( _dir )
            , velocity( vel )
            , selfId( objId )
    { }
 
    /**
     * @brief zwraca nadany wcześniej identyfikator
     */
    int32_t getId( void ) const
    {
        return selfId;
    }
 
    /// pozycja obiektu
    vector3f    position;
 
    /// typ obiektu
    objectTypes objectType;
 
    /// kierunek poruszania sie aktora
    vector3f    dir;
 
    /// jego predkosc
    float       velocity;
 
private:
    /// prywatny identyfikator obiektu
    int32_t     selfId;
};

Zarządzanie aktorami

Nasze obiekty, reprezentujące aktorów sceny gry, są tylko nośnikiem informacji. Potrzebujemy jeszcze obiektu zarządzającego sceną i jej obiektami. Wypiszmy więc, za co odpowiadać będzie ów obiekt:

  • dodawanie nowych aktorów do sceny
  • usuwanie istniejących aktorów ze sceny
  • wyświetlanie dodanych wcześniej aktorów
  • aktualizację pozycji aktorów
  • wykrywanie kolizji między aktorami

Napiszmy zatem definicję klasy zarządcy, realizujacą wymienione zadania:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
 * @class sceneManager
 */
template< typename T >
class sceneManager
{
    public: // public typedefs
        typedef std::map< int32_t, baseSceneObject > sceneObjectsContainer;
 
    public:
        /**
         * @brief Domyslny konstruktor
         * Inicjalizuje materialy i siatki aktorow
         */
        sceneManager( void ) : ids( 0 )
        {
            initializeMaterials();
            initializeMeshes();
        }

Konstruktor klasy wywołuje jedynie dwie metody pomocnicze, które wypełnią danymi tablice zawierające dane materiałów i siatek aktorów.

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
27
28
29
30
        /**
         * @brief Dodaje do sceny obiekt o podanym typie
         * @param objType
         * @param pos
         * @return identyfikator nadany obiektowi
         */
        int32_t addSceneObject(
              const objectTypes& objType
            , const vector3f& pos
            , const vector3f& dir = vector3f()
            , float vel = 0.0f
            , const vector3f& orient = vector3f() )
        {
            int32_t newId = ids++;
 
            //warunek wstępny
            assert( sceneObjects.find( newId ) == sceneObjects.end() );
 
            sceneObjects.insert( sceneObjectsContainer::value_type( newId
                , baseSceneObject
                  (
                      newId
                    , pos
                    , dir 
                    , vel
                    , objType
                  ) ) );
 
            return newId;
        }

Metoda addSceneObject umożliwia dodanie do sceny nowego aktora. Tworzy ona obiekt typu baseSceneObject a następnie zapamiętuje go w mapie wszystkich obiektów - aktorów.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
        /**
         * @brief Usuwa ze sceny obiekt o podanym id
         * @param objId
         */
        void removeSceneObject( int32_t objId )
        {
            sceneObjectsContainer::iterator it = sceneObjects.find( objId );
 
            if( it != sceneObjects.end() )
            {
                sceneObjects.erase( it );
            }
            else
            {
                std::ostringstream e;
                e << "Scene object of id=";
                e << objId;
                e << " does not exists in scene container.";
                throw std::logic_error( e.str() );
            }
        }

Analogicznie do metody addSceneObject metoda removeSceneObject usuwa aktora o podanym identyfikatorze ze sceny. Ta metoda przyda nam się do usuwania zniszczonych przez gracza klocków.

5
Twoja ocena: Brak Ocena: 5 (2 ocen)

Copyright © 2008-2010 Wrocławski Portal Informatyczny

design: rafalpolito.com