Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?
Autorzy: Piotr Szawdyński, pekfos
Biblioteki C++

Przemieszczanie, skalowanie i obracanie sprajtów

[lekcja] Rozdział 10. Modyfikowanie położenia, obracanie oraz zmienianie rozmiaru sprajta.

Wprowadzenie

W poprzednim rozdziale dowiedziałeś się w jaki sposób wczytuje się tekstury oraz jak umieszcza się sprajta na scenie. W niniejszym rozdziale skupimy się na ustawianiu położenia sprajta, jego obracaniu oraz skalowaniu.

Budowa klasy sf::Sprite

Mając utworzony obiekt typu sf::Sprite oraz skojarzoną z obiektem teksturę, masz w praktyce przygotowany kod źródłowy do eksperymentów związanych z klasą sf::Sprite. Zanim jednak zapoznasz się z interesującymi Ciebie aspektami, warto najpierw dowiedzieć się trochę na temat budowy komponentów biblioteki SFML, a w szczególności poznać dokładnie klasę sf::Sprite. Klasa sf::Sprite dziedziczy po innych klasach, tj. po klasie sf::Drawable oraz po klasie sf::Transformable.

Klasa nadrzędna sf::Drawable

Jak już się dowiedziałeś w poprzednim rozdziale, klasa sf::Drawable dostarcza uniwersalny interfejs, umożliwiający rysowanie wszystkich obiektów graficznych na scenie w jednakowy sposób. Deklaracja metody wirtualnej, odpowiedzialnej za rysowanie obiektów zawarta jest więc w klasie sf::Drawable natomiast jej implementacja znajduje się w klasie sf::Sprite, która wie, w jaki sposób powinien być rysowany sprajt.

Klasa nadrzędna sf::Transformable

Druga klasa, tj. klasa sf::Transformable dostarcza interfejs związany z modyfikacją cech obiektu, nazywanych przekształceniami. Przez przekształcenia rozumie się takie aspekty jak: zmiana położenia obiektu, zmiana kąta obrotu obiektu, ustawianie centralnego punktu obiektu (wokół którego obiekt ma być obracany) oraz skalowanie. Klasa sf::Transformable posiada również kilka innych narzędzi, wykorzystywanych głównie przez wewnętrzne mechanizmy biblioteki SFML oraz czasami przez programistów na wyższym poziomie wtajemniczenia, czyli tych którzy posiadają szerszą wiedzę związaną z mechanizmami przekształcania sceny. W każdym razie najważniejszą informacją dla Ciebie jest fakt, że klasa sf::Transformable dostarcza narzędzia umożliwiające modyfikowanie położenia sprajta na scenie. Tym samym, omawiając wszelkie narzędzia do zmiany położenia sprajta, jego obrotu czy też skalowania, omawiana będzie w rzeczywistości klasa sf::Transformable, która dzięki zastosowaniu dziedziczenia sprawia wrażenie, że jest integralną częścią klasy sf::Sprite.

Fragment kodu pomijany w przykładach

Aby łatwiej Ci się analizowało kod znajdujący w dalszej części niniejszego rozdziału, zamieszczam kluczowy fragment kodu źródłowego:
C/C++
sf::Texture tekstura;
tekstura.loadFromFile( "box.jpg" );

sf::Sprite sprajt; //INFO: zwróć uwagę, że obiekt 'sprajt' jest typu sf::Sprite
sprajt.setTexture( tekstura );

Przemieszczanie sprajta

Klasa sf::Sprite posiada kilka metod umożliwiających modyfikowanie położenia obiektu. Tymi metodami są:
C/C++
void setPosition( float x, float y );
void setPosition( const sf::Vector2f & position );

void move( float offsetX, float offsetY );
void move( const sf::Vector2f & offset );
Jak już wiesz, deklaracja oraz implementacja wspomnianych metod znajduje się w klasie sf::Transformable, jednak można z nich swobodnie korzystać z poziomu obiektu typu sf::Sprite dzięki zastosowanemu mechanizmowi dziedziczenia.

Ustawianie pozycji obiektu - metoda setPosition

Pierwsze dwie metody tj. metody setPosition umożliwiają ustawienie położenia obiektu na scenie. Naszym obiektem jest sprajt, więc napisanie:
C/C++
sprajt.setPosition( 200, 100 );
spowoduje, że sprajt zostanie umieszczony na scenie na pozycji x=200 oraz y=100. Ten sam efekt uzyskamy wywołując drugą metodę setPosition w następujący sposób:
C/C++
sprajt.setPosition( sf::Vector2f( 200, 100 ) );
Obie zaprezentowane metody działają dokładnie tak samo, jednak czasami jeden zapis w danej sytuacji może być wygodniejszy od drugiego, stąd też do dyspozycji mamy dwie metody wykonujące tę samą operację.

Przesuwanie obiektu - metoda move

Kolejne dwie metody tj. metody move umożlwiają przesuwanie obiektu względem jego aktualnej pozycji. Tym samym, jeżeli obiekt będzie miał początkową pozycję np. x=60 oraz y=10 to wywołanie metody w następujący sposób:
C/C++
sprajt.move( 30, - 20 );
spowoduje, że sprajt zostanie przesunięty na pozycję x=60+30=90 oraz y=10-20=-10. Tak samo jak w przypadku metody setPosition istnieją dwie metody move realizujące tę samą operację, ale przyjmującą wartości w odmienny sposób. Operacja analogiczna do tej, która została przedstawiona powyżej, będzie wyglądała następująco:
C/C++
sprajt.move( sf::Vector2f( 30, - 20 ) );

