Flame Engine

Tayyip Guzel
Flutter Students Club
5 min readJan 23, 2022

Herkese Selamlar🔥💙,

İlk yazımda sizlere Flutter ve Dart ile geliştirilmiş 2D oyun motoru Flame Engine’i anlatacağım. Haydi başlayalım..

Flame Nedir?

Flame Flutter’ın gücünden yararlanarak mobil, web ve masaüstü oyunlar geliştirmemizi sağlar. Oyun geliştirmek için gerekli bütün altyapıya sahip modüler bir oyun motorudur.

Bizlere bir oyunu oluşturmak için basit ama gerekli işlevleri sağlar. Örneğin; İnputlar, resimler, sprite ve spritesheetler, animasyonlar vs. component yapıları içerisinde barındırır.

Flame core paket dışında geliştirmeler de yapmaktadır.

Flame: İçerisinde core bileşenleri bulunduran pakettir.

Forge2D: Çarpışma algılayan gelişmiş fizik motoruna sahip pakettir.

Audio: audioplayers paketini kullanarak ses efektlerini kullanmamızı sağlar.

Splash: Açılış ekranı eklememizi sağlar.

Tiled: Tile Maps için kullanılan pakettir.

Birbirinden bağımsız ve modüler bu paketlerin her birini ayrı ayrı kullanabilmekteyiz.

Paketin Yüklenmesi

Flutter ve dart için paketlerin bulunduğu pub.dev adresinden arayarak ya da bu link üzerinden pakete erişebilirsiniz.

dependencies:
flame: 1.0.0

Flame’i projenize dahil etmek için yukarıdaki kod satırını pubspec.yaml’a ekleyin.

Pubspec.yaml içerisinde Crtl+S yaparak ya da komut satrından flutter pub runkomutunu çalıştırıp kullanmaya başlayabilirsiniz.

Dosya Yapısı

Geliştirdiğimiz bütün mobil uygulamalar içinde .png , .svg uzantılı dosyalar bulunur. Bu yapılar olmazsa olmaz denebilir.

Genel olarak ana dizin üzerinde bir assets klasörümüz bulunur. Bütün uygulama resimleri ve videoları bu klasör içerisinde yer alır. Flame bizlere bu şekilde assets klasörü açmamızı önerir. Bu klasör altında ise images , audio olarak iki alt klasör bulunur. Bu yapının gücünü ise projede göreceğiz.

flutter:
assets:
- assets/audio/gun_sound.mp3
- assets/images/gun.png
- assets/images/bullet.png

Asset olarak eklediğimiz her yapıyı pubspec.yaml içerisinde bu şekilde belirtmemiz gerekiyor.

FlameGame

Flame paketini yükledikten sonra kullanabildiğimiz bir yapıdır. Oyun geliştirmek için kullandığımız bir sınıftır. Bu sınıfı Component sınıfından ve Game mixin’inden kalıtım almaktadır. Haydi beraber bu yapıyı oluşturalım.

Öncelikle main.dart üzerinde birkaç değişiklik yapmamız gerekiyor.

main.dart

WidgetsFlutterBinding.ensureInitialized() fonksiyonu Flutter motoruyla iletişime geçer ve eğer runApp() fonksiyonundan önce bir kod çalıştırmak isterseniz bunu kullanabilirsiniz.

Flame.device.fullScreen() ise uygulama açıldığında tam ekranda açılmasını sağlar.

game_page.dart

Bu sayfaya import 'package:flame/game.dart'; importunu ekliyoruz ve oyunumuz için başlangıçı yaptık. Bu sınıfın ekranda görünmesini sağlamalıyız ve bunun için MyApp sınıfımıza bazı eklemeler yapacağız.

main.dart

MyApp sınıfı içerisinde FlameGame sınıfından kalıtım alan sınıfımızdan flameExample isimli bir nesne üretiyoruz. Bu oluşturduğumuz yapıyı Flutter widget ağacına yerleştirmemiz gerekiyor. GameWidget flame paketiyle gelen ve oluşturduğumuz sınıfı ağaca dahil etmemizi sağlayan widgettır.

https://docs.flame-engine.org/

Flame dökümanından aldığım bu fotoğraf component yaşam döngüsünü anlatmaktadır. Oyunun yapısını düşünürsek sürekli bir döngü vardır. Döngüye başlarken dahil olan yapılar ve sonradan güncellenen yapılarda bulunmaktadır. Oyunun işleyişi bu şekildedir.

Flame göründüğü üzereonLoad() ve update(double t) onGameResize()fonksiyonlarını içerir. onLoad() ile oyun ilk çalışırken görünecek componentları ekleriz. update() ile oyun içerisinde componentlarla ilgili güncelleme yapmak için kullanırız. onGameResize() ise başlangıçta component add metodu ile eklendiğinde ve ekran yeniden boyutlandığında çalışır.

Componentlar

