Einführung
Im Sommer 2010 haben wir das Spiel „Sand Trap“ entwickelt, mit dem wir an einem Wettbewerb für HTML5-Spiele für Smartphones teilgenommen haben. Auf den meisten Smartphones wurde jedoch nur ein Teil des Spiels angezeigt oder das Spiel war zu klein, sodass es nicht spielbar war. Deshalb haben wir das Spiel so programmiert, dass es sich flüssig an jede Auflösung anpassen lässt. Nach einer kleinen Umprogrammierung und unter Verwendung der in diesem Artikel beschriebenen Ideen hatten wir ein Spiel, das für alle modernen Browser skaliert werden konnte, unabhängig davon, ob es auf einem Computer oder einem Mobilgerät ausgeführt wurde.


Dieser Ansatz hat bei „Sand Trap“ gut funktioniert, deshalb haben wir die gleiche Methode auch für unser neuestes Spiel „Thwack!“ verwendet. Das Spiel passt die Bildschirmauflösung automatisch an, sodass es sowohl im Vollbildmodus als auch in Fenstern mit benutzerdefinierter Größe angezeigt werden kann, wie in den folgenden Screenshots zu sehen.
Für die Implementierung mussten sowohl CSS als auch JavaScript verwendet werden. Mit CSS den gesamten Bildschirm auszufüllen, ist ganz einfach. Mit CSS können Sie jedoch nicht das gleiche Seitenverhältnis beibehalten, um ein Auseinanderziehen des Canvas und des Spielbereichs zu verhindern. Hier kommt JavaScript ins Spiel. Sie können Dokumentelemente mit JavaScript neu skalieren und die Größenänderung bei Fensterereignissen auslösen.
Seite vorbereiten
Im ersten Schritt müssen Sie den Bereich auf der Seite festlegen, in dem das Spiel stattfinden soll. Wenn Sie dies als Div-Block einfügen, können Sie andere Tags oder ein Canvas-Element darin platzieren. Wenn Sie die Einrichtung richtig vornehmen, übernehmen diese untergeordneten Elemente die Skalierung des übergeordneten Div-Blocks.
Wenn Ihr Spielbereich aus zwei Teilen besteht, einem Spielbereich und einem Bereich für die Punkteerfassung, könnte er so aussehen:
<div id="gameArea">
<canvas id="gameCanvas"></canvas>
<div id="statsPanel"></div>
</div>
Sobald Sie eine grundlegende Dokumentstruktur haben, können Sie diesen Elementen einige CSS-Eigenschaften zuweisen, um sie für die Größenänderung vorzubereiten. Viele der CSS-Eigenschaften für „gameArea“ werden direkt von JavaScript manipuliert. Damit sie funktionieren, müssen Sie jedoch einige weitere CSS-Eigenschaften einrichten, beginnend mit dem übergeordneten div-Block „gameArea“:
#gameArea {
position: absolute;
left: 50%;
top: 50%;
}
Dadurch wird die linke obere Ecke des Canvas in der Mitte des Bildschirms platziert. Die im nächsten Abschnitt beschriebene JavaScript-Funktion zum automatischen Ändern der Größe verwendet zusätzliche CSS-Eigenschaften, um die Größe des Spielbereichs zu ändern und ihn im Fenster zu zentrieren.
Da die Größe des Spielbereichs automatisch an die Größe des Fensters angepasst wird, sollten die Abmessungen der untergeordneten Elemente des div-Blocks „gameArea“ nicht in Pixeln, sondern in Prozent angegeben werden. Bei Pixelwerten können innere Elemente nicht mit dem übergeordneten Div-Element skaliert werden, wenn es sich ändert. Es kann jedoch hilfreich sein, mit Pixeln zu beginnen und sie dann in Prozent umzuwandeln, sobald Sie ein Layout gefunden haben, das Ihnen gefällt.
Für dieses Beispiel soll der Spielbereich 300 Pixel hoch und 400 Pixel breit sein. Der Canvas deckt den gesamten Spielbereich ab und unten verläuft ein halbtransparenter Statistikbereich mit einer Höhe von 24 Pixeln, wie in Abbildung 1 dargestellt.

Wenn Sie diese Werte in Prozent umwandeln, hat der Canvas eine Breite und Höhe von 100 % (von gameArea, nicht des Fensters). Wenn Sie 24 durch 300 teilen, ergibt sich eine Höhe von 8 % für das Statistikfeld. Da es den unteren Bereich des Spielfelds bedecken soll, beträgt seine Breite 100%, wie in Abbildung 2 dargestellt.

Nachdem Sie die Abmessungen des Spielfelds und seiner untergeordneten Elemente festgelegt haben, können Sie die CSS-Eigenschaften für die beiden inneren Elemente so zusammenstellen:
#gameCanvas {
width: 100%;
height: 100%;
}
#statsPanel {
position: absolute;
width: 100%;
height: 8%;
bottom: 0;
opacity: 0.8;
}
Größe des Spiels anpassen
Jetzt können Sie eine Funktion erstellen, die die Größenänderung des Fensters verarbeitet. Rufen Sie zuerst eine Referenz auf das übergeordnete Dokumentelement „gameArea“ ab.
var gameArea = document.getElementById('gameArea');
Da Sie sich nicht um die genaue Breite oder Höhe kümmern, müssen Sie als Nächstes das Verhältnis von Breite zu Höhe festlegen. Anhand der früheren Referenz für einen Spielbereich mit 400 Pixeln Breite und 300 Pixeln Höhe wissen Sie, dass Sie das Seitenverhältnis auf 4 Einheiten breit und 3 Einheiten hoch festlegen möchten.
var widthToHeight = 4 / 3;
Da diese Funktion jedes Mal aufgerufen wird, wenn die Größe des Fensters geändert wird, sollten Sie auch die neuen Abmessungen des Fensters abrufen, damit Sie die Abmessungen des Spiels entsprechend anpassen können. Verwenden Sie dazu die Eigenschaften „innerWidth“ und „innerHeight“ des Fensters.
var newWidth = window.innerWidth;
var newHeight = window.innerHeight;
Genauso wie Sie das gewünschte Seitenverhältnis festgelegt haben, können Sie jetzt das aktuelle Seitenverhältnis des Fensters ermitteln:
var newWidthToHeight = newWidth / newHeight;
So können Sie festlegen, ob das Spiel vertikal oder horizontal den Bildschirm ausfüllen soll, wie in Abbildung 3 dargestellt.

Wenn die gewünschte Form des Spielbereichs breiter als die des Fensters ist (und die Höhe kürzer), müssen Sie das Fenster horizontal ausfüllen und oben und unten Ränder lassen. Wenn die gewünschte Form des Spielbereichs höher als die des Fensters ist (und die Breite schmaler), müssen Sie das Fenster vertikal ausfüllen und links und rechts Ränder lassen.
Vergleichen Sie dazu das gewünschte Seitenverhältnis mit dem Seitenverhältnis des aktuellen Fensters und nehmen Sie die entsprechenden Anpassungen vor:
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';
}
Nachdem Sie die Breite und Höhe des Spielfelds angepasst haben, müssen Sie es zentrieren. Legen Sie dazu oben einen negativen Rand in Höhe von der Hälfte der Höhe und links einen negativen Rand in Höhe von der Hälfte der Breite fest. Denken Sie daran, dass das CSS bereits die linke obere Ecke des Div-Elements „gameArea“ genau in der Mitte des Fensters platziert. Dadurch wird der Spielbereich im Fenster zentriert:
gameArea.style.marginTop = (-newHeight / 2) + 'px';
gameArea.style.marginLeft = (-newWidth / 2) + 'px';
Außerdem sollten Sie die Schriftgröße automatisch anpassen. Wenn Sie für alle untergeordneten Elemente „em“ verwenden, können Sie die CSS-Property „fontSize“ des div-Blocks „gameArea“ einfach auf einen Wert festlegen, der von seiner Größe abhängt.
gameArea.style.fontSize = (newWidth / 400) + 'em';
Passen Sie abschließend die Canvas-Abmessungen so an, dass sie der neuen Breite und Höhe entsprechen. Beachten Sie, dass die Abmessungen der Game Engine im Rest des Spielcodes von den Abmessungen der Canvas-Zeichnung getrennt bleiben müssen, um eine dynamische Canvas-Auflösung zu ermöglichen.
var gameCanvas = document.getElementById('gameCanvas');
gameCanvas.width = newWidth;
gameCanvas.height = newHeight;
Die fertige Funktion zum Ändern der Größe könnte also so aussehen:
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;
}
Sie möchten, dass diese Anpassungen automatisch vorgenommen werden, wenn die Größe des Fensters geändert wird oder, bei Mobilgeräten, die Bildschirmausrichtung. Sie können diese Ereignisse so verarbeiten, dass sie Ihre Funktion „resizeGame()“ aufrufen:
window.addEventListener('resize', resizeGame, false);
window.addEventListener('orientationchange', resizeGame, false);
Wenn das Fenster zu hoch ist oder der Bildschirm im Hochformat ist, wird die Breite auf 100% des Fensters festgelegt. Wenn das Fenster zu breit ist oder der Bildschirm im Querformat ist, wird die Höhe auf 100% des Fensters festgelegt. Die verbleibende Dimension wird entsprechend dem vordefinierten Seitenverhältnis von Breite zu Höhe festgelegt.
Zusammenfassung
Gopherwood Studios hat Versionen dieser Struktur für alle unsere HTML5-Spiele verwendet. Sie hat sich als sehr nützlich erwiesen, um mehrere Bildschirmauflösungen und verschiedene Mobilgeräte zu unterstützen. Außerdem bieten unsere Webspiele mithilfe eines Vollbildbrowsers ein immersives Erlebnis, das eher traditionellen Desktop-Spielen ähnelt als vielen browserbasierten Spielen. Wir freuen uns auf weitere Innovationen bei Webspielen, da sich HTML5 und Webtechnologien ständig weiterentwickeln.