Bağımsız Görüntülerle Çalışmak

Bağımsız görüntüleri (sprite) göstermek belki de bir 2B uygulama programlama arayüzünün en önemli parçasıdır. Çünkü temel olarak 2B oyunlardaki çoğu şey bağımsız görüntülerdir. Şimdi SFML'de işlerin nasıl yürüdüğüne birlikte bakalım.

Genel olarak bağımsız görüntüler, sabit disklerden yüklenir. Bir görüntüyü SFML ile yüklemek için sf::Image sınıfı ve onun LoadFromFile fonksiyonu kullanılır:
sf::Image Image;
if (!Image.LoadFromFile("sprite.tga"))
{
    // Hata...
}
Ayrıca LoadFromMemory fonksiyonuyla halihazırda belleğe alınmış bir görüntüyü de yükleyebilirsiniz:
sf::Image Image;
if (!Image.LoadFromMemory(FilePtr, Size))
{
    // Hata...
}
Bir yerlerden görüntü yüklemek yerine görüntüleri kendiniz oluşturup, istediğiniz bir renkle doldurabilirsiniz veya bir piksel dizisinden yükleyebilirsiniz:
sf::Image Image1(200, 200, sf::Color(0, 255, 0));
sf::Image Image2(200, 200, PointerToPixelsInMemory);
Veya aşağıdaki gibi resim değişkenlerini tanımladıktan sonra da kullanabilirsiniz:
sf::Image Image1, Image2;

Image1.Create(200, 200, sf::Color(0, 255, 0));
Image2.LoadFromPixels(200, 200, PointerToPixelsInMemory);
Görüntüler bellekten yüklendiği zaman, piksellerin belirli bir biçimde (32 bit RGBA) olması gerektiğini unutmayın.

Ayrıca görüntünün piksellerine okumak ve yazmak için de erişilebilir:
sf::Color Color = Image.GetPixel(10, 20);
Image.SetPixel(20, 30, Color);
Görüntüleri değiştirirken dikkatli olun, kopyalanabilirler fakat bu pek de hafif bir işlem değildir.


Bir Bağımsız Görüntü Oluşturmak
Şimdiye kadar bir görüntüyü oluşturmayı, yüklemeyi ve değiştirmeyi öğrendik. Fakat bunlar bağımsız görüntüler değildir. SFML'de görüntüler ve bağımsız görüntüler iki ayrı sınıfa ayrılır. Görüntüleri, bellekteki piksel dizileri, bağımsız görüntüleri de bu dizileri pencerede görüntülemek için bir yol olarak görebilirsiniz.

SFML'de her bağımsız görüntü, sf::Sprite sınıfının bir örneğidir. Bu sınıf çizilebilir her şeye temellik eden sf::Drawable'den kalıt alır. sf::Drawable, çizilebilir nesnelerin görünümlerini almayı ve ayarlamayı sağlayan bir çok fonksiyon tanımlar. Aşağıda konuyla ilgili birkaç örnek kullanıma bakalım
sf::Sprite Sprite;
Sprite.SetColor(sf::Color(0, 255, 255, 128));
Sprite.SetX(200.f);
Sprite.SetY(100.f);
Sprite.SetPosition(200.f, 100.f);
Sprite.SetRotation(30.f);
Sprite.SetOrigin(0, 0);
Sprite.SetScaleX(2.f);
Sprite.SetScaleY(0.5f);
Sprite.SetScale(2.f, 0.5f);
Sprite.SetBlendMode(sf::Blend::Multiply);

Sprite.Move(10, 5);
Sprite.Rotate(90);
Sprite.Scale(1.5f, 1.5f)
Parametre olarak iki kayar noktalı sayı alan her fonksiyon aynı zamanda bir sf::Vector2f de alabilir.

Nesnelerin merkezi, SetOrigin fonksiyonu ile tanımlanır, öntanımlı merkez nesnelerin sol üst köşeleridir. Merkez; dönüşüm, döndürme ve yeniden boyutlandırmanın hangi noktanın referans alacağını söyler.

