Skip to content

Oyunları iframe ile yerleştirmek için en iyi uygulamalar

Birçok platform (Itch.io, Newgrounds, Cinevva ve kendi siteniz) oyunları iframe'ler içinde yerleştirir. Bu eğitim, oyununuzun iframe içinde sorunsuz çalışmasını nasıl sağlayacağınızı ele alır.

1) Temel yerleştirilebilir yapı

Oyununuz, sayfanın tamamını kontrol etmeyi gerektirmeden çalışmalıdır:

html
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>
    * { margin: 0; padding: 0; }
    html, body { width: 100%; height: 100%; overflow: hidden; }
    canvas { display: block; width: 100%; height: 100%; }
  </style>
</head>
<body>
  <canvas id="game"></canvas>
  <script src="game.js"></script>
</body>
</html>

2) Iframe bağlamını algılama

js
const isEmbedded = window.self !== window.top

if (isEmbedded) {
  // Davranışı yerleştirilmiş bağlama göre ayarla
  hideExternalLinks()
  adjustUIForSmallSize()
}

function hideExternalLinks() {
  document.querySelectorAll('a[target="_blank"]').forEach(link => {
    link.style.display = 'none'
  })
}

3) Gerekli iframe izinlerini sağlama

Üst sayfa, iframe'inizin neler yapabileceğini kontrol eder. Yaygın izinler:

html
<iframe 
  src="https://game.example.com"
  allow="fullscreen; autoplay; gamepad; pointer-lock"
  sandbox="allow-scripts allow-same-origin allow-pointer-lock allow-popups"
></iframe>

Oyununuz, eksik izinleri sorunsuz biçimde ele almalıdır:

js
// Tam ekran özelliğinin kullanılabilir olup olmadığını kontrol et
const canFullscreen = document.fullscreenEnabled || document.webkitFullscreenEnabled

if (!canFullscreen) {
  document.getElementById('fullscreen-btn').style.display = 'none'
}

4) Iframe içinden tam ekrana geçme

Tam ekran için allow="fullscreen" özniteliği gerekir:

js
async function requestFullscreen() {
  const elem = document.documentElement
  
  try {
    if (elem.requestFullscreen) {
      await elem.requestFullscreen()
    } else if (elem.webkitRequestFullscreen) {
      await elem.webkitRequestFullscreen()
    }
  } catch (err) {
    // Tam ekrana izin verilmiyor; mesaj göster
    showMessage('Yerleştirilmiş durumdayken tam ekran kullanılamıyor')
  }
}

5) Üst sayfayla iletişim kurma

Farklı kaynaklar arasında güvenli iletişim için postMessage kullanın:

Oyununuzda:

js
// Üst sayfaya mesaj gönder
function notifyParent(type, data) {
  if (window.parent !== window) {
    window.parent.postMessage({ type, data, source: 'game' }, '*')
  }
}

// Üst sayfadan gelen mesajları al
window.addEventListener('message', (event) => {
  // Gerekirse kaynağı doğrula
  // if (event.origin !== 'https://trusted-host.com') return
  
  const { type, data } = event.data
  
  switch (type) {
    case 'pause':
      pauseGame()
      break
    case 'resume':
      resumeGame()
      break
    case 'setVolume':
      setVolume(data.volume)
      break
  }
})

// Oyun hazır olduğunda bildir
window.addEventListener('load', () => {
  notifyParent('ready', { width: 800, height: 600 })
})

// Oyun olaylarını bildir
function onGameOver(score) {
  notifyParent('gameover', { score })
}

Üst sayfada:

js
const iframe = document.getElementById('game-iframe')

iframe.addEventListener('load', () => {
  // Oyundan gelen mesajları dinle
  window.addEventListener('message', (event) => {
    if (event.source !== iframe.contentWindow) return
    if (event.data.source !== 'game') return
    
    const { type, data } = event.data
    
    if (type === 'ready') {
      console.log('Oyun hazır:', data)
    }
    if (type === 'gameover') {
      showScoreModal(data.score)
    }
  })
})

// Oyuna komut gönder
function pauseGame() {
  iframe.contentWindow.postMessage({ type: 'pause' }, '*')
}

6) Odağı yönetme

Iframe'ler odağı kaybederek klavye girişinin çalışmamasına neden olabilir:

