Wprowadzenie
W poprzednich rozdziałach dowiedziałeś się, jak wyświetlać obrazki, oraz jakie można na nich wykonać transformacje.
W tym rozdziale dowiesz się, jak wyświetlać figury geometryczne, fachowo zwane prymitywami.
Biblioteka SFML posiada wbudowaną obsługę prymitywów.
Klasą bazową dla wszystkich prymitywów jest
sf::Shape.
Dziedziczy ona po
sf::Drawable(czyli można ją wyświetlać) oraz po
sf::Transformable(czyli można zmieniać jej pozycję, obrót, skalowanie, itd.).
Figury w SFML
Prostokąty
Prostokąty to chyba najprostsze figury jakie istnieją. Ich tworzenie implementuje klasa
sf::RectangleShape.
sf::RectangleShape rectangle( sf::Vector2f( rozmiarX, rozmiarY ) );
rectangle.setPosition( pozcjaX, pozycjaY );
Linie
W SFML nie ma osobnej klasy dla linii. Dlaczego? Dlatego, że linia, to po prostu prostokąt o szerokości 1.
sf::RectangleShape line1( dlugosc, 1.0f );
sf::RectangleShape line2( 1.0f, dlugosc );
line1.setPosition( pozycjaX, pozycjaY );
Jest pewna sztuczka pozwalająca rysować linie od jednego do drugiego punktu. Polega ona na tym, że metoda draw() klasy sf::RenderWindow potrafi rysować tablice wierzchołków.
sf::RenderWindow win;
sf::Vertex line[ 2 ] = { sf::Vertex( sf::Vector2f( poczatekX, poczatekY ) ), sf::Vertex( sf::Vector2f( koniecX, koniecY ) ) }; win.draw( line, 2, sf::Lines );
|
Koła
Do tworzenia kół używamy klasy
sf::CircleShape. Kółko tworzymy podając jego promień.
sf::CircleShape circle( promien );
circle.setPosition( pozycjaX, pozycjaY );
Trójkąty
Nie, nie ma w SFML nie ma klasy dla trójkątów, a to dlatego, że trójkąt to wielokąt regularny, a te tworzy się za pomocą klasy
sf::CircleShape.
Ma ona możliwość tworzenia koła, bądź wielokąta regularnego podając promień(czyli odległość najdalszego punktu od środka) i ilość boków.
sf::CircleShape triangle( promien, 3 );
triangle.setPosition( pozycjaX, pozycjaY );
Wielokąty
Do tworzenia wielokątów używamy klasy
sf::ConvexShape. Tworzymy je podając liczbę i położenie kolejnych wierzchołków.
Uwaga: Klasa sf::ConvexShape ma kilka ograniczeń. Po pierwsze, za jej pomocą można rysować tylko wielokąty wypukłe(jeśli nie wiesz co to znaczy zerknij do Wikipedii) Po drugie, wierzchołki musisz deifniować po kolei(tzn. zgodnie lub przeciwnie do ruchu wskazówek zegara). Jeśli je zdefiniujesz byle jak, to mogą wystąpić dziwne problemy.
|
sf::ConvexShape convex;
convex.setPointCount( liczba_wierzcholkow );
convex.setPoint( 0, sf::Vector2f( pozycja_1wierzcholkaX, pozycja_1wierzcholkaY ) );
convex.setPoint( 1, sf::Vector2f( pozycja_2wierzcholkaX, pozycja_2wierzcholkaY ) );
Własności kształtów
Rysowanie
sf::Shape dziedziczy po klasie
sf::Drawable, więc można je rysować, tak jak inne rzeczy w SFML
Transformacje
Klasa
sf::Shape dziedziczy po
sf::Transformable, więc można na niej wykonywać wszystkie transformacje, takie jak ustawianie pozycji, obrót, skalowanie itp.
Więcej info w poprzednim rozdziale
Wypełnianie kolorem
Wypełnianie kolorem jest proste: wystarczy ustawić kolor za pomocą metody
setFillColor()sf::CircleShape circle( 50 );
circle.setFillColor( kolor );
Wypełnianie teksturą
Teraz czas na bardzo fajny efekt: Kształt można wypełnić teksturą prawie bez żadnej pracy(kolejna zasługa OpenGL)
sf::Texture texture;
sf::CircleShape circle( 50 );
circle.setTexture( & texture );
Proste, co nie? Proste, fajne i skuteczne. Żeby z powrotem ustawić brak tekstury wystarczy wywołać
setTexture() z parametrem
NULL.
Brzegi kształtu
Możemy ustawić kolor i grubość brzegu kształtu za pomocą metod
setOutlineColor() i
setOutlineThickness()sf::CircleShape circle( 50 );
circle.setOutlineColor( kolor )
circle.setOutlineThickness( grubosc )
Brzegi nie są teksturowane.
Przykład
#include <iostream>
#include <SFML/Graphics.hpp>
using namespace std;
using namespace sf;
int main()
{
RenderWindow win( VideoMode( 800, 800 ), L"Rozdział 1" );
CircleShape circle( 50 );
circle.setPosition( 0, 0 );
circle.setOutlineColor( Color::Red );
circle.setOutlineThickness( 2 );
Texture texture;
if( !texture.loadFromFile( "textura.png" ) )
cerr << "Nie można załadować grafiki\n";
circle.setTexture( & texture );
while( win.isOpen() )
{
win.clear( Color::White );
Event e;
while( win.pollEvent( e ) )
{
if( e.type == Event::Closed )
win.close();
}
win.draw( circle );
win.display();
}
}