Piksel değerleri için tamsayılar kullanılmasına rağmen bağımsız görüntülerin konumları için kayar noktalı değerlerin kullanılmasını merak ediyorsanız, bunun nedeninin daha fazla esneklik sağlaması olduğunu söyleyebiliriz. Bazen bir bağımsız görüntünün yerini bir sonraki karede bir pikselden daha az bir mesafede hareket ettirmek isteyebilirsiniz.

Bağımsız görüntülere pek çok dönüşüm uygulandığı zaman, sonuçta oluşan alanı veya genel anlamda son konumun yerel bir noktasını almak epey zorlaşır. Bu yüzden sf::Sprite ve tüm çizilebilir sınıflar, iki dönüşüm fonksiyonunu tanımlar:
// Yerel bir noktayı, evrensel koordinatlara çevir
sf::Vector2f Global = Sprite.TransformToGlobal(sf::Vector2f(10, 25));

// Evrensel bir noktayı, yerel koordinatlara çevir
sf::Vector2f Local = Sprite.TransformToLocal(sf::Vector2f(425, 120));
Bunlar dışında sık kullanılan fonksiyonlara bakacak olursak:
// Bağımsız görüntünün kaynak resmini değiştir
sf::Image Image;
Sprite.SetImage(Image);

// Bağımsız görüntünün boyutlarını al
float Width  = Sprite.GetSize().x;
float Height = Sprite.GetSize().y;

// Bağımsız görüntüyü yeniden boyutlandır
Sprite.Resize(60, 100);

// Bağımsız görüntüyü X ve Y ekseninde döndür
Sprite.FlipX(true);
Sprite.FlipY(true);

// Bağımsız görüntünün belirtilen pikseldeki rengini al
sf::Color Pixel = Sprite.GetPixel(10, 5);
İstersek bağımsız görüntülere kolayca etkileşim katabiliriz:
// Geçen zamanı al
float ElapsedTime = App.GetFrameTime();

// Bağımsız görüntüleri hareket ettirelim
if (App.GetInput().IsKeyDown(sf::Key::Left))  Sprite.Move(-100 * ElapsedTime, 0);
if (App.GetInput().IsKeyDown(sf::Key::Right)) Sprite.Move( 100 * ElapsedTime, 0);
if (App.GetInput().IsKeyDown(sf::Key::Up))    Sprite.Move(0, -100 * ElapsedTime);
if (App.GetInput().IsKeyDown(sf::Key::Down))  Sprite.Move(0,  100 * ElapsedTime);

// Bağımsız görüntüleri döndürelim
if (App.GetInput().IsKeyDown(sf::Key::Add))      Sprite.Rotate(-100 * ElapsedTime);
if (App.GetInput().IsKeyDown(sf::Key::Subtract)) Sprite.Rotate( 100 * ElapsedTime);


Bağımsız Görüntü Çizme
Tarama penceresinde bir bağımsız görüntü çizmek çok kolaydır:
App.Draw(Sprite);
Ek bir parametreye ihtiyaç yoktur çünkü bağımsız görüntü kendi görüntüsüyle ilgili tüm bilgilere (konumu, rengi, ...) sahiptir. Eğer asıl görüntünün sadece bir alt bölgesini çizmek isterseniz, bağımsız görüntünün SubRect parametresini değiştirebilirsiniz:
Sprite.SetSubRect(sf::IntRect(10, 10, 20, 20));
Böylece görüntünün yalnızca 10, 10 pikselinden 20, 20 pikseline kadarki alanını çizdiriyoruz.

sf::IntRect, dikdörtgenleri işlemek için bir sınıftır. Kayar koordinatlı dikdörtgenler için ayrıca sf::FloatRect sınıfı bulunmaktadır.

Bağımsız görüntüler, bir 2B uygulama programlama arayüzündeki temel konseptlerden biridir ve görmüş olduğunuz gibi SFML içinde kullanımı çok kolaydır. İlerleyen derslerde basit şekillerin nasıl çizilebileceğini görebilirsiniz.

Bu eğitselle ilgili örneklere sfml-gelistirme deposundan ulaşabilirsiniz.


Kaynak: Graphics - Displaying a sprite