Gra 2D, część 13: Edytor poziomów cz. 3

02.06.2011 - Marcin Milewski
TrudnośćTrudność

Implementacja TileGridHelper: przekształcanie punktów względem siatki

Przed chwilą napisaliśmy kod, który korzysta z klasy TileGridHelper. Poniżej prezentujemy deklarację tej klasy:

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
// Plik: TileGridHelper.h
#ifndef TILEGRIDHELPER_H
#define TILEGRIDHELPER_H
 
#include "StdAfx.h"
#include "BasicMathTypes.h"
 
class TileGridHelper {
public:
    explicit TileGridHelper(const Position& beg, const Position& end);
 
    // Przyciąga podany punkt do najbliższego punktu siatki
    TileGridHelper& SnapToGrid();
 
    // Zmienia współrzędne podanych punktów tak, że w beg znajdują się
    // minimalne (lewy dolny narożnik), a w end maksymalne (prawy górny narożnik).
    TileGridHelper& SortCoordsOfBox();
 
    // Wymagają posortowanych współrzędnych
    unsigned TilesHorizontally() const;
    unsigned TilesVertically() const;
 
    Position Beg() const { return m_beg; }
    Position End() const { return m_end; }
 
private:
    Position m_beg, m_end;
};
 
#endif
  

Następnie przyjrzyjmy się jej definicji. Każda z metod ma dobrze określone, konkretne zadanie. Dzięki temu ich implementacja jest prosta oraz (jeżeli ktoś ma ochotę) łatwa do testowania. Przekazane w konstruktorze punkty zapamiętujemy w polach klasy:

1
2
3
4
5
6
7
// Plik: TileGridHelper.cpp
#include "TileGridHelper.h"
 
TileGridHelper::TileGridHelper(const Position& beg, const Position& end)
    : m_beg(beg), m_end(end) {
}
  

Metoda SnapToGrid zaokrągla każdą ze współrzędnych obu punktów. Dlaczego tak jest dobrze? Dlatego, że punkty przekazane w konstruktorze pochodzą z przestrzeni świata. To znaczy, że punkt (3,14; 8,0) oznacza ósmy (tak naprawdę dziewiąty, bo pierwszy kafelek jest definiowany przez punkt (0,0)) kafelek w pionie oraz nieco ponad trzeci w poziomie. Zaokrąglając wartość każdej współrzędnej otrzymujemy punkt oznaczający początek (czyli lewy dolny narożnik) najbliższego kafelka. Ponadto metoda zwraca referencję do instancji, na rzecz której została wywołana. Pozwala to na łańcuchowe wywoływanie metod (ang. method chaining).

1
2
3
4
5
6
7
// Plik: TileGridHelper.cpp
TileGridHelper& TileGridHelper::SnapToGrid() {
    m_beg = Position(round(m_beg.X()), round(m_beg.Y()));
    m_end = Position(round(m_end.X()), round(m_end.Y()));
    return *this;
}
  

Kolejną, równie prostą w implementacji funkcją jest SortCoordsOfBox. Jak podawaliśmy wcześniej, dla dowolnych dwóch punktów określających prostokąt, modyfikuje je ona tak, aby m_beg oraz m_end oznaczały odpowiednio lewy dolny oraz prawy górny narożnik prostokąta. Podobnie jak SnapToGrid, ta metoda również zwraca referencję do TileGridHelper.

1
2
3
4
5
6
7
8
9
10
// Plik: TileGridHelper.cpp
TileGridHelper& TileGridHelper::SortCoordsOfBox() {
    Position orga = m_beg, orgb = m_end;
    m_beg[0] = std::min(orga.X(), orgb.X());
    m_end[0] = std::max(orga.X(), orgb.X());
    m_beg[1] = std::min(orga.Y(), orgb.Y());
    m_end[1] = std::max(orga.Y(), orgb.Y());
    return *this;
}
  

Do zaimplementowania pozostały metody zwracające rozmiar prostokąta wyrażony w kafelkach w poziomie oraz pionie. Ich implementacja polega na odjęciu odpowiednich współrzędnych przechowywanych punktów. Na wszelki wypadek wykonujemy jeszcze zaokrąglenie. Oto omawiane metody:

1
2
3
4
5
6
7
8
unsigned TileGridHelper::TilesHorizontally() const {
    return static_cast<unsigned>(round(m_end[0] - m_beg[0]));
}
 
unsigned TileGridHelper::TilesVertically() const {
    return static_cast<unsigned>(round(m_end[1] - m_beg[1]));
}
  
0
Twoja ocena: Brak

Copyright © 2008-2010 Wrocławski Portal Informatyczny

design: rafalpolito.com