Flame’de oyunu oluşturmak için gerekli yapılara component ismi verilmektedir. Sprite , animasyonlu spritelar ,parallax vs. yapıları olşuturmak için component yapılarını kullanırız. Tüm componentlar Component abstract sınıfından kalıtım almaktadır.

Position Component

Bu component ekrandaki bir kareyi,daireyi veya hareketli bir grafiği temsil eder.

Componentları oluştururken belirli bir dosya düzeniyle gitmek projeyi düzenli hale getirecektir.

lib klasörü altına component isimli bir klasör açalım.

position_component.dart

Componentları kullanırken bu şekilde MyCircle sınıfı oluşturuyoruz ve PositionComponent sınıfından kalıtım alıyoruz.

super() metodu,üst sınıfın varsayılan constructor ’ına ulaşmamızı ve çalıştırmamızı sağlar.

Bu sınıfı oluşturduktan sonra flame’e bunu bildirmemiz gerekiyor. bunun için oluşturduğumuz FlameGame sınıfı içerisine giriyoruz.

game_page.dart

MyCircle sınıfından nesne üretiyoruz ve radiusve position değerlerini giriyoruz. Sonrasında onLoad() içerisinde add() fonksiyonu ile ekliyoruz.

Screenshot

Bu şekilde bir ekran elde ediyoruz. PositionComponent ile bu tarz şekiller oluşturabilmekteyiz.

Sprite Component

PositionComponent ile benzer yapıda olan SpriteComonent ile Sprite ’lar oluşturabilmekteyiz.

sprite_component.dart

SpriteComponent oluştururken MySprite sınıfı yine kalıtım alıyor ve super ile üst constructor çalıştırılıyor ve bilgi gönderiliyor.

Burada farklı bir yapı karşmıza çıkıyor. HasGameRef<> Flame paketi içerisinde bulunan bir mixin ’dir. Bu bize FlameGame ‘den kalıtım alan MediumGameExample sınıfının özelliklerini kullanmamızı sağlar. loadSprite metodunu kullanmak için bu mixin yapısına ihtiyacımız vardır.

game_page.dart

Component oluştuktan sonra yine MediumGameExample snıfında eklememiz gerekmektedir.

Screenshot

Ve ekran görüntümüz bu şekilde olacaktır.

Sprite Animation Component

2D oyunlarda animasyonlar programlar üzerinden yapılmak yerine sprite ’lar ile yapılmaktadır. Bir kedi düşünelim, adım atarken yaptığı hareketleri çizip sonra onları hızlıca arka arkaya oynatırsak kedi yürüyor gibi görünür. Haydi deneyelim..

Öncelikle bir adet SpriteSheet ’e ihtiyacımız var.

SpriteSheet Örneği

SpriteSheet ’ler bu şekilde görünmektedir. Biz bu örneği kullanmayacağız.

Github üzerinden projeye ve assets ’e ulaşabilirsiniz.

animation_sprite_component.dart

CatComponent sınıfı SpriteAnimationComponent sınıfından kalıtım almaktadır. Önceki kullanımlardan farklı olan yapıları inceleyelim.

animationSpeed değeri sprite ’lar arasında geçiş süresini belirlemektedir.

animation ise spriteSheet ’in isimli kurucusu ile oluşmaktadır. row spriteSheet ’te kaçıncı satırı kullandığımızı belirler. to ise satırda kaç adet sprite olduğunu belirtir.

Component ’ı MediumGameExample içerisinde add() fonksiyonu ile eklemeyi unutmayın.

Cat Animation

Oluşturduğumuz animasyon bu şekilde görünmektedir.

Parallax Component

Bu component 2D oyunların vazgeçilmez yapılarından birisidir. Arka planda oluşturulan katmanların hareketleri ile aslında karakter ilerliyormuş gibi görüntü yakalanır. Haydi Deneyelim..

main.dart

main() fonksiyonu içerisinde ekranı yatay konuma getiriyoruz.

Yeni bir component dosyası oluşturuyoruz.

parallax_component.dart

ParallaxComponent yapısı HasGameRef ’i içerisinde barındırmaktadır. Bu yüzden dahil etmedik. Parallax bu şekilde oluşturulmaktadır. baseVelocity ve velocityMultiplierDelta bu katmanların hızlarını belirlemektedir.

Component ’ı MediumGameExample içerisinde add() fonksiyonu ile eklemeyi unutmayın.

Parallax Animation

Flame içerisinde 2D oyun geliştirmek için gerekli olan bütün yapılar mevcuttur. Effect yapıları, Camera, Inputlar , Audio gibi bir çok gerekli yapılar da vardır. Flame web sitesi üzerinden daha fazla kaynağa erişebilirsiniz.

Projenin Github reposuna bu linkten ulaşabilirsiniz. Umarım anlaşılır ve güzel bir içerik olmuştur. Sonraki yazılarda görüşmek üzere.. 💙

--

--