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
- Hızlı yüklenen bir web oyunu yayınlayın
- Mobil uyumlu web oyunları
- İçerik üreticileri için
- COOP/COEP ve SharedArrayBuffer — iframe yerleştirmesini etkileyen farklı kaynak üstbilgileri
- Oyununuzu itch.io'da nasıl yayımlarsınız? — itch.io, tarayıcı oyunlarını yerel olarak iframe'lere yerleştirir
Harici kaynaklar
- MDN: iframe öğesi — iframe öznitelikleri için eksiksiz başvuru
- MDN: İzin Politikası — iframe'lerin hangi özellikleri kullanabileceğini kontrol etme
- MDN: postMessage API'si — iframe ile üst sayfa arasında iletişim kurma