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 ​