js
// Tıklandığında canvas'a otomatik olarak odaklan
canvas.addEventListener('click', () => {
  canvas.focus()
})

// Canvas'ı odaklanabilir hâle getir
canvas.tabIndex = 1

// Odak kaybını işle
window.addEventListener('blur', () => {
  // Basılı tutulan tuşları sıfırla
  input.left = input.right = input.up = input.down = false
  
  if (isEmbedded) {
    // İsteğe bağlı olarak duraklat
    // pauseGame()
  }
})

// Üst sayfadan odak iste
function requestFocus() {
  notifyParent('requestFocus', {})
}

7) Duyarlı yerleştirme boyutu

Farklı yerleştirme boyutlarını destekleyin:

js
function handleResize() {
  const width = window.innerWidth
  const height = window.innerHeight
  
  // Kullanıcı arayüzünü boyuta göre ayarla
  if (width < 400 || height < 300) {
    enableCompactUI()
  } else {
    enableFullUI()
  }
  
  // Oyunu uygun şekilde ölçeklendir
  resizeCanvas(width, height)
}

window.addEventListener('resize', handleResize)
handleResize()

8) Yerleştirmeler için yükleme göstergesi

Hemen bir şeyler gösterin:

js
// Anında görüntülemek için HTML içine yerleştir
const loadingHTML = `
  <div id="loading" style="
    position: fixed;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #1a1a2e;
    color: #fff;
    font-family: sans-serif;
  ">
    <div>
      <div class="spinner"></div>
      <p>Yükleniyor...</p>
    </div>
  </div>
`

// Oyun hazır olduğunda kaldır
function hideLoading() {
  const loading = document.getElementById('loading')
  if (loading) {
    loading.style.opacity = '0'
    loading.style.transition = 'opacity 0.3s'
    setTimeout(() => loading.remove(), 300)
  }
}

9) Platforma özgü SDK'lar

Bazı platformların kendi API'leri vardır:

Itch.io:

js
// SDK gerekmez ancak başarımlar için postMessage kullanılabilir
window.parent.postMessage({ type: 'itch-achievement', data: { id: 'first-win' }}, '*')

Newgrounds:

js
// Newgrounds.io SDK'sını ekle
const ngio = new Newgrounds.io.core('APP_ID', 'AES_KEY')
ngio.callComponent('Medal.unlock', { id: 12345 })

Cinevva:

js
// Oyunun hazır olduğunu bildir
window.parent.postMessage({ type: 'cinevva:ready' }, '*')

// Oynanabilir duruma geldiğini bildir
window.parent.postMessage({ type: 'cinevva:playable' }, '*')

10) Güvenlik hususları

js
// Hassas işlemlerde mesaj kaynaklarını doğrula
window.addEventListener('message', (event) => {
  const trustedOrigins = [
    'https://itch.io',
    'https://cinevva.com',
    'https://yoursite.com'
  ]
  
  if (!trustedOrigins.includes(event.origin)) {
    return // Güvenilmeyen mesajları yok say
  }
  
  // Mesajı işle...
})

// Hassas işlemleri postMessage üzerinden kullanıma açma
// Yalnızca izin verilenler listesindeki komutları kabul et
const allowedCommands = ['pause', 'resume', 'setVolume', 'mute']

window.addEventListener('message', (event) => {
  const { type } = event.data
  if (!allowedCommands.includes(type)) return
  
  // Komutu işle...
})

Test kontrol listesi

  • Yerel test: file:// yerine basit bir HTTP sunucusu kullanın
  • Farklı kaynaklar: Gerçek bir iframe yerleştirmesiyle test edin
  • İzinler: Kısıtlı bir sandbox ile test edin
  • Odak: Iframe'in dışına tıkladıktan sonra klavyeyi test edin
  • Yeniden boyutlandırma: Farklı yerleştirme boyutlarında test edin
  • Mobil: Yerleştirilmiş bağlamda dokunmatik kontrolleri test edin
html
<!-- Yerleştirme test sayfası -->
<!DOCTYPE html>
<html>
<body style="background: #333; padding: 20px;">
  <h1 style="color: #fff;">Yerleştirme Testi</h1>
  <iframe 
    src="http://localhost:8000" 
    width="800" 
    height="600"
    allow="fullscreen; autoplay; gamepad"
  ></iframe>
</body>
</html>

İlgili içerikler

Harici kaynaklar