Rysujmy... Rysujmy.
Rysujmy! Tak! Rysujmy, ale nie w paincie i nie kredkami :) W tym rodziale zajmiemy się rysowaniem, malowaniem czy też jak to się przyjęło w świecie programistów wyświetlaniem sprajtów na ekranie :)
Co to jest sprajt i jak on działa w SFML?
Sprajt w bibliotece SFML jest to klasa za pomocą której mamy możliwość rysowania obrazów 2D na ekranie. Sprajt jest klasą 'lekką', czyli taką którą możemy beztrosko tworzyć dla każdego obiektu, który zechcemy wyświetlić bez ponoszenia istotnego kosztu pamięciowego jak również bez istotnej utraty na szybkości aplikacji. Sukces ten zawdzięczamy przede wszystkim konstrukcji klasy
Sprite, która zamiast kopiować obraz, który będzie wyświetlała - trzyma uchwyt do obrazu. Dzięki temu możliwe jest wielokrotne wyświetlenie tego samego obrazu na scenie minimalnym kosztem pamięciowym.
Tworzenie sprajta
Skoro podstawową wiedzę o sprajtach w SFML już masz to nic nie szkodzi na przeszkodzie aby się nauczyć pracować ze sprajtami. Zacznijmy najpierw od utworzenia pustego sprajta:
Obsługa sprajta
Klasa
Sprite dziedziczy po klasie
sf::Drawable, dostarczając tym samym serię metod które warto zapamiętać, bowiem często i gęsto będą się przydawały podczas wytwarzania gier. Metody o których mowa służą bowiem do ustalania położenia sprajta, obrotu, skalowania i innych cudów związanych z przekształcaniem obrazu, który ma być wyświetlany. Przytoczę tu te najczęściej używane, a resztę zawsze możesz doczytać sobie w dokumentacji. Oto one:
Dokumentacja |
---|
SetX | Ustawia nowe położenie sprajta w osi X. (metoda) |
---|
SetY | Ustawia nowe położenie sprajta w osi Y. (metoda) |
---|
SetPosition | Ustawia nowe położenie sprajta. (metoda) |
---|
SetRotation | Ustawia nowy kąt o jaki ma być obrócony obiekt. (metoda) |
---|
SetCenter | Ustawia nową pozycję środka obiektu. (metoda) |
---|
SetScaleX | Ustawia mnożnik przeskalowania sprajta w osi X. (metoda) |
---|
SetScaleY | Ustawia mnożnik przeskalowania sprajta w osi Y. (metoda) |
---|
SetScale | Ustawia mnożniki przeskalowania obiektu w osiach X i Y. (metoda) |
---|
Move | Przesuwa sprajta na nową pozycję względem aktualnego położenia. (metoda) |
---|
Rotate | Obraca obiekt o kąt wyrażony w stopniach. (metoda) |
---|
Pełną listę metod znajdziesz w dokumentacji klasy
Sprite. O powyższych funkcjach warto poczytać oczywiście w dokumentacji byś mógł poczuć się w pełni usatysfakcjonowany, niemniej jednak teraz skupmy się na najważniejszym aspekcie, tj. na narysowaniu obrazka na ekranie :)
Skojarzenie grafiki ze sprajtem
Zanim nasz sprajt z obrazkiem zostanie wyświetlony to najpierw wypadałoby skojarzyć jakąś grafikę ze sprajtem. Do tego celu należy wykorzystać metodę
SetImage należącą do klasy
Sprite. Za pomocą metody
SetImage przekazujemy obraz, który ma być skojarzony ze sprajtem.
Pamiętaj, że obraz musi być trzymany w pamięci tak długo jak długo chcemy go wyświetlać.
|
Rysowanie sprajta
W celu wyświetlenia przygotowanego wcześniej sprajta na ekranie należy wywołać metodę
Draw należącą do klasy
sf::RenderWindow. Metoda
Draw przyjmuje jako argument obiekt typu
sf::Drawable, a ponieważ klasa
Sprite dziedziczy właśnie po klasie
sf::Drawable to możliwe jest (i jest jak najbardziej prawidłowe) przekazanie obiektu typu
Sprite jako argument do metody
Draw. Wyświetlenie sprajta będzie więc wyglądało tak:
sf::Sprite naszSprajt;
oknoAplikacji.Draw( naszSprajt );
Przykład
Podsumujmy wiedzę, którą zebraliśmy do tej pory na temat sprajtów i zobaczmy jak będzie wyglądał przykład wyświetlający sprajta na ekranie:
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow oknoAplikacji( sf::VideoMode( 800, 600, 32 ), "Kurs SFML - http://cpp0x.pl" );
sf::Image obrazek;
obrazek.LoadFromFile( "ludek.png" );
sf::Sprite naszSprajt;
naszSprajt.SetImage( obrazek );
naszSprajt.SetPosition( 400, 300 );
naszSprajt.SetScale( 5, 5 );
while( oknoAplikacji.IsOpened() )
{
sf::Event zdarzenie;
while( oknoAplikacji.GetEvent( zdarzenie ) )
{
if( zdarzenie.Type == sf::Event::Closed )
oknoAplikacji.Close();
}
const sf::Input & sterowanie = oknoAplikacji.GetInput();
if( sterowanie.IsKeyDown( sf::Key::Left ) )
naszSprajt.Move( - 0.2, 0 );
if( sterowanie.IsKeyDown( sf::Key::Right ) )
naszSprajt.Move( + 0.2, 0 );
if( sterowanie.IsKeyDown( sf::Key::Up ) )
naszSprajt.Move( 0, - 0.2 );
if( sterowanie.IsKeyDown( sf::Key::Down ) )
naszSprajt.Move( 0, + 0.2 );
oknoAplikacji.Clear( sf::Color( 255, 0, 0 ) );
oknoAplikacji.Draw( naszSprajt );
oknoAplikacji.Display();
}
return 0;
}
Trochę więcej o sprajcie
Skoro mamy już jakieś podstawy na temat sprajtów i udało nam się wyświetlić obraz na ekranie to nie oznacza to wcale, że możemy zakończyć już naszą edukację na temat sprajtów w SFML. Warto bowiem poświęcić jeszcze trochę czasu aby zgłębić lepiej tajniki klasy
Sprite. Klasa ta jest bowiem naszym panaceum na wszelkie ewentualne problemy związane z wyświetlaniem grafiki.
Barwy i przeźroczystość sprajta
Jeżeli masz potrzebę zmienić sposób wyświetlania barw sprajta, bądź zmienić poziom jego przeźroczystości to z pomocą przyjdzie Ci metoda
SetColor. Umożliwia ona bowiem zmianę natężenia barw renderowanego sprajta jak również zmianę jego poziomu przeźroczystości. Dokumentacja, która jest dostępna na łamach niniejszego serwisu wyjaśnia wyczerpująco działanie metody
SetColor dlatego też pozwolę sobie w tym miejscu zakończyć jej opisywanie :)
Rzeczywista pozycja sprajta
Sprajt od chwili jego utworzenia do wyświetlenia ulega licznym transformacjom. Tymi transformacjami mogą być np. skala, położenie, zmiana punktu centralnego sprajta wokół którego dokonujemy jego obrotu czy też sam obrót. O ile takie zachowanie jest dla nas naturalne i oczekiwane to czasem zachodzi potrzeba ustalenia czy np. kursor myszy znajduje się nad obracanym obiektem czy też nie. Samodzielne obliczanie pozycji faktycznej pozycji sprajta byłoby uciążliwe i z pewnością mało praktyczne. Twórcy biblioteki SFML przewidzieli to i utworzyli do tego celu metody, które dokonają takich obliczeń za nas. Tymi metodami są:
Dokumentacja |
---|
TransformToGlobal | Konwertuje lokalne współrzędne do golbalnych współrzędnych. (metoda) |
---|
TransformToLocal | Konwertuje globalne współrzędne do lokalnych współrzędnych. (metoda) |
---|
Jeżeli będziemy chcieli ustalić czy nad sprajtem znajduje się kursor myszy to wystarczy, że dokonamy odpowiedniej transformacji za pomocą jednej z powyższych metod. Przykładowy kod może wyglądać tak:
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow oknoAplikacji( sf::VideoMode( 800, 600, 32 ), "Kurs SFML - http://cpp0x.pl" );
sf::Image obrazek;
obrazek.Create( 30, 60, sf::Color::White );
sf::Sprite naszSprajt;
naszSprajt.SetImage( obrazek );
naszSprajt.SetPosition( 400, 300 );
naszSprajt.SetScale( 5, 5 );
naszSprajt.SetCenter( obrazek.GetWidth() / 2.0f, obrazek.GetHeight() / 2.0f );
naszSprajt.SetColor( sf::Color( 0x00, 0xff, 0x00, 0x80 ) );
while( oknoAplikacji.IsOpened() )
{
sf::Event zdarzenie;
while( oknoAplikacji.GetEvent( zdarzenie ) )
{
if( zdarzenie.Type == sf::Event::Closed )
oknoAplikacji.Close();
}
oknoAplikacji.Clear( sf::Color::Black );
naszSprajt.Rotate( 0.01f );
const sf::Input & sterowanie = oknoAplikacji.GetInput();
sf::Vector2f punkt = naszSprajt.TransformToLocal( sf::Vector2f(( float ) sterowanie.GetMouseX(),( float ) sterowanie.GetMouseY() ) );
bool bCzyZaznaczony =( punkt.x >= 0 && punkt.y >= 0 && punkt.x <= obrazek.GetWidth() && punkt.y <= obrazek.GetHeight() );
naszSprajt.SetColor( bCzyZaznaczony ? sf::Color::Green: sf::Color::Red );
oknoAplikacji.Draw( naszSprajt );
oknoAplikacji.Display();
}
return 0;
}
Rzeczywista pozycja myszki
Jeżeli uruchomiłeś wcześniejszy program demonstrujący działanie metody
TransformToLocal to zapewne zauważyłeś, że wszystko zadziałało tak jak chcieliśmy - po najechaniu myszką na prostokąt zmienił on swój kolor. Problem się pojawi jednak gdy zmienisz rozmiar okna - wówczas pozycja myszki zacznie się 'rozjeżdżać' z obrazem, w wyniku czego program zacznie działać po prostu źle. Rozwiązaniem tego problemu jest metoda
ConvertCords, która należy do klasy
sf::RenderWindow. Metoda
ConvertCords konwertuje współrzędne ze 'świata rzeczywistego' na ekran, czyli np. położenie myszki znajdującej się w oknie do położenia myszki umieszczonej na buforze ekranu. Oto fragment kodu, który należy zmodyfikować by prawidłowo obsługiwać współrzędne myszy na ekranie:
const sf::Input & sterowanie = oknoAplikacji.GetInput();
sf::Vector2f mysz = oknoAplikacji.ConvertCoords( sterowanie.GetMouseX(), sterowanie.GetMouseY() );
sf::Vector2f punkt = naszSprajt.TransformToLocal( mysz );
bool bCzyZaznaczony =( punkt.x >= 0 && punkt.y >= 0 && punkt.x <= obrazek.GetWidth() && punkt.y <= obrazek.GetHeight() );
naszSprajt.SetColor( bCzyZaznaczony ? sf::Color::Green: sf::Color::Red );
Pozostałe informacje
To by było na tyle na chwilę obecną o możliwościach klasy
Sprite. Jak widzisz biblioteka SFML jest bardzo wygodna w użyciu i posiada wystarczająco dużo udogodnień by można było poważnie myśleć o wykorzystaniu jej do tworzenia własnych gier :)