Rive Animasyonuyla Arapça Karakterler Nasıl Canlandırılır?
5 dk okumaMohammad Shaker

Rive Animasyonuyla Arapça Karakterler Nasıl Canlandırılır?

Amal uygulaması, Rive animasyonlarıyla Arapça karakterleri canlı ve etkileşimli hale getirir. Rive, performans ve kontrol avantajlarıyla tercih edildi.

Engineering

Hızlı cevap

Amal uygulaması, Rive animasyonlarıyla Arapça karakterleri canlı ve etkileşimli hale getirir. Rive, performans ve kontrol avantajlarıyla tercih edildi.

Rive Animasyon Sürecimiz: Arapça Karakterleri Canlandırmak

Amal, tüm karakter animasyonları için Rive (eski adıyla Flare) kullanıyor — dudak senkronlu konuşma, avatar kişiselleştirme, geri bildirim reaksiyonları ve oyun karakterleri dahil. Rive’yi Lottie veya sprite sayfaları yerine seçmemizin sebebi; çalışma zamanında durum makinelerini desteklemesi, programatik manipülasyonu ve 60fps GPU hızlandırmalı render’ı tek ve kompakt bir dosyada sunmasıdır.

Animasyon Varlık Kütüphanesi

Temel Karakterler

  • lip-sync-amal-01.riv
    - Ana Amal karakteri (tam vücut ve sadece yüz versiyonları)
    - Her ağız pozisyonu için birden fazla artboard (fonem eşleştirme için)
    - Durumlar: boşta, konuşma, hata, kutlama, uyuma
    - Dosya boyutu: 1.2 MB (sprite sayfalarına kıyasla 50+ MB yerine)
  • avatar.riv
    - Özelleştirilebilir kullanıcı avatarı (3 artboard)
    1. Tam vücut: baş, gövde, uzuvlar ve kıyafetler
    2. Sadece baş: kontrol paneli ve ebeveyn uygulaması için
    3. Kelebek dost: ödül animasyonu
    - Bileşen bazlı: baş şekli, saç, gözler, kıyafetler, aksesuarlar, renkler
    - Dosya boyutu: 2.4 MB
  • coin-01.riv & coins-01.riv
    - Ödül animasyonları (yüzen ve toplanan paralara yönelik)
    - Tek madeni para: 150 KB
    - Çoklu paralar: 300 KB
  • cute-monster-final.riv
    - Çoklu duygu durumları olan geri bildirim karakteri
    - Durumlar: mutlu (doğru cevap), kafası karışık (yanlış), düşünüyor (işleme), kutlama (seriyi devam ettirme)
    - Dosya boyutu: 1.8 MB

Android-Özel Optimizasyon

  • 16KB sayfa hizalaması için özel NDK derlemesi (Rive NDK-r28)
  • Standart derlemeye göre ikili dosya boyutunu %8 azaltır
  • Android 12+ agresif bellek yönetimi ile uyumluluğu garanti eder

Dudak Senkronizasyonu Süreci (Teknik Detaylar)

Adım 1: TTS Ses Üretimi ve Konuşma İşaretlerinin Çıkarılması

# src/services/tts_client.py
from google.cloud import texttospeech

def generate_speech_with_marks(text: str, language: str = 'ar-SA'):
    client = texttospeech.TextToSpeechClient()
    
    synthesis_input = texttospeech.SynthesisInput(text=text)
    voice = texttospeech.VoiceSelectionParams(
        language_code=language,
        name='ar-SA-Neural2-A'  # WaveNet sesi
    )
    audio_config = texttospeech.AudioConfig(
        audio_encoding=texttospeech.AudioEncoding.MP3,
        effects_profile_id=['small-bluetooth-speaker-class-device']  # Çocuk hoparlörü
    )
    
    # Konuşma işaretleri (fonem zamanlaması) talebi
    request = texttospeech.SynthesizeSpeechRequest(
        input=synthesis_input,
        voice=voice,
        audio_config=audio_config,
        enable_text_to_speech_as_cloud_service=True
    )
    
    response = client.synthesize_speech(request=request)
    
    # Yanıtta:
    # - audio_content: MP3 verisi
    # - timepoints: [{character, byte_pos, time_ms}, ...]
    
    return {
        'audio': response.audio_content,
        'speech_marks': response.timepoints  # Fonem düzeyinde zaman damgaları
    }

Adım 2: Fonemlerin Rive Ağız Durumlarına Haritalanması

lip_sync_avatar.json Arapça fonemleri ağız pozisyonlarına eşler:

{
  "phoneme_map": {
    "ا": { "rive_state": "mouth_a_open", "duration_ms": 200 },
    "ب": { "rive_state": "mouth_lips_closed", "duration_ms": 150 },
    "ع": { "rive_state": "mouth_pharyngeal", "duration_ms": 250 },
    "ق": { "rive_state": "mouth_uvular", "duration_ms": 180 },
    ...
  },
  "mouth_positions": [
    { "id": "mouth_a_open", "blend_values": { "jaw_open": 0.8, "lips_rounded": 0.2 } },
    { "id": "mouth_lips_closed", "blend_values": { "jaw_open": 0.1, "lips_rounded": 0.9 } },
    ...
  ]
}

Adım 3: LipSyncController Oynatmayı Yönetir

// lib/src/modules/animations/controllers/lip_sync_controller.dart
class LipSyncController extends GetxController {
  late Rive riveCharacter;
  late AudioPlayer audioPlayer;
  late LipSyncMapper mapper;
  
