mobile game development etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
mobile game development etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

Let’s Play into the Future with Flutter Flame!

 


Hello everyone. Today I have prepared a guide about Flame for you. Developers who are bored of constantly developing mobile applications, who want to try something different, who have an idea and want to realize it from a familiar place, this place is for you! Let’s start by getting to know Flame first.

What is Flutter Flame?

Flutter Flame is an open source game engine for developing Flutter-based 2D games. It allows you to create games for mobile, web and desktop platforms using the Dart language. You can bring the power and flexibility of Flutter to the game world and experience a fast and easy game development experience.

Why Preferable?

First of all, as with Flutter in general, you can create games for Android, iOS and web with a single code base.

Assuming you already have Flutter knowledge, you won’t be overwhelmed by the details of a new technology for your simple game, and you will quickly grasp Flame.

It’s open source, so you can easily get support from the developer community.

Let’s look at the main features of Flame.

Game Loop

Flame allows games to run in a continuous loop. Thanks to this loop, all objects on the game screen are updated and drawn. This loop is based on two main functions:

update(dt): Updates of game objects such as position, state, etc. are done here.

render(canvas): The graphics to be drawn on the screen are defined here.

Component System

Flame offers a component-based approach to creating game objects. You can define and manage objects such as players, enemies, obstacles, etc. as components.

class Player extends PositionComponent {
@override
void render(Canvas canvas) {
// You can write the player drawing codes here
}

@override
void update(double dt) {
// You can write the player update codes here
}
}

Sprite ve Animasyon Desteği

Sprites are graphical elements within the game. Flame allows you to easily manage sprite-based animations.

final sprite = await Sprite.load('player.png');

Çarpışma Tespiti (Collision Detection)

In games, it is important to detect the collision of objects. Flame has a collision detection system that facilitates this process.

bool collision = player.toRect().overlaps(enemy.toRect());

Flame ile Yapılabilecek Basit Bir Oyun Taslağı

In this section, I have prepared an outline that you can use as a guide when you start developing a game.

First, after creating the project, we install the flame package.

flutter pub add flame

Then we can create our Main Game class.

import 'package:flame/game.dart';

class MyGame extends FlameGame {

@override
void render(Canvas canvas) {
// Draw game objects here
}

@override
void update(double dt) {
// Make game updates here
}
}

And finally we start the game.

void main() {
runApp(GameWidget(game: MyGame()));
}

This is of course a very simple and general outline. There are a lot of things to change and improve regarding the game’s features and genre. At this point, there is a repo you can review. It has a lot of resources and examples. After my outline, you can make use of this repo to move forward. And of course you should also read the official documentation. The link to both is below.

As a result, Flutter Flame allows you not only to develop games, but also to make creative projects with your Flutter knowledge. It’s a great opportunity to try yourself in the game world! I hope this was useful.

Thank you.

Selin.

Flutter Flame ile Geleceğe Oynayalım!

 


Herkese merhaba. Bugün sizlere Flame ile ilgili bir rehber hazırladım. Sürekli mobil uygulama geliştirmekten sıkılan, farklı bir şey denemek isteyen, fikri olan ve tanıdık bi yerden hayata geçirmek isteyen geliştiriciler, burası tam size göre! Önce Flame’i tanıyarak başlayalım.

Flutter Flame nedir?

Flutter Flame, Flutter tabanlı 2D oyunlar geliştirmek için kullanılan açık kaynaklı bir oyun motorudur. Dart dilini ullanarak mobil, web ve masaüstü platformları için oyunlar oluşturmanı sağlar. Flutter’ın gücünü ve esnekliğini oyun dünyasına taşıyabilir, hızlı ve kolay bir oyun geliştirme deneyimi yaşayabilirsin.

Neden Tercih Edilebilir?

İlk olarak genel Flutter işleyişinde olduğu gibi burada da tek kod tabanı ile Android, iOS ve web için oyunlar oluşturabilirsin.

Flutter bilgisine zaten sahip olduğunu düşünürsek, geliştireceğin basit oyunun için yeni bir teknolojide detaylara boğulmazsın, Flame’i de hızlıca kavrarsın.

Açık kaynaklıdır bu sebeple geliştirici topluluğundan kolaylıkla destek alabilirsin.

Şimdi Flame’in temel özelliklerine bakalım.

Oyun Döngüsü (Game Loop)

Flame, oyunların sürekli bir döngü (loop) içinde çalışmasını sağlar. Bu döngü sayesinde oyun ekranındaki tüm nesneler güncellenir ve çizilir. Bu döngü iki ana fonksiyona dayanır:

