Oyun Programlama Kalıpları — State

ÜNOG
ÜNOG
Published in
4 min readOct 22, 2020

ÜNOG’a Katıl Bültenimize Abone OlGeçmiş Yayınlarımızı Oku

Bu sefer Ludum Dare’de kesinlikle birinci olacaksınız, kafaya koydunuz. Bunun için de tabi ki bir puzzle platformer yapmanız gerekiyor. Şimdi ise kahramanınızın kontrollerini yazıyorsunuz. İlk adım, tabi ki zıplamak! B’ye basıldı mı karakter zıplamalı. Basit bir şekilde yapabiliriz:

Zıplamanın yanısıra, karakterin uçmasını sağlayan bir kod parçası.

Ama bir bug var, fark ettiniz mi?

Karakterimizin havada uçmasını engelleyecek hiç bir şey yok — oyuncu her B tuşuna bastığında, yerde veya havada, karakter yükseklere doğru zıplamaya devam eder. Neyse ki bunu çözmenin basit bir yolu var, tek bir boolean bayrağına bakar.

Artık sadece eğer zaten zıplamıyorsak zıplayabiliyoruz.

Şimdi ise oyuncumuz ne zaman DOWN tuşuna basarsa o zaman karakterimizin eğilmesini istiyoruz, DOWN tuşunu bıraktığımızda da doğrulsun. Hızlıca bunu da ekleyelim:

Artık karakterimiz, eğilip doğrulabiliyor. Ama sıkıntı tam olarak zıplarken de doğrulabiliyor…

Ne yazık ki hala bir bug var…

Oyuncu bu kodumuz ile:

  1. DOWN tuşuna basılı tutup eğilir.
  2. B tuşuna basıp eğilmişken zıplayabilir.
  3. DOWN tuşunu burakıp havadayken doğrulabilir.

Bu da, zıplamanın ortasında doğrulma animasyonunu oynayacağımız anlamına gelir! Bir boolean daha ekleyelim…

Doğru zamanlarda eğildiğimizi garantilemek için isDucking boolean bayrağını eklememiz gerekti.

Şimdi ise diyelim bir DiveAttack, yani uçan tekme özelliği eklemek istiyoruz. Eğer oyuncu karakterimiz havadayken DOWN tuşuna basar ise karakter uçan tekme atmalı.

Artık zıplarken DOWN tuşuna basarsak karakterimiz uçan tekme atıyor. Ama hala bir problem var.

Artık tekme atabiliyoruz, ama bu son yazdığımız eklenti ile zıplama kodumuzu bozduk… Çünkü uçan tekme aşamasındayken oyuncu B tuşuna basar ise karakterimiz havada zıplayabilliyor. Bunun çözüm yolu da başka bir boolean bayrağı eklemek… Ama böyle giderse işin sonunda onlarca bayrağımız olacak ve daha karakterimiz yürümeye bile başlamadı! Bu gidişatın bizi zorlayacağı ortada. Aslında başarmak istediğimiz şey gerçekten basit:

Oyuna eklemek istediğimiz sistem basitçe bu.

Bu görseli çizerek aslıda çözüme çok yaklaştınız! Bu çözüme ise State Programlama Kalıbı deniyor veya diğer bir isim ile Finite State Machines.

Kısaca açıklamak gerekir ise:

  • Oyunda belli sayıda state’ler, yani durumlar var. Mesela bu örneğimizdeki stateler Ayakta, Zıplıyor, Uçan Tekme, ve Eğilmiş.
  • Sisteminiz her an sadece bir state içerisinde olabilir. Bu örnekte karakterimiz aynı anda hem Ayakta durup hem de uçan tekme atamaz. Bu problemi kolayca çözebilmek State Machine kullanmamızın başlıca nedenlerinden biri.
  • Sisteme seri şeklinde eventler veya inputlar yollanmalıdır. Örneğimizde inputlar tabi ki oyuncumuz bastığı tuşlar.
  • Her state, aynı zamanda belli bir geçiş ağına sahip. Doğru input geldiğinde, o input’a bağlı transition, yani geçiş aktive olur ve diğer bir state’e geçilir. Mesela karakterimiz Zıplıyor state’indeyken DOWN inputu gelir ise karakterimiz Uçan Tekme state’ine geçmeli.

State Kalıbı teoride bunlardan ibaret. En temeline elimizde state’ler, input’lar ve transition’lar var, ve bunların bir flowchart gibi çizmesi kolay. Peki bunu kod şeklinde nasıl yazmalıyız?

Şu anda karşılaştığımız problemlerden bir tanesi kimi boolean kombinasyonlarımızın hatalı olması. Mesela isJumping ve isDucking asla aynı anda doğru olmamalı. Bu durumda kullanmamız gereken sistem boolean değil ama enum.

Her bir state için bir enum belirledik.

Farklı farklı boolean bayrakları yerine karakterimiz artık sadece bir state değişkenine sahip olacak. Ve bunun yanı sıra, if sıramızda önce inputu kontrol etmek yerine artık state’i kontrol edicez. Bunun avatajı da aynı state altındaki kodun birbirinden ayrılmaması.

Çok daha temiz ve emin olun daha az bug’a yol açacak.

Artık kodumuzda farklı farklı boolean bayraklarını değerlendirmemize gerek yok, olayı tek bir state değişkeni ile çözebiliyoruz! Bu da kodumuzdaki bug sayısını gerçekten azaltıyor.

Bu sistem bir çok GameJam oyunu için yeterli olur. Ama eğer oyununuzun bu örnekte olduğundan çok daha komplike ise o zaman her state’in kendi sınıfı olması işinizi görecektir. Bu özel güç doldurmak gibi daha komplike özellikler eklemenize yardımcı olackatır. Sınıf bazlı state kodlamasını öğrenmeniz için size aşağıdaki videoyu öneriyoruz:

Bu yazımız ile umarım kodunuzu biraz sadeleştirebilmişizdir ama bu postumuz State Machine konusunun sadece bir başlangıcı! Eğer Hierarchical State Machines veya Pushdown Automata ile ilgili bilgi sahibi olmak istiyorsanız sizi temel kaynağımız olan Game Programming Patterns kitabı ile başbaşa bırakıyoruz:

Haftaya görüşmek üzere!

ÜNOG’a Katıl Bültenimize Abone OlGeçmiş Yayınlarımızı Oku

--

--

ÜNOG
ÜNOG
Editor for

Türkiye’nin en güzel oyun geliştirme topluluğu. https://unog.dev