Skip to content

Best Practices

Bu sayfa, mini-app geliştirirken dikkat etmen gereken kritik konuları ve önerilen kalıpları içerir.


Ekran Kesimi (Notch / Dynamic Island)

Birçok iPhone ve Android cihazda ekranın üstünde ön kamera kesimi (notch, Dynamic Island veya punch-hole) ve altında home indicator bulunur. Mini-app tam ekran açıldığında bu alanlar oyun UI'ının üstüne gelebilir.

Temel Kural

Arka planı tam ekran yap, UI elementlerini safe zone içinde tut.

┌─────────────────────────────┐
│   [ Dynamic Island ]        │  ← Arka plan buraya uzanır (tam ekran hissi)
│─────────────────────────────│
│  ❤️❤️❤️        SKOR: 500   │  ← UI elementleri safe zone'dan başlar
│                             │
│      OYUN ALANI             │
│                             │
│─────────────────────────────│
│        ▬ (swipe bar)        │  ← Arka plan buraya da uzanır
└─────────────────────────────┘

Cihaz Değerleri

Cihaztopbottom
iPhone 16 / 15 Pro (Dynamic Island)59dp34dp
iPhone 13 / 14 (notch)47dp34dp
iPhone SE / 8 (fiziksel home)20dp0dp
Android gesture nav + cutout27–40dp24–48dp
Android gesture nav, cutout yok0dp24–48dp

CSS ile Kullanım (Önerilen)

Platform, WebView yüklenince CSS değişkenlerini otomatik inject eder:

css
/* Arka plan tam ekran — notch arkasına da uzanır */
body {
  background: #1a1a2e;
  /* Safe area için padding EKLEME — arka plan taşsın */
}

/* Sadece UI container'larına safe area uygula */
.game-hud {
  padding-top: var(--sa-top, 0px);
  padding-bottom: var(--sa-bottom, 0px);
  padding-left: var(--sa-left, 0px);
  padding-right: var(--sa-right, 0px);
}

.score-panel {
  /* Üstten güvenli alana çek */
  margin-top: var(--sa-top, 0px);
}

.bottom-bar {
  /* Alttan güvenli alana çek */
  padding-bottom: calc(var(--sa-bottom, 0px) + 8px);
}

JS ile Kullanım

js
const insets = supergame.getSafeAreaInsets()
// { top: 59, bottom: 34, left: 0, right: 0 }

// Canvas tabanlı oyunlarda manuel layout ayarı
if (insets.top > 0) {
  uiCamera.y = insets.top
}
if (insets.bottom > 0) {
  bottomBar.y = screenHeight - insets.bottom - bottomBar.height
}

// Notch var mı kontrolü
const hasNotch = insets.top > 20

Yanlış Kullanım ❌

css
/* YANLIŞ: body'ye padding verirsen arka plan taşmaz, beyaz boşluk oluşur */
body {
  padding-top: var(--sa-top, 0px); /* ❌ */
}

Doğru Kullanım ✅

css
/* DOĞRU: body tam ekran, sadece içerik container'ı inset alır */
body {
  background: #1a1a2e; /* arka plan taşar */
}
.hud {
  padding-top: var(--sa-top, 0px); /* ✅ içerik inset alır */
}

Lifecycle: Arka Plan / Ön Plan

Mini-app Discovery feed'inde kaydırılarak ekrandan çıktığında veya overlay menüden arka plana gönderildiğinde platform otomatik olarak:

  • WebView içindeki tüm <audio> ve <video> elementlerini pause eder
  • Gyroscope / accelerometer stream'lerini durdurur
  • Multiplayer (WebSocket) bağlantılarını açık bırakır

Ancak oyun döngüsünü (game loop) ve arka plan müziğini durdurma/devam ettirme işlemi geliştiriciye kalır.

Müzik / Ses Yönetimi

Önemli

Platform ses dosyalarını otomatik pause eder ama tekrar çalmaz. onForeground'da müziği kendin başlatmalısın.

js
const bgMusic = new Audio('music.mp3')
bgMusic.loop = true

// Sayfa yüklendiğinde başlat
bgMusic.play()

supergame.onBackground(() => {
  // Platform zaten pause etti — ekstra bir şey yapmana gerek yok
  // Ama game loop'u durdur:
  gameLoop.stop()
})

supergame.onForeground(() => {
  // Müziği yeniden başlat (platform başlatmaz)
  bgMusic.play().catch(() => {})
  // Game loop'u devam ettir
  gameLoop.start()
})
csharp
void Start()
{
    SuperGame.onBackground(() => {
        // Platform audio elementi pause eder
        // Ek Unity AudioSource varsa kendin durdur:
        bgMusicSource.Pause();
        Time.timeScale = 0f;
    });

    SuperGame.onForeground(() => {
        // Müziği yeniden başlat
        bgMusicSource.Play();
        Time.timeScale = 1f;
    });
}
gdscript
func _ready():
    gameTegra.onBackground(func():
        # Oyunu durdur
        get_tree().paused = true
        $BGMusic.stream_paused = true
    )
    gameTegra.onForeground(func():
        # Devam ettir
        get_tree().paused = false
        $BGMusic.stream_paused = false
    )

Multiplayer Bağlantısı Açık Kalır

Gyroscope gibi sensor stream'ler durdurulur ama multiplayer bağlantıları canlı kalır. Oyuncu geri döndüğünde sunucudan kaçırılan olayları çekebilirsin:

js
supergame.onForeground(() => {
  gameLoop.start()
  bgMusic.play().catch(() => {})

  // Arka planda kaçırılan olayları sorgula
  syncMissedEvents()
})

Unsubscribe

Callback artık gerekmiyorsa bellek sızıntısını önlemek için kaldır:

js
const unsubBg = await supergame.onBackground(() => { ... })
const unsubFg = await supergame.onForeground(() => { ... })

// Sahne değiştiğinde ya da temizlik sırasında:
unsubBg()
unsubFg()

Özet Kontrol Listesi

Yayına almadan önce şunları kontrol et:

  • [ ] Oyun HUD'u notch/Dynamic Island arkasında kalmıyor
  • [ ] body tam ekran arka plan rengi var — --sa-top/--sa-bottom ile padding yok
  • [ ] onBackground'da game loop durduruluyor
  • [ ] onForeground'da müzik yeniden başlatılıyor
  • [ ] Multiplayer bağlantısı arka planda kesilmiyor (platform bunu zaten garanti eder)
  • [ ] Unsubscribe fonksiyonları sahne temizliğinde çağrılıyor