Render Text (Metin Render Etme)

Bu bölümde oyuna son geliştirmeleri ekleyeceğiz: bir can sistemi, kazanma koşulu ve render edilmiş metin biçiminde geri bildirim. Bu bölüm, daha önce tanıtılan Text Renderingarrow-up-right bölümünü yoğun şekilde kullanır; henüz okumadıysanız önce o bölümden geçmenizi öneririm.

Breakout'ta tüm metin render kodu, FreeType kütüphanesinin başlatılması, render yapılandırması ve gerçek render kodunu barındıran TextRenderer sınıfında kapsüllenir:

Metin oluşturucunun fonksiyon içerikleri metin render bölümündeki kodla neredeyse aynı; ancak ekrana glyph render eden kod biraz farklı:

void TextRenderer::RenderText(std::string text, float x, float y, float scale, glm::vec3 color)
{
    [...]
    for (c = text.begin(); c != text.end(); c++)
    {
        float xpos = x + ch.Bearing.x * scale;
        float ypos = y + (this->Characters['H'].Bearing.y - ch.Bearing.y) * scale;

        float w = ch.Size.x * scale;
        float h = ch.Size.y * scale;
        // her karakter için VBO güncelle
        float vertices[6][4] = {
            { xpos,     ypos + h,   0.0f, 1.0f },
            { xpos + w, ypos,       1.0f, 0.0f },
            { xpos,     ypos,       0.0f, 0.0f },

            { xpos,     ypos + h,   0.0f, 1.0f },
            { xpos + w, ypos + h,   1.0f, 1.0f },
            { xpos + w, ypos,       1.0f, 0.0f }
        };
        [...]
    }
}

Bunun biraz farklı olmasının nedeni, metin render bölümünde kullandığımızdan farklı bir ortografik projeksiyon matrisi kullanmamız. Metin render bölümünde tüm y değerleri aşağıdan yukarıya doğru sıralanırken Breakout oyununda tüm y değerleri yukarıdan aşağıya doğru sıralanır; 0.0 y koordinatı ekranın üst kenarına karşılık gelir. Bu nedenle dikey ofseti nasıl hesapladığımızı biraz değiştirmemiz gerekiyor.

RenderText'in y parametresinden aşağıya doğru render ettiğimizden dikey ofseti, bir glyph'in glyph alanının üstünden aşağıya ne kadar itildiği olarak hesaplıyoruz. FreeType'dan 'H', 'T' veya 'X' gibi bazı glyphlar her zaman bu üst kenara değer. Bu yüzden bu tepe glyph'lerin bearingY'ını söz konusu glyph'in bearingY'ından çıkararak kırmızı vektörün uzunluğunu hesaplıyoruz:

Glyph dikey ofseti

ypos hesaplamasını güncellemek dışında, mevcut ortografik projeksiyon matrisiyle çarpıldığında tüm vertex'lerin hâlâ ön yüzlü kalmasını sağlamak için vertex sırasını da biraz değiştirdik (yüz ayıklamaarrow-up-right bölümünde tartışıldığı gibi).

TextRenderer'ı oyuna eklemek kolay:

Metin oluşturucu, buradanarrow-up-right indirebileceğiniz OCR A Extended adlı bir fontla başlatılır.


Oyuncu Canları

Topu alt kenara ulaşır ulaşmaz oyunu sıfırlamak yerine oyuncuya birkaç ekstra şans vermek istiyoruz. Başlangıçta 3 can veririz; top alt kenara her değdiğinde can sayısı 1 azalır. Yalnızca can sayısı 0 olduğunda oyunu sıfırlıyoruz:

Oyunun Update fonksiyonunu oyunu sıfırlamak yerine oyuncunun can sayısını azaltacak şekilde güncelliyoruz:

Oyunu/seviyeyi sıfırlarken oyuncunun can sayısını da sıfırlamayı unutmayın:

Oyuncunun şu anki can sayısını göstermek için metin oluşturucuyu kullanıyoruz:

Hayat sayısı render

Seviye Seçimi

Kullanıcı GAME_MENU oyun durumundayken oynanacak seviyeyi seçme kontrolünü vermek istiyoruz. W veya S tuşlarıyla seviyeler arasında geçiş yapabilir; Enter tuşuyla GAME_MENU durumundan GAME_ACTIVE durumuna geçiş yapılır:

Menü durumunda oyuncuya talimat ve seçilen seviyeyi arka planda gösteriyoruz:

Seviye seçim ekranı

W veya S tuşuna basıldığında oyunun birden fazla kare boyunca tuş basışını kaydetmesi nedeniyle seviyeler hızla kayar. Bunu çözmek için GUI sistemlerinde yaygın bir numarayı kullanıyoruz: yalnızca basılı tuşları kaydetmekle kalmaz, bir kez işlenen ve bırakılana kadar tekrar işlenmeyen tuşları da saklarız:

GLFW'nin tuş callback fonksiyonunda tuş bırakıldığında işlenmiş değerini sıfırlıyoruz:


Kazanma Koşulu

Oyuncu tüm solid olmayan blokları yıktığında oyunu kazanır. GameLevel sınıfında bunun için bir fonksiyon oluşturduk:

Bu koşulu oyunun Update fonksiyonunda kontrol edip true döndürdüğünde oyun durumunu GAME_WIN olarak değiştiriyoruz:

GAME_WIN durumunda oyuncuyu tebrik edip yeniden başlatma veya çıkış seçeneği sunuyoruz:

Kazanma ekranı

Ve işte bu kadar! Üzerinde aktif olarak çalıştığımız Breakout oyununun son parçası. Deneyin, zevkinize göre özelleştirin ve herkese gösterin!

Oyunun son kaynak kodu: başlıkarrow-up-right, kodarrow-up-right.

Ek Okuma

Last updated