Javascript Canvas Elementi ile Flappy Bird Yapımı

Tarayıcı tabanlı oyunlar yapmak web yazılım geliştirme meraklıları için çok faydalı bir pratiktir. Bu sefer, kısmen de olsa, meşhur Flappy Bird oyununu yapacağız. Projenin kodlarına bu repo’dan ulaşabilirisiniz.

Kod kısmına geçmeden önce ihtiyacımız olan görselleri bulalım. Bir oyunun içerisinde onlarca farklı görsel olabilir. Bunların hepsini tek tek yüklemek, her biri için ayrı bir istek göndermek, memory’de yer ayırmak verimsiz olur. Bunun yerine tüm görselleri birleştirip tek bir imaj dosyası olarak oyunumuza dahil edip ihtiyacımız olan görselin konumunu göstererek kullanacağız. Flappy Bird için şu adresteki görseli kullanacağım. Görsele git reposundan da ulaşabilirsiniz.

Kodumuzu yazmaya başlayalım. Her zamanki gibi index.html dosyamızla başlıyoruz. Bir canvas elementi ekliyoruz DOM ağacımıza. Bütün çizimlerimiz bu element üzerine javascript ile olacak. Basit CSS stilleri ile canvasımızı ortalıyor ve sprite görselimizi arkaplan olarak veriyoruz. background-size ile görselin uygun bölümüne denk gelmesini sağlıyoruz.

Eklediğimiz game.js dosyası ile giriş yapıyoruz. Moduler bir yapı kullanacağız. 4 farklı module dosyamız var.

  • vars: Oyuna ait değişkenleri bunun içinde tutacağız
  • Bird: Oyundaki kuş nesnesi için gerekli sınıf bu dosyanın içerisinde
  • Ground: Oyunda kuşun düşüp çarpacağı zemin için bu dosyada bir sınıf tanımlı
  • Column: Kuşumuza engel olan kolonlar bu dosyadaki sınıf ile oluşacak

game.js dosyamızda önce DOM ağacımızdan canvas elementimizi alıyoruz ve ekran boyutumuza göre boyutlandırıyoruz. Dikey bir ekranda oynanan bir oyun olduğu için maksimum yükseklik ve 16/9 oranında genişlik veriyoruz.

Kuş yere düşerken ona yere çeken bir yer çekimi kuvveti gerekli. Bunu frame başına piksel biriminde bütün ekranı 5 saniyede düşecek şekilde hesapladık.

Görselimizi tüm objelerde kullanmak üzere sprite değişkenine atıyoruz. Bird, ground ve columns değişkenlerimize ilgili sınıflardan birer örnek oluşturuyoruz. Kolonlar ekrandan çıkıp tekrar canlandığında skoru arttırmamız gerektiğinden bunun için bir event bağlamamız gerektiğinden increaseScore fonksiyonunu kullanıyoruz.

setInterval kullanarak her bir frame için canvasımıza çizim yapacağız. context.clearRect ile önce ekranımızı temizliyoruz. CSS ile arkaplanımızı verdiğimiz için clearRect yapsak bile görselimiz görünür olacak. Her bir sınıfımız için draw methodumuzu çağırarak canvasa çiziyoruz, skorumuzu fillText ile yazıyoruz. Son olarak kuşumuzun yere ya da kolona dokunup dokunmadığını kontrol ederek setIntervali bitiriyoruz.
Bird
Kuş görselimiz 3 adımlı bir animasyona sahip. Her bir adımın görsel koordinatlarını constructor methodunda frames değişkenine atıyoruz. Sprite üzerinde bu pozisyon değerleini kolayca bulmak için Sprite Cow sitesini kullanabilirsiniz. Kuşun canvas üzerindeki konumunu position nesnesinde tutacağız. Son olarak kuşun boyutlarını (34*24) canvasımıza uydurmak için canvas boyutları ile görselimizdeki arkaplan görseli boyutlarını (288*512) oranlıyoruz.
draw methodu içinde ile her bir frame için dikey pozisyonu (y) tekrar hesaplayıp drawImage ile canvasımıza çizdiriyoruz.
isTouchingGround ve isTouchingColumns methodları ile her iki nesnenin ilgili position değerlerini karşılaştırarak bir çakışma var ise true döndürüyoruz.
Ground
Bird sınıfından çok da farklı değil. Görselimizdeki yeri oluşturan kısım canvasımızdan biraz daha uzun. Bunu ileri geri hareketler ile hareket ediyormuş gibi göstermek için kullanacağız. Her 22px’de tekrar eden bir örüntü var. Bunu bölerek frames dizisine ekliyoruz. Diğer kısımlar Bird sınıfı ile neredeyse aynı şekilde ilerliyor.
Column
Bu sınıfın constructor metodunda iki kolon arasındaki boşluğu gap değişkenine atıyoruz (canvas yüksekliğinin %25’i olacak şekilde). gapTopPosition ise üst kolonun dikeyde konumu belirtiyor.  Bu değeri, her kolon canlandırma işleminde çağırılan, reviveColumn methodunda rastgele bir değerle değiştiriyoruz ki geçiş boşluğumuz sürekli aynı yerde olmasın.

Yayımlandı

kategorisi

yazarı:

Etiketler:

Yorumlar

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir