Örnek Olay - HTML5 Oyunlarını Otomatik Olarak Yeniden Boyutlandırma

Derek Detweiler
Derek Detweiler

Giriş

2010 yazında, cep telefonları için HTML5 oyunlarıyla ilgili bir yarışmaya katıldığımız Kum Tuzağı oyununu oluşturduk. Ancak çoğu cep telefonu, oyunu yalnızca bir kısmını gösteriyordu veya çok küçük bir ekranda gösteriyordu. Bu da oyunu oynanamaz hale getiriyordu. Bu nedenle, oyunun her çözünürlüğe uyum sağlayacak şekilde akıcı bir şekilde ayarlanmasını kendimize görev edindik. Biraz yeniden programlama ve bu makalede açıklanan fikirleri kullandıktan sonra, masaüstünde veya mobil cihazda çalışan, tüm modern tarayıcılarda ölçeklendirilebilen bir oyunumuz oldu.

Thwack'ın tam ekran görüntüsü
tarayıcı penceresinde thwack smaller ekran görüntüsü

Bu yaklaşım, Sand Trap için işe yaradığı için en son oyunumuz Thwack!'ta da aynı yöntemi kullandık. Oyun, ekran çözünürlüğünü aşağıdaki ekran görüntülerinde gösterildiği gibi hem tam ekrana hem de özel boyutlu pencerelere sığacak şekilde otomatik olarak ayarlar.

Bunu uygulamak için hem CSS hem de JavaScript'ten yararlanmak gerekiyordu. Ekranın tamamını doldurmak için CSS kullanmak basit bir işlemdir ancak CSS, kanvasın ve oyun alanının uzamasını önlemek için aynı genişlik-yükseklik oranını korumanıza izin vermez. İşte bu noktada JavaScript devreye giriyor. JavaScript ile doküman öğelerini yeniden ölçeklendirebilir ve pencere etkinliklerinde yeniden boyutlandırmayı tetikleyebilirsiniz.

Sayfayı hazırlama

İlk adım, sayfadaki oyun alanını belirlemektir. Bunu bir div bloğu olarak eklerseniz içine başka etiketler veya bir kanvas öğesi yerleştirebilirsiniz. Doğru şekilde ayarlandığında bu alt öğeler, üst div bloğunun ölçeklendirmesini devralır.

Oyun alanınızda iki bölüm (oyun alanı ve skor tutma alanı) varsa alanınız aşağıdaki gibi görünebilir:

<div id="gameArea">
 
<canvas id="gameCanvas"></canvas>
 
<div id="statsPanel"></div>
</div>

Temel bir doküman yapısı oluşturduktan sonra bu öğeleri yeniden boyutlandırmaya hazırlamak için birkaç CSS özelliği verebilirsiniz. "gameArea" için CSS özelliklerinin çoğu doğrudan JavaScript tarafından değiştirilir ancak bunların çalışması için üst gameArea div bloğundan başlayarak birkaç CSS özelliği daha ayarlayın:

#gameArea {
 
position: absolute;
 
left:     50%;
 
top:      50%;
}

Bu işlem, kanvasın sol üst köşesini ekranın ortasına getirir. Bir sonraki bölümde açıklanan JavaScript otomatik yeniden boyutlandırma işlevi, oyun alanını yeniden boyutlandırmak ve pencerede ortalanmak için ek CSS özelliklerini kullanır.

Oyun alanı, pencerenin boyutlarına göre otomatik olarak yeniden boyutlandırıldığı için gameArea div bloğunun alt öğelerinin boyutlarını piksel cinsinden değil, yüzde cinsinden belirtmeniz gerekir. Piksel değerleri, iç öğelerin değişen üst div ile ölçeklenmesine izin vermez. Ancak, piksellerle başlayıp beğendiğiniz bir düzene sahip olduktan sonra bunları yüzdelere dönüştürmek yararlı olabilir.

Bu örnekte, oyun alanını 300 piksel yüksekliğinde ve 400 piksel genişliğinde ayarlayın. Kanvas, oyun alanının tamamını kaplar ve Şekil 1'de gösterildiği gibi alt kısımda 24 piksel yüksekliğinde yarı saydam bir istatistik paneli bulunur.

gameArea alt öğelerinin piksel cinsinden boyutları
Şekil 1: gameArea alt öğelerinin piksel cinsinden boyutları

Bu değerleri yüzdeye çevirmek, tuvalin genişliğini% 100 ve yüksekliğini (pencerenin değil, gameArea'nın) %100 yapar. 24'ü 300'e böldüğümüzde istatistik panelinin yüksekliği %8 olarak bulunur. Oyun alanının alt kısmını kapladığı için panelin genişliği de Şekil 2'de görüldüğü gibi %100 olur.

gameArea alt öğelerinin yüzde cinsinden boyutları
Şekil 2: gameArea alt öğelerinin yüzde cinsinden boyutları

Oyun alanının ve alt öğelerinin boyutlarını belirlediğinize göre, içteki iki öğenin CSS özelliklerini aşağıdaki gibi oluşturabilirsiniz:

#gameCanvas {
 
width: 100%;
 
height: 100%;
}
#statsPanel {
 
position: absolute;
 
width: 100%;
 
height: 8%;
 
bottom: 0;
 
opacity: 0.8;
}

Oyunu yeniden boyutlandırma

Artık pencerenin yeniden boyutlandırılmasını işleyen bir işlev oluşturmaya hazırsınız. Öncelikle, üst gameArea doküman öğesine referans alın.

var gameArea = document.getElementById('gameArea');

Tam genişlik veya yükseklikle ilgilenmediğiniz için ayarlamanız gereken bir sonraki bilgi, genişliğin yüksekliğe oranıdır. 400 piksel genişliğinde ve 300 piksel yüksekliğinde bir oyun alanı referansınızı kullanarak en boy oranını 4 birim genişlik ve 3 birim yükseklik olarak ayarlamak istediğinizi biliyorsunuz.

var widthToHeight = 4 / 3;

Bu işlev, pencere boyutu her değiştiğinde çağrılacağı için oyununuzun boyutlarını eşleşecek şekilde ayarlayabilmek için pencerenin yeni boyutlarını da almanız gerekir. Pencerenin innerWidth ve innerHeight özelliklerini kullanarak bunu bulun.

var newWidth = window.innerWidth;
var newHeight = window.innerHeight;

İstediğiniz genişlik-yükseklik oranını belirlediğiniz gibi, pencerenin mevcut genişlik-yükseklik oranını da belirleyebilirsiniz:

var newWidthToHeight = newWidth / newHeight;

Bu sayede, oyunun ekranı dikey mi yoksa yatay mı dolduracağına karar verebilirsiniz (Şekil 3).

En boy oranını korurken gameArea öğesini pencereye sığdırma
Şekil 3: En boy oranını koruyarak gameArea öğesini pencereye sığdırma

İstediğiniz oyun alanı şekli pencerenin şeklinden daha genişse (ve yüksekliği daha kısaysa) pencereyi yatay olarak doldurmanız ve üstte ve altta boşluk bırakmanız gerekir. Benzer şekilde, istenen oyun alanı şekli pencerenin şeklinden daha yüksekse (ve genişlik daha darsa) pencereyi dikey olarak doldurmanız ve solda ve sağda marjlar bırakmanız gerekir.

Bunu yapmak için, istediğiniz genişlik/yükseklik oranını mevcut pencerenin genişlik/yükseklik oranıyla test edin ve aşağıdaki gibi uygun düzenlemeleri yapın:

if (newWidthToHeight > widthToHeight) {
 
// window width is too wide relative to desired game width
  newWidth
= newHeight * widthToHeight;
  gameArea
.style.height = newHeight + 'px';
  gameArea
.style.width = newWidth + 'px';
} else { // window height is too high relative to desired game height
  newHeight
= newWidth / widthToHeight;
  gameArea
.style.width = newWidth + 'px';
  gameArea
.style.height = newHeight + 'px';
}

Oyun alanının genişliğini ve yüksekliğini ayarladıktan sonra, üstte yüksekliğin yarısı ve solda genişliğin yarısı kadar negatif bir kenar boşluğu ekleyerek öğeleri ortalamanız gerekir. CSS'nin, gameArea div'inin sol üst köşesini zaten pencerenin tam ortasına yerleştirdiğini unutmayın. Bu nedenle, oyun alanı pencerenin ortasına yerleştirilir:

gameArea.style.marginTop = (-newHeight / 2) + 'px';
gameArea
.style.marginLeft = (-newWidth / 2) + 'px';

Yazı tipi boyutunu otomatik olarak ayarlamak da isteyebilirsiniz. Tüm alt öğeleriniz em kullanıyorsa gameArea div bloğunun fontSize CSS mülkünü, boyutuna göre belirlenen bir değere ayarlayabilirsiniz.

gameArea.style.fontSize = (newWidth / 400) + 'em';

Son olarak, kanvas çizim boyutlarını yeni genişlik ve yükseklikle eşleştirin. Oyun kodunun geri kalanının, dinamik bir tuval çözünürlüğünü karşılamak için oyun motoru boyutlarını tuval çizim boyutlarından ayrı tutması gerektiğini unutmayın.

var gameCanvas = document.getElementById('gameCanvas');
gameCanvas
.width = newWidth;
gameCanvas
.height = newHeight;

Bu nedenle, tamamlanmış yeniden boyutlandırma işlevi aşağıdaki gibi görünebilir:

function resizeGame() {
   
var gameArea = document.getElementById('gameArea');
   
var widthToHeight = 4 / 3;
   
var newWidth = window.innerWidth;
   
var newHeight = window.innerHeight;
   
var newWidthToHeight = newWidth / newHeight;
   
   
if (newWidthToHeight > widthToHeight) {
        newWidth
= newHeight * widthToHeight;
        gameArea
.style.height = newHeight + 'px';
        gameArea
.style.width = newWidth + 'px';
   
} else {
        newHeight
= newWidth / widthToHeight;
        gameArea
.style.width = newWidth + 'px';
        gameArea
.style.height = newHeight + 'px';
   
}
   
    gameArea
.style.marginTop = (-newHeight / 2) + 'px';
    gameArea
.style.marginLeft = (-newWidth / 2) + 'px';
   
   
var gameCanvas = document.getElementById('gameCanvas');
    gameCanvas
.width = newWidth;
    gameCanvas
.height = newHeight;
}

Artık pencere yeniden boyutlandırıldığında veya mobil cihazlarda ekran yönü değiştirildiğinde bu ayarlamaların otomatik olarak yapılmasını istiyorsunuz. Bu etkinlikleri, resizeGame() işlevinizi şu şekilde çağırarak ele alın:

window.addEventListener('resize', resizeGame, false);
window
.addEventListener('orientationchange', resizeGame, false);

Pencerenin boyutu çok yüksekse veya ekranın yönü dikeyse genişliği pencerenin% 100'ü, pencerenin boyutu çok genişse veya ekranın yönü yataysa yüksekliği pencerenin% 100'ü yaparsınız. Kalan boyut, önceden belirlenmiş genişlik-yükseklik en boy oranına göre boyutlandırılır.

Özet

Gopherwood Studios, tüm HTML5 oyunlarımız için bu yapının sürümlerini kullandı ve bu yapı, birden fazla ekran çözünürlüğünü ve çeşitli mobil cihazları barındırmak için çok faydalı oldu. Ayrıca, tam ekran tarayıcı sayesinde web oyunlarımız, birçok tarayıcı tabanlı oyundan daha geleneksel masaüstü oyunlarına benzer bir sürükleyici deneyim sunar. HTML5 ve web teknolojileri gelişmeye devam ettikçe web oyunlarında daha fazla yenilik görmeyi umuyoruz.