Obracanie sprajta

Klasa sf::Sprite odziedziczyła po sf::Transformable kilka metod pomocnych przy obracaniu obiektu:
C/C++
void sf::Transformable::setRotation( float angle );
void sf::Transformable::rotate( float angle );

float sf::Transformable::getRotation() const;
Kąt podajemy w stopniach.

Ustawianie obrotu - metoda setRotation

Metoda setRotation ustawia kąt obrotu obiektu na scenie względem oryginalnego położenia.
C/C++
sprajt.setRotation( 60 );
Powyższe wywołanie spowoduje, że sprajt zostanie obrócony o 60 stopni.

Aktualny kąt - metoda getRotation

Metoda getRotation zwraca aktualny kąt obrotu obiektu. Dla 'świeżego' obiektu, aktualny kąt wynosi 0.
C/C++
sf::Sprite sprajt2;
sprajt2.getRotation(); //0

Obracanie obiektu - metoda rotate

Metoda rotate ustawia kąt obrotu względem poprzedniego położenia.
C/C++
sprajt.rotate( 15 );
Zauważ, że powyższy zapis jest równoznaczny z następującym:
C/C++
sprajt.setRotation( sprajt.getRotation() + 15 );

Skalowanie sprajta

Klasa sf::Sprite posiada następujące metody do skalowania:
C/C++
void setScale( float factorX, float factorY );
void setScale( const Vector2f & factors );

void scale( const Vector2f & factor )
void scale( float factorX, float factorY );

const Vector2f & getScale() const;
Jak można zauważyć, SFML pozwala na modyfikowanie wysokości i szerokości obiektu niezależnie od siebie.

Ustawianie skali - metody setScale

setScale ustawia skalowanie obiektu względem oryginalnych rozmiarów.
C/C++
sprajt.setScale( 1, 2 );
sprajt.setScale( sf::Vector2f( 0.5, 0.5 ) );
W pierwszej linii szerokość sprajta pozostaje bez zmian, a wysokość jest 2 razy większa. W drugiej, szerokość i wysokość są 2 razy mniejsze.

Aktualna skala - metoda getScale

Metoda getScale zwraca aktualną skalę w formie obiektu sf::Vector2f. Domyślna skala to 1, 1.

Modyfikowanie skali - metody scale

Metody scale skalują poprzednio wyskalowany obiekt.
C/C++
sprajt.setScale( 1, 2 );
sprajt.scale( 2, 1 );
sprajt.scale( sf::Vector2f( 0.5, 0.5 ) );
Po wykonaniu tego kodu, obraz będzie w naturalnych rozmiarach, ponieważ 1 * 2 * 0.5 = 1.
Oba poniższe zapisy są równoważne:
C/C++
sprajt.scale( 2, 3 );
sprajt.setScale( sprajt.getScale().x * 2, sprajt.getScale().y * 3 );

Środek obiektu

Do ustawiania i pobierania środka obiektu służą poniższe metody:
C/C++
void setOrigin( float x, float y );
void setOrigin( const sf::Vector2f & origin );

sf::Vector2f getOrigin();
Punkt ten, jest osią obrotu i punktem zaczepienia przy ustawianiu położenia. Domyślnie środkiem obiektu jest jego lewy górny róg.

Przykład

C/C++
#include <SFML/Graphics.hpp>

int main()
{
    sf::RenderWindow oknoAplikacji( sf::VideoMode( 640, 480, 32 ), "Kurs SFML - http://cpp0x.pl" );
   
    sf::Texture tekstura;
    tekstura.loadFromFile( "box.jpg" );
    sf::Sprite obrazek;
    obrazek.setTexture( tekstura );
   
    while( oknoAplikacji.isOpen() )
    {
        sf::Event zdarzenie;
        while( oknoAplikacji.pollEvent( zdarzenie ) )
        {
            if( zdarzenie.type == sf::Event::Closed )
                 oknoAplikacji.close();
           
            if( zdarzenie.type == sf::Event::KeyPressed && zdarzenie.key.code == sf::Keyboard::Escape )
                 oknoAplikacji.close();
           
            if( zdarzenie.type == sf::Event::MouseButtonPressed && zdarzenie.mouseButton.button == sf::Mouse::Middle )
                 oknoAplikacji.close();
           
        }
        oknoAplikacji.clear( sf::Color::Black );
       
        obrazek.setOrigin( 20, 20 ); //INFO: dopisane w tym rozdziale
        obrazek.setPosition( 100, 80 ); //INFO: dopisane w tym rozdziale
        obrazek.setRotation( 30 ); //INFO: dopisane w tym rozdziale
        obrazek.setScale( 1.2, 0.8 ); //INFO: dopisane w tym rozdziale
       
        oknoAplikacji.draw( obrazek );
        oknoAplikacji.display();
    }
    return 0;
}

Podsumowanie

W niniejszym rozdziale nauczyłeś się w jaki sposób można przemieszczać, obracać i skalować obiekty w bibliotece SFML 2.0. Wiedzę, którą zdobyłeś w ramach niniejszego kursu SFML możesz spokojnie zacząć wykorzystywać do pisania prostych jak również bardziej złożonych gier 2D. Kolejne rozdziały niniejszego kursu SFML będą zawierały porady dla osób, które mają już dobrze opanowaną bibliotekę SFML 2.0.
Poprzedni dokument Następny dokument
Wczytywanie tekstur i rysowanie sprajtów Dodatkowe materiały