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

Derek Detweiler
Derek Detweiler

Giriş

2010 yazında, cep telefonları için düzenlenen HTML5 oyunlarıyla ilgili bir yarışmaya girdiğimiz Sand Trap oyununu geliştirdik. Ancak çoğu cep telefonu ya oyunun yalnızca bir kısmını gösteriyor ya da oyunu çok küçük tutarak tamamen oynanamıyor. Bu nedenle, oyunu her çözünürlüğe uyacak şekilde akıcı bir şekilde ayarlamaya karar verdik. Bu makalede açıklanan fikirleri biraz yeniden programlamadan ve kullandıktan sonra, ister masaüstü ister mobil cihazda çalışsın, tüm modern tarayıcılarda çalışan bir oyun ortaya çıktı.

Thwack tam ekran ekran görüntüsü
tarayıcı penceresindeki thwack daha küçük ekran görüntüsü

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

Bunu uygulamak için hem CSS'den hem de JavaScript'ten yararlanmak gerekiyordu. Ekranın tamamını doldurmak için CSS kullanmak çok kolay değildir, ancak CSS, tuvalin ve oyun alanının esnemesini önlemek için aynı genişlik-yükseklik oranını korumanıza izin vermez. İşte JavaScript burada devreye giriyor. Doküman öğelerini JavaScript ile yeniden ölçeklendirebilir ve pencere etkinliklerinde yeniden boyutlandırmayı tetikleyebilirsiniz.

Sayfa Hazırlanıyor

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

Oyun alanınızın, bir oyun alanı ve bir skor tutma alanı olmak üzere iki bölümü varsa, bu alan 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ına sahip olduktan sonra bu öğelere birkaç CSS özelliği vererek onları yeniden boyutlandırmaya hazırlayabilirsiniz. "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ğuyla başlayarak birkaç CSS daha özelliği daha ayarlayın:

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

Kanvasın sol üst köşesi, ekranın ortasına yerleştirilir. Bir sonraki bölümde açıklanan JavaScript otomatik yeniden boyutlandırma işlevi, oyun alanını yeniden boyutlandırmak ve pencerede ortalamak için ek CSS özelliklerini değiştirir.

Oyun alanı, pencerenin boyutlarına göre otomatik olarak yeniden boyutlandırıldığından gameArea div blokunun alt öğeleri için boyutları piksel cinsinden değil, yüzde cinsinden boyutlarda istersiniz. Piksel değerleri, iç öğelerin, değiştikçe üst div ile ölçeklenmesine izin vermez. Ancak, piksellerle başlamak ve istediğiniz gibi bir düzen elde ettikten sonra bunları yüzdelere dönüştürmek yararlı olabilir.

Bu örnekte, oyun alanının 300 piksel yüksekliğinde ve 400 piksel genişliğinde olmasıyla başlayın. Tuval, tüm oyun alanını kaplar ve Şekil 1'de gösterildiği gibi, alt kısımda 24 piksel yüksekliğinde yarı saydam bir istatistik paneli uzanır.

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

Bu değerleri yüzdelere çevirmek, tuvalin genişliğini% 100, yüksekliği% 100 (pencere yerine gameArea için) yapar. 24'ü 300'e bölerseniz istatistik panelinin yüksekliği %8 olur ve Şekil 2'de görüldüğü gibi oyun alanının alt kısmını kaplayacağı için genişliği de %100 olur.

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

Artık oyun alanının ve alt öğelerinin boyutlarını belirlediğinize göre, iki iç öğenin CSS özelliklerini aşağıdaki gibi bir araya getirebilirsiniz:

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

Oyunu Yeniden Boyutlandırma

Artık yeniden boyutlandırılan pencereyi işleyecek bir işlev oluşturmaya hazırsınız. Önce üst gameArea belge öğesine bir referans alın.

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

Tam genişlik veya yükseklikle ilgili endişeniz olmadığından, ayarlamanız gereken bir sonraki bilgi genişliğin yüksekliğe oranıdır. Önceki referans olarak 400 piksel genişliğinde ve 300 piksel yüksekliğindeki bir oyun alanına başvurduğunuzda, en boy oranını 4 birim genişliğinde ve 3 birim yüksekliğinde ayarlamak istediğinizi biliyorsunuz.

var widthToHeight = 4 / 3;

Pencere yeniden boyutlandırıldığında bu işlev çağrıldığından, oyununuzun boyutlarını eşleşecek şekilde ayarlayabilmek için pencerenin yeni boyutlarını da elde etmeniz gerekir. Bunu, pencerenin InnerWidth ve InnerHeight özelliklerini kullanarak bulabilirsiniz.

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

Tıpkı genişliğin yüksekliğe oranını istediğiniz gibi belirlediğiniz gibi, şimdi de pencerenin mevcut genişlik-yükseklik oranını belirleyebilirsiniz:

var newWidthToHeight = newWidth / newHeight;

Bu şekilde, Şekil 3'te gösterildiği gibi oyunun ekranı dikey mi yoksa yatay mı dolduracağına karar verebilirsiniz.

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

İstenilen oyun alanının şekli pencerenin şeklinden genişse (ve yüksekliği daha kısaysa) pencereyi yatay olarak doldurmanız, üste ve alt kısımları boyunca kenar boşlukları bırakmanız gerekir. Benzer şekilde, istenen oyun alanının şekli pencerenin şeklinden yüksekse (ve genişlik daha darsa) pencereyi dikey olarak doldurmanız, sol ve sağ boyunca kenar boşlukları bırakmanız gerekir.

Bunun için, istediğiniz genişlik-yükseklik oranını geçerli pencerenin genişlik-yükseklik oranıyla test edin ve aşağıdaki gibi uygun ayarlamaları 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';
}

Artık oyun alanının genişliğini ve yüksekliğini ayarladığınıza göre, üste yüksekliğin yarısı kadar, sol tarafa ise genişliğin yarısı kadar bir negatif kenar boşluğu yerleştirerek öğeleri ortalamanız gerekir. CSS'nin, gameArea div öğesinin sol üst köşesini pencerenin tam ortasına yerleştirdiğini unutmayın. Bu nedenle, oyun alanı pencerede ortalanır:

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

Yazı tipi boyutunu da otomatik olarak ayarlamak isteyebilirsiniz. em kullanan tüm alt öğeleriniz varsa gameArea div bloğunun fontSize CSS özelliğini boyutu tarafından belirlenen bir değere kolayca ayarlayabilirsiniz.

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

Son olarak, tuval çizim boyutlarının yeni genişlik ve yükseklikle eşleşmesini istersiniz. Dinamik tuval çözünürlüğüne uyum sağlamak için oyun kodunun geri kalanının 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;

Dolayısıyla, 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 yeniden boyutlandırma Game() işlevinizi şu şekilde çağırmalarını sağlayarak işleyin:

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

Pencere çok fazla yukarıya yeniden boyutlandırıldıysa veya ekranın yönü dikeyse, pencerenin genişliğini% 100 yapmışsınız demektir. Pencere çok geniş olarak yeniden boyutlandırıldıysa veya ekranın yönü yataysa, pencerenin yüksekliğinin% 100'ünü yapmışsınız demektir. 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 kullanmıştır ve çok sayıda ekran çözünürlüğünü ve çeşitli mobil cihazları barındırması açısından oldukça yararlıdır. Buna ek olarak, tam ekran tarayıcı sayesinde bu, web oyunlarımıza tarayıcı tabanlı birçok oyundan daha geleneksel masaüstü oyunlarına benzer etkileyici bir deneyim sağlar. HTML5 ve web teknolojileri gelişmeye devam ettikçe web oyunlarında daha fazla yeniliği dört gözle bekliyoruz.