  void playWithLipSync(String text, String audioPath) {
    // 1. Rive karakterini yükle
    riveCharacter.loadRiveFile('lip-sync-amal-01.riv');
    
    // 2. TTS çıktıdan konuşma işaretlerini yükle
    mapper = LipSyncMapper.fromJson(loadJsonAsset('lip_sync_avatar.json'));
    
    // 3. Ağız animasyonunu çalıştırarak sesi oynat
    audioPlayer.play(AudioSource.file(audioPath));
    
    // 4. Her ses pozisyonunda ağız durumunu güncelle
    audioPlayer.onPositionChanged.listen((Duration position) {
      String phoneme = mapper.phonemeAtTime(position.inMilliseconds);
      String riveState = mapper.riveStateForPhoneme(phoneme);
      
      riveCharacter.setStateInput('mouth_state', riveState);
    });
  }
}

Adım 4: RiveCharacterController Karakter Yaşam Döngüsünü Yönetir

// Karakterin tüm animasyon durumlarını yönetir (sadece ağız değil)
class RiveCharacterController extends GetxController {
  States: boşta → hazırlık → konuşma → boşta → hata/kutlama
  
  void startExercise() {
    // Karakter geçişleri: boşta → hazırlık (dinlemeye hazır)
    character.setStateInput('state_machine', 'prepare');
  }
  
  void childSpeaks(String recognizedText, double accuracy) {
    character.setStateInput('state_machine', 'speaking');
    lipSyncController.playFeedback(recognizedText);
  }
  
  void onFeedbackComplete(bool wasCorrect) {
    if (wasCorrect) {
      character.setStateInput('state_machine', 'celebrate');
      playRewardAnimation();
    } else {
      character.setStateInput('state_machine', 'error');
      playEncouragingPhrase();
    }
  }
}

Avatar Kişiselleştirme Sistemi

Bileşen Tabanlı Mimari

Çocuklar avatarlarını parçalardan kişiselleştirir:

{
  "avatar_customization": {
    "head_shapes": [
      { "id": "round", "rive_element": "head_round" },
      { "id": "oval", "rive_element": "head_oval" },
      { "id": "square", "rive_element": "head_square" }
    ],
    "hair_styles": [
      { "id": "ponytail", "rive_element": "hair_ponytail" },
      { "id": "braids", "rive_element": "hair_braids" },
      { "id": "straight", "rive_element": "hair_straight" }
    ],
    "colors": {
      "skin_tone": ["light", "medium", "dark"],
      "hair_color": ["black", "brown", "blonde", "red"],
      "shirt_color": ["blue", "pink", "green", "yellow", "purple"],
      "accent_color": ["red", "orange", "green", "blue"]
    }
  }
}

Rive Adlandırılmış Elemanlar Haritası (avatar_customization_rive_names.dart)

const avatarRiveNames = {
  'head_round': 'Head_Round',
  'head_oval': 'Head_Oval',
  'hair_ponytail': 'Hair_Ponytail',
  'shirt_blue': 'Shirt_Blue',
  'shirt_pink': 'Shirt_Pink',
  // ... 50+ eleman eşleştirmesi
};

Çocuk "yuvarlak baş + mavi gömlek" seçtiğinde uygulama şunları yapar:
1. Rive elemanı Head_Round etkinleştirilir
2. Rive elemanı Shirt_Blue etkinleştirilir
3. Diğer tüm baş şekilleri ve gömlek renkleri devre dışı bırakılır
4. Çocuğun kişiselleştirilmiş avatarı uygulamanın her yerinde görünür

Neden Alternatifler Değil de Rive?

ÖzellikRiveLottieSprite SayfalarıVideo
Durum makineleri
Çalışma zamanı kontrolü✓ (tam)ParçalıManuel✗ (pasif)
Dosya boyutu1-2 MB2-3 MB50+ MB100+ MB
Performans60fps GPU30fps CPU60fps GPUDeğişken
İnteraktivite✓ Tam✓ Parçalı✓ Tam✗ Yok
Öğrenme eğrisiOrtaKolayKolayKolay
BakımTek .riv dosyaTek JSONYüzlerce resimTek video

Rive kazandı: Programatik kontrol, durum makineleri ve kompaktlık, mobil uygulamada ihtiyaç duyduğumuz özelliklerdir.

Performans Optimizasyonu

  • Karakter ön yükleme: Uygulama açılışında .riv dosyalarını yükleyin, her egzersizde değil
  • GPU desteği: Rive, uygun cihazlarda otomatik GPU kullanır, eski cihazlarda CPU geri dönüşümü
  • Bellek havuzu: Rive denetleyicilerini ekranlar arasında yeniden kullanarak çöp toplama gecikmelerini önleyin
  • Sıkıştırma: Rive dosyaları zaten sıkıştırılmıştır, ekstra optimizasyona gerek yoktur

Sonuç: Snapdragon 662+ (2019 orta segment telefonlar) üzerinde 60fps animasyonlar sağlanmıştır.

Sıkça Sorulan Sorular

S: Adobe Animate’den Rive’ye animasyon aktarabilir miyim?
C: Doğrudan değil. Biz Rive'nin kendi editörü (rive.app) ile çalışıyoruz. Animatörler Rive'de tasarlar, Animate veya After Effects değil. İş akışı: Rive’de karakter tasarlanır → .riv olarak dışa aktarılır → Flutter uygulamasına entegre edilir.

S: Farklı beden tipleri veya engeller nasıl yönetiliyor?
C: Avatar kişiselleştirme; zayıf, atletik, yuvarlak beden tipi seçenekleri ve gözlük, işitme cihazları, hareket destekleri gibi aksesuarlar içerir. Böylece tüm çocuklar kendilerini temsil edilmiş hisseder.

S: Çocuk avatarını beğenmezse ne olur?
C: İstediği zaman avatarı kişiselleştirebilir. Uygulama tek tip bir görünüm dayatmaz — çocuklar tam yaratıcı özgürlüğe sahiptir.

İlgili Makaleler