update(dt): Oyun nesnelerinin konum, durum gibi güncellemeleri burada yapılır.

render(canvas): Ekrana çizilecek grafikler burada tanımlanır.

Bileşen Tabanlı Sistem (Component System)

Flame, oyun nesnelerini oluşturmak için bileşen tabanlı bir yaklaşım sunar. Oyuncular, düşmanlar, engeller gibi nesneleri bileşenler olarak tanımlayabilir ve yönetebilirsin.

class Player extends PositionComponent {
@override
void render(Canvas canvas) {
// Oyuncu çizim kodlarını buraya yazabilirsin
}

@override
void update(double dt) {
// Oyuncu güncelleme kodlarını buraya yazabilirsin
}
}

Sprite ve Animasyon Desteği

Sprite’lar, oyun içindeki grafik öğeleridir. Flame, sprite tabanlı animasyonları kolayca yönetmeni sağlar.

final sprite = await Sprite.load('player.png');

Çarpışma Tespiti (Collision Detection)

Oyunlarda nesnelerin çarpışmasını algılamak önemlidir. Flame, bu süreci kolaylaştıran collision detection sistemine sahiptir.

bool collision = player.toRect().overlaps(enemy.toRect());

Flame ile Yapılabilecek Basit Bir Oyun Taslağı

Bu bölümde oyun geliştirmeye başladığında rehber olarak kullanabileceğin bir taslak hazırladım.

İlk olarak projeyi oluşturduktan sonra flame paketini yüklüyoruz.

flutter pub add flame

Sonrasında Ana Oyun sınıfımızı oluşturabiliriz.

import 'package:flame/game.dart';

class MyGame extends FlameGame {
@override
void render(Canvas canvas) {
// Oyun nesnelerini burada çiz
}

@override
void update(double dt) {
// Oyun güncellemelerini burada yap
}
}

Ve son olarak oyunu başlatıyoruz.

void main() {
runApp(GameWidget(game: MyGame()));
}

Bu tabiki çok basit ve genel bir taslak. Oyunun özellikleri ve türü ile ilgili olarak değiştirilecek, geliştirilecek çok fazla şey var. Bu noktada inceleyebileceğin bir repo mevcut. İçeriğinde çok fazla kaynak ve örnek var. Benim genel hatlarıyla oluşturduğum yazımdan sonra buradan faydalanarak ilerleyebilirsin. Ve elbette ki resmi dokümantasyonu da okumanda fayda var. Her ikisinin de linki aşağıda.

Sonuç olarak Flutter Flame, sadece oyun geliştirmekle kalmaz, Flutter bilginle yaratıcı projeler yapmanı sağlar. Kendini oyun dünyasında denemek için harika bir fırsat! Umarım faydalı olmuştur.

Teşekkürler.

Selin.

Performance Optimisation in Unity: Tips for Smoother and More Efficient Games

 

Unity and Performance Optimization

Hello everyone,

In this article, I will talk about performance, which is sometimes overlooked by most developers, including me, in the early stages of the game development process, but is very important. I said very important because performance is a critical factor that directly affects the player experience. In order to offer a smoother and more enjoyable experience to the players and to make our game more demanded and played, we need to develop by paying attention to details such as high frame rates (FPS) and low latency. Unity is a very powerful game engine in this sense, and when used correctly, it helps us develop high-performance games. Since I have experienced that it is so important, I have researched what we can do for performance optimisation with Unity, what are the most effective techniques and tips. Let’s get started.

1. Using Profiler

Unity Profiler is a tool for analysing game performance. Profiler monitors CPU and GPU usage, memory allocation, and other performance metrics. Thanks to this tool, we have the chance to identify the source of performance problems and find solutions for them.

How to use it?

  • First of all, we use Window => Analysis => Profiler to open the Profiler window. With this, we aim to see performance data.
  • Then we run Profiler while playing our game and wait for it to collect data in real time. By analysing the performance in different scenes, we get a feedback from the game.
  • At this point, we analyse the data we collect. For this, we can examine different tabs such as CPU, GPU, Rendering, Memory in the Profiler window and identify performance degrading points here.

2. Optimising Graphics Settings

LOD (Level of Detail) Usage

LOD allows distant objects to be rendered with less detailed models. This improves performance, especially in large scenes, by de-detailing some of the objects in the game.

  • Creating LOD Groups: In a game, we can create different levels of detail to let Unity know which objects should be rendered in more detail and which ones don’t need all the detail. We do this mostly for objects and manage it with the LOD Group component. Thus, especially in large scenes, objects that are not in sight are rendered with less detailed models and performance is increased.
  • Culling: We can improve performance by setting a game plan so that we do not need to render objects outside the camera field of view. We can increase performance by using Occlusion Culling.

Batching Techniques

  • Static Batching: Used for static (motionless) objects. It renders many objects with a single draw call.
  • Dynamic Batching: Used for dynamic (moving) objects. Reduces the number of draw calls by combining small and similar objects.

3. Physics and Collision Optimisation

Rigidbody and Collider Settings

  • Adding Rigidbody component unnecessarily may cause performance degradation. Instead, it is sufficient to add it only to objects that interact physically.
  • Another point about game performance is to use simpler Collider types if possible. Examples of simple Collider types are Box and Sphere. Using Mesh Colliders instead of more standardised ones like these can negatively affect performance.

Physics Simulation

  • Physics simulation is important to make the game realistic. However, physics calculations are often resource intensive, which affects game performance. The first thing we can do to prevent this is to set the Fixed Timestep value. The physics simulation is updated at certain time intervals, not every frame. This interval is called Fixed Timestep and we can set it in Edit => Project Settings => Time. This value is set to 0.02 (50 FPS) by default. We can adjust this value according to our game and performance requirements. A higher value means fewer physics updates, which can improve performance, but may reduce the accuracy of the physics simulation.
  • Another topic is what can be done with Physics Layers. Physics layers control which objects collide with each other. We can use these layers to prevent unnecessary collision checks. First we create new layers in Edit => Project Settings => Tags and Layers. Then we assign objects to the appropriate layers from the Inspector panel. Finally, in Edit => Project Settings => Physics, we determine which layers will collide with each other. For example, there may be collisions between player and bullet layers, but not between background objects and bullets. In this case, the unnecessary collision does not need to run in the background. And certainly not to degrade performance.

4. Memory Management

Object Pooling

  • This method allows us to create a certain number of objects in advance for frequently created and destroyed objects and reuse them. Especially since continuous creation and destruction of new objects can negatively affect performance, we can reduce this cost and prevent performance degradation with object pooling. Let’s also mention a few points to be considered while doing this. It is important to determine the initial size of the pool according to the needs of our game. A pool that is too small may cause continuous creation of new objects; a pool that is too large means unnecessary memory usage. Then what we do will not have the desired effect on performance. We should also keep a good track of the state of the objects. Objects must be made suitable for reuse. For example, bullets should return to the pool when they reach the target or after a certain period of time. Finally, when returning objects to the pool, we must remember to deactivate them. This prevents the objects from performing unnecessary calculations.
  • We also need to avoid creating new objects by caching objects that are used repeatedly.

Memory Usage Monitoring

  • With Unity Profiler we can monitor memory usage and identify unnecessary memory allocations.
  • We also need to minimise GC (Garbage Collection) operations. If we can prevent unnecessary memory allocation and reduce the activation of GC, this also contributes positively to performance.

5. Code Optimisation

Efficient Code Writing

  • LINQ (Language Integrated Query) makes it easier to make queries on data, but the performance cost is high. For this reason, it may be more advantageous to use classic loops and conditions instead of LINQ in parts where we expect high performance.
  • In C#, memory management is performed by Garbage Collector (GC). Memory is allocated when new objects are created and cleared by GC when these objects are not in use. However, unnecessary memory allocations and consequent attempts to delete unnecessary created objects can negatively affect performance.

Asynchronous Operations

  • Async and Await: Performing long-running operations such as network operations or disc read/write asynchronously ensures that the main game loop runs uninterrupted.

As a result, performance optimisation in Unity is of great importance as it makes our games run smoother and more efficiently. In this article, I have tried to explain techniques and tips that will help us improve our performance. I hope that by applying these tips, we can offer a better gaming experience to our players.

Good coding to all of us.

Thanks for reading.

Selin.

Unity’de Performans Optimizasyonu: Daha Akıcı ve Verimli Oyunlar İçin İpuçları

 

Unity ve Performans Optimizasyonu

Herkese merhaba,

Bu yazımda sizlere oyun geliştirme sürecinin ilk aşamalarında ben de dahil olmak üzere çoğu geliştiriciler tarafından zaman zaman göz ardı edilen ancak çok önemli olan performans konusundan bahsedeceğim. Çok önemli dedim çünkü performans oyuncu deneyimini doğrudan etkileyen kritik bir faktör. Oyunculara daha akıcı ve zevkli bir deneyim sunmak ve oyunumuzun daha fazla talep görmesi ve oynanması için yüksek kare hızları (FPS) ve düşük gecikme süreleri gibi detaylara dikkat ederek geliştirme yapmamız gerekiyor. Unity, bu anlamda çok güçlü bir oyun motoru ve doğru kullanıldığında yüksek performanslı oyunlar geliştirmemize oldukça yardımcı oluyor. Bu kadar önemli olduğunu deneyimlediğim için Unity ile performans optimizasyonu için neler yapabiliriz, en etkili teknikler ve ipuçları nelerdir, onları araştırdım. Gelin, başlayalım.

1. Profiler Kullanımı

Unity Profiler, oyunun performansını analiz etmek için kullanılan bir araç. Profiler, CPU ve GPU kullanımını, bellek tahsisini, ve diğer performans metriklerini izliyor. Bu araç sayesinde performans sorunlarının kaynağını tespit edip buna yönelik çözüm üretme şansına sahip oluyoruz.

Nasıl Kullanılır?

  • Öncelikle Profiler’ penceresini açmak için Window => Analysis => Profiler adımlarını kullanıyoruz. Bununla performans verilerini görmeyi amaçlıyoruz.
  • Sonrasında oyunumuzu oynarken Profiler’ı çalıştırıyoruz ve gerçek zamanlı olarak verileri toplamasını bekliyoruz. Farklı sahnelerdeki performansı inceleyerek oyundan bir feedback almış oluyoruz.
  • Bu noktada topladığımız verilerle ilgili analiz yapıyoruz. Bunun için Profiler penceresinde bulunan CPU, GPU, Rendering, Memory gibi farklı sekmeleri inceleyebiliriz ve buradaki performans düşüren noktaları belirleyebiliriz.

2. Grafik Ayarlarını Optimize Etmek

LOD (Level of Detail) Kullanımı

LOD, uzaktaki nesnelerin daha az detaylı modellerle render edilmesini sağlar. Bu, oyundaki nesnelerin bazılarını ayrıntılarından arındırarak özellikle büyük sahnelerde performansı artırır.

  • LOD Grupları Oluşturma: Bir oyunda hangi nesnelerin daha detaylı gösterileceği, hangilerinin tüm detaylarına ihtiyaç duyulmayacağını Unity’e bildirebilmek için farklı detay seviyeleri oluşturabiliriz. Bunu çoğunlukla nesneler için yaparız ve LOD Grubu bileşeni ile yönetiriz Böylelikle özellikle büyük sahnelerde göz önünde olmayan nesneler daha az detaylı modeli ile render edilir ve performans artışı sağlanır.
  • Culling: Kamera görüş alanı dışındaki nesneleri render etmemize gerek olmayacak şekilde bir oyun planı koyarak performans artışı konusunda gelişme sağlayabiliriz. Occlusion Culling kullanarak performansı artırabiliriz.

Batching Teknikleri

  • Static Batching: Statik (hareketsiz) nesneler için kullanılır. Birçok nesneyi tek bir draw call ile render eder.
  • Dynamic Batching: Dinamik (hareketli) nesneler için kullanılır. Küçük ve benzer nesneleri birleştirerek draw call sayısını azaltır.

3. Fizik ve Çarpışma Optimizasyonu

Rigidbody ve Collider Ayarları

  • Gereksiz yere Rigidbody bileşeni eklemek performans düşüşüne sebep olabilir. Bunun yerine sadece fiziksel etkileşime giren nesnelere eklemek yeterlidir.
  • Mümkünse daha basit Collider türlerini kullanmak oyun performansı ile ilgili bir başka nokta. Basit Collider türlerine Box ve Sphere’i örnek verebiliriz. Bu gibi daha standardize edilmişlerin yerine Mesh Collider kullanmak performansı olumsuz etkileyebilir.

Fizik Simülasyonu

  • Fizik simülasyonu oyunu gerçekçi kılmak için önemli. Ancak, fizik hesaplamaları çoğu zaman yoğun kaynak kullanımı gerektiriyor ve bu da oyun performansını etkiliyor. Bunu önlemek için yapabileceğimiz ilk şey Fixed Timestep değerini ayarlamak. Fizik simülasyonu, her çerçevede değil, belirli zaman aralıklarında güncelleniyor. Bu aralık Fixed Timestep olarak adlandırılıyor ve bunu Edit => Project Settings => Time adımlarından ayarlayabiliriz. Bu değer varsayılan olarak 0.02 (50 FPS) olarak ayarlanmıştır. Bu değeri, oyunumuza ve performans gereksinimlerimize göre ayarlayabiliriz. Daha yüksek bir değer daha az fizik güncellemesi anlamına gelir ve bu da performansı artırabilir, ancak fizik simülasyonunun doğruluğunu azaltabilir.
  • Bir diğer konu fizik katmanları (Physics Layers) ile yapılabilecekler. Fizik katmanları, hangi nesnelerin birbirleriyle çarpışacağını kontrol eder. Gereksiz çarpışma kontrollerini önlemek için bu katmanları kullanabiliriz. Önce Edit => Project Settings => Tags and Layers adımlarından yeni katmanlar oluştururuz. Sonrasında nesneleri Inspector panelinden uygun katmanlara atama yaparız. Son olarak Edit => Project Settings => Physics adımlarından hangi katmanların birbirleriyle çarpışacağını belirleriz. Örneğin, oyuncu ve mermi katmanları arasında çarpışma olabilir, ancak arka plan nesneleriyle mermiler arasında çarpışma olmayabilir. Bu durumda gereksiz olan çarpışmanın arka planda çalışmasına gerek yoktur. Ve tabi performansı düşürmesine de.

4. Bellek Yönetimi

Nesne Havuzlama (Object Pooling)

  • Bu yöntem, sıkça oluşturulan ve yok edilen nesneler için önceden belirli sayıda nesne yaratıp bunları yeniden kullanmayı sağlıyor. Özellikle sürekli olarak yeni nesne oluşturma ve yok etme işlemleri performansı olumsuz etkileyebileceğinden, nesne havuzlama ile bu maliyeti azaltabiliyor ve performansın düşmesini engelleyebiliyoruz. Bunu yaparken dikkat edilmesi gereken birkaç noktaya da değinelim. Havuzun başlangıç boyutunu oyunumuzun ihtiyaçlarına göre iyi belirlememiz önemli. Çok küçük bir havuz, sürekli yeni nesne oluşturulmasına neden olabilir; çok büyük bir havuz ise gereksiz bellek kullanımı anlamına gelir. O zaman yaptığımız işlemin performansa istenen yönde bir etkisi olmaz. Ayrıca nesnelerin durumunu da iyi takip etmeliyiz. Nesneler mutlaka tekrar kullanıma uygun hale getirilmeli. Örneğin, mermiler hedefe ulaştığında veya belirli bir süre geçtikten sonra havuza geri dönmeli. Son olarak da nesneleri havuza iade ederken, bunları devre dışı bırakmayı unutmamamız gerekiyor. Bu, nesnelerin gereksiz yere hesaplama yapmasını engeller.
  • Tekrar tekrar kullanılan nesneleri önbelleğe alarak yeni nesne oluşturma işlemlerinden de kaçınmamız gerekiyor.

Bellek Kullanımı İzleme

  • Unity Profiler ile bellek kullanımını izleyip gereksiz bellek tahsislerini belirleyebiliriz.
  • GC (Garbage Collection) işlemlerini de minimize etmemiz gerekir. Gereksiz bellek tahsisini önleyerek GC’nin devreye girmesini azaltabilirsek, bu da performansa olumlu yönde katkı sağlar.

5. Kod Optimizasyonu

Verimli Kod Yazımı

  • LINQ (Language Integrated Query), veriler üzerinde sorgular yapmayı kolaylaştırıyor ancak performans maliyeti yüksek.Bu sebeple yüksek performans beklediğimiz kısımlarda LINQ yerine klasik döngüleri ve koşulları kullanmak daha avantajlı olabilir.
  • C# dilinde bellek yönetimi, Garbage Collector (GC) tarafından gerçekleştiriliyor. Yeni nesneler oluşturulduğunda bellek tahsis ediliyor ve bu nesneler kullanılmadığında GC tarafından temizleniyor. Ancak, gereksiz bellek tahsisleri ve buna bağlı olarak gereksiz oluşturulan nesnelerin silinmeye çalışılması performansı olumsuz etkileyebilir.

Asenkron İşlemler

  • Async ve Await: Ağ işlemleri veya disk okuma/yazma gibi uzun süren işlemleri asenkron olarak gerçekleştirmek ana oyun döngüsünün kesintisiz çalışmasını sağlar.

Sonuç olarak Unity’de performans optimizasyonu, oyunlarımızın daha akıcı ve verimli çalışmasını sağladığından büyük öneme sahip. Ben de bu makalede performansımızı artırmamıza yardımcı olacak teknikler ve ipuçlarını anlatmaya çalıştım. Bu ipuçlarını uygulayarak, oyuncularımıza daha iyi bir oyun deneyimi sunabileceğimizi umuyorum.

Hepimize iyi kodlamalar.

Teşekkürler.

Selin.