Güçlendirmeler (Powerups)

Breakout'a neredeyse son şeklini verdik; ancak en azından bir oyun mekaniği daha eklersek sıradan bir Breakout klonundan farklı bir şey elde edebiliriz. Power-up'lar (güç artırıcılar) olsa harika olmaz mıydı?

Fikir şu: bir tuğla yıkıldığında küçük bir olasılıkla bir power-up bloğu doğar. Bu blok yavaşça aşağı düşer; oyuncu paddle'ıyla çarpışırsa power-up türüne bağlı olarak ilginç bir efekt gerçekleşir. Örneğin bir power-up paddle'ı büyütür, bir diğeri topun nesnelerden geçmesine izin verir. Aksine oyuncuyu olumsuz etkileyen negatif power-up'lar da var.

Bir power-up'ı birkaç ekstra özelliğe sahip bir GameObject olarak modelleyebiliriz. Bu yüzden GameObject'ten türeyen bir PowerUp sınıfı tanımlıyoruz:

const glm::vec2 SIZE(60.0f, 20.0f);
const glm::vec2 VELOCITY(0.0f, 150.0f);

class PowerUp : public GameObject 
{
public:
    // power-up durumu
    std::string Type;
    float       Duration;	
    bool        Activated;
    // kurucu
    PowerUp(std::string type, glm::vec3 color, float duration, 
            glm::vec2 position, Texture2D texture) 
        : GameObject(position, SIZE, texture, color, VELOCITY), 
          Type(type), Duration(duration), Activated() 
    { }
};

Bir PowerUp, ekstra duruma sahip bir GameObject'tir. Sınıfın başlık dosyasına buradanarrow-up-right ulaşabilirsiniz.


Power-up Türleri

Her power-up türünü bir string, aktif kalma süresini ve aktif olup olmadığını tanımlar. Breakout'ta toplam 4 pozitif ve 2 negatif power-up bulunur:

Power-up görselleri
  • Speed: Topun hızını %20 artırır.

  • Sticky: Top paddle ile çarpıştığında, boşluk tuşuna basılana kadar paddle'a yapışık kalır. Bu, oyuncunun topu serbest bırakmadan önce daha iyi konumlandırmasını sağlar.

  • Pass-Through: Solid olmayan bloklar için çarpışma çözümü devre dışı bırakılır; top birden fazla bloktan geçebilir.

  • Pad-Size-Increase: Paddle'ın genişliğini 50 piksel artırır.

  • Confuse: Kısa bir süre için confuse son işlem efektini etkinleştirir; kullanıcıyı şaşırtır.

  • Chaos: Kısa bir süre için chaos son işlem efektini etkinleştirir; kullanıcıyı derinden yönünü kaybettirir.

Dokular: Speedarrow-up-right, Stickyarrow-up-right, Pass-Througharrow-up-right, Pad-Size-Increasearrow-up-right, Confusearrow-up-right, Chaosarrow-up-right.

Seviye blok dokularına benzer şekilde her power-up dokusu tamamen gri tonlamalıdır. Bu, bir renk vektörüyle çarpıldığında power-up renklerinin dengeli kalmasını sağlar.

Power-up'ların durumu, süresi ve belirli efektleri olduğundan oyunda şu anda aktif olan tüm power-up'ları takip etmek gerekir:


Power-up Doğurma

Her tuğla yıkıldığında küçük bir olasılıkla power-up doğurmak istiyoruz. Bu işlevsellik SpawnPowerUps fonksiyonunda bulunur:

Normal power-up'lar için 75'te 1, negatif power-up'lar için 15'te 1 olasılık kullanıyoruz. Her power-up'a kullanıcı tarafından daha kolay tanınabilmesi için belirli bir renk ve türüne göre saniye cinsinden süre veriliyor; 0.0f süresi sonsuz anlamına gelir.


Power-up Etkinleştirme

DoCollisions fonksiyonunu sadece tuğla ve paddle çarpışmalarını değil, paddle ile yıkılmamış her pow-erup arasındaki çarpışmaları da kontrol edecek şekilde güncellememiz gerekiyor:

Yok edilmemiş tüm power-up'lar için ya ekranın alt kenarına ulaşıp ulaşmadıklarını ya da paddle'la çarpışıp çarpışmadıklarını kontrol ediyoruz. Her iki durumda da power-up yok edilir; paddle'a çarpma durumunda ayrıca etkinleştirilir.

Power-up'ı etkinleştirmek ActivatePowerUp fonksiyonuyla gerçekleşir:

sticky ve pass-through efektleri oyun mantığını değiştirdiğinden bu efektleri top nesnesinin özelliği olarak saklıyoruz; bu sayede halihazırda aktif olan efekti temel alarak oyun mantığını değiştirebiliyoruz. BallObject güncellemesi: başlıkarrow-up-right, kodarrow-up-right.

Sticky efekti, top ve paddle arasındaki çarpışma kodunda küçük bir güncellemeyle uygulanır:

Pass-through efekti için ise solid olmayan tuğlalara çarpışma çözümü uygulanmaz:


Power-up'ları Güncelleme

Artık geriye kalan tek şey power-up'ların doğduktan sonra hareket edebilmesini ve süreleri dolduğunda devre dışı bırakılmasını sağlamak; aksi takdirde power-up'lar sonsuza kadar aktif kalır.

UpdatePowerUps fonksiyonunda power-up'ları hızlarına göre hareket ettiriyor ve aktif power-up'ların süresini azaltıyoruz. Süre 0.0f'a düştüğünde efekt devre dışı bırakılır ve ilgili değişkenler orijinal durumlarına sıfırlanır:

Her efekt için ilgili öğeleri orijinal durumlarına sıfırlayarak devre dışı bırakıyoruz. UpdatePowerUps'ın sonunda PowerUps vektörünü dolaşıp yok edilmiş ve devre dışı bırakılmış her power-up'ı siliyoruz. Bunun için algorithm başlığından remove_if fonksiyonunu bir lambda yüklemiyle kullanıyoruz.

circle-info

remove_if fonksiyonu, lambda yükleminin doğru olduğu tüm öğeleri kapsayıcı nesnesinin sonuna taşır ve bu kaldırılan öğeler aralığının başlangıcına bir iterator döndürür. Kapsayıcının erase fonksiyonu bu iterator ve vektörün son iterator'ını alarak ikisi arasındaki tüm öğeleri kaldırır.

Bir power-up efekti aktifken aynı türden başka bir power-up oyuncu paddle'ıyla çarpışabilir. Bu durumda oyunun PowerUps vektöründe aynı türden birden fazla aktif power-up olabilir. Bu yüzden IsOtherPowerUpActive fonksiyonunu kullanarak aynı türde hâlâ aktif başka bir power-up olup olmadığını kontrol ediyoruz:


Render

Tüm bu işlevselliği bir araya getirdiğimizde oyunu hem daha eğlenceli hem de çok daha zorlu kılan çalışan bir power-up sistemine sahip oluyoruz.

Güncellenmiş oyun kodu (seviye sıfırlandığında tüm power-up efektleri de sıfırlanır): başlıkarrow-up-right, kodarrow-up-right.

Last updated