Pengantar
Pada musim panas 2010, kami membuat Sand Trap, game yang kami masukkan dalam kompetisi game HTML5 untuk ponsel. Namun, sebagian besar ponsel hanya menampilkan sebagian game atau membuat game terlalu kecil sehingga tidak dapat dimainkan sama sekali. Jadi, kami berusaha membuat game menyesuaikan dengan lancar agar sesuai dengan resolusi apa pun. Setelah sedikit memprogram ulang dan menggunakan ide-ide yang diuraikan dalam artikel ini, kami memiliki game yang diskalakan di seluruh browser modern, baik yang berjalan di desktop maupun perangkat seluler.


Pendekatan ini berfungsi dengan baik untuk Sand Trap, jadi kami menggunakan metode yang sama pada game terbaru kami, Thwack!. Game akan otomatis menyesuaikan resolusi layar agar sesuai dengan jendela layar penuh dan ukuran kustom, seperti yang ditunjukkan pada screenshot di bawah.
Untuk menerapkannya, Anda harus memanfaatkan CSS dan JavaScript. Menggunakan CSS untuk mengisi seluruh layar adalah hal yang mudah, tetapi CSS tidak memungkinkan Anda mempertahankan rasio lebar-ke-tinggi yang sama untuk mencegah peregangan kanvas dan area game. Di sinilah JavaScript berperan. Anda dapat menskalakan ulang elemen dokumen dengan JavaScript dan memicu perubahan ukuran pada peristiwa jendela.
Menyiapkan Halaman
Langkah pertama adalah menentukan area di halaman tempat game akan berlangsung. Jika menyertakannya sebagai blok div, Anda dapat menempatkan tag lain atau elemen kanvas di dalamnya. Dengan menyiapkannya dengan benar, elemen turunan ini akan mewarisi penskalaan blok div induk.
Jika Anda memiliki dua bagian di area game, yaitu area bermain dan area pencatatan skor, tampilannya mungkin seperti ini:
<div id="gameArea">
<canvas id="gameCanvas"></canvas>
<div id="statsPanel"></div>
</div>
Setelah memiliki struktur dokumen dasar, Anda dapat memberi elemen ini beberapa properti CSS untuk menyiapkannya agar dapat diubah ukurannya. Banyak properti CSS untuk “gameArea” dimanipulasi langsung oleh JavaScript, tetapi agar berfungsi, siapkan beberapa properti CSS lainnya yang dimulai dengan blok div gameArea induk:
#gameArea {
position: absolute;
left: 50%;
top: 50%;
}
Tindakan ini akan menempatkan sudut kiri atas kanvas di tengah layar. Fungsi pengubahan ukuran otomatis JavaScript yang dijelaskan di bagian berikutnya memanipulasi properti CSS tambahan untuk mengubah ukuran area game dan memusatkan area tersebut di jendela.
Karena area game otomatis diubah ukurannya sesuai dengan dimensi jendela, Anda tidak ingin dimensi dalam piksel untuk elemen turunan blok div gameArea; sebagai gantinya, Anda menginginkannya dalam persentase. Nilai piksel tidak memungkinkan elemen dalam diskalakan dengan div induk saat berubah. Namun, sebaiknya mulailah dengan piksel, lalu konversikan ke persentase setelah Anda memiliki tata letak yang Anda sukai.
Untuk contoh ini, mulailah dengan area game yang memiliki tinggi 300 piksel dan lebar 400 piksel. Kanvas mencakup seluruh area game, dan panel statistik semitransparan berjalan di sepanjang bagian bawah dengan tinggi 24 piksel, seperti yang ditunjukkan pada Gambar 1.

Menerjemahkan nilai ini ke dalam persentase akan membuat kanvas memiliki lebar 100% dan tinggi 100% (dari gameArea, bukan jendela). Membagi 24 dengan 300 akan menghasilkan tinggi panel statistik sebesar 8%, dan, karena akan menutupi bagian bawah area game, lebarnya juga akan menjadi 100%, seperti yang terlihat pada Gambar 2.

Setelah menentukan dimensi area game dan elemen turunannya, Anda dapat menggabungkan properti CSS untuk dua elemen di dalamnya sebagai berikut:
#gameCanvas {
width: 100%;
height: 100%;
}
#statsPanel {
position: absolute;
width: 100%;
height: 8%;
bottom: 0;
opacity: 0.8;
}
Mengubah Ukuran Game
Sekarang Anda siap membuat fungsi untuk menangani jendela yang diubah ukurannya. Pertama, ambil referensi ke elemen dokumen gameArea induk.
var gameArea = document.getElementById('gameArea');
Karena Anda tidak peduli dengan lebar atau tinggi yang tepat, bagian informasi berikutnya yang perlu Anda tetapkan adalah rasio lebar terhadap tinggi. Dengan menggunakan referensi sebelumnya tentang area game yang memiliki lebar 400 piksel dan tinggi 300 piksel, Anda tahu bahwa Anda ingin menetapkan rasio aspek dengan lebar 4 unit dan tinggi 3 unit.
var widthToHeight = 4 / 3;
Karena fungsi ini dipanggil setiap kali ukuran jendela diubah, Anda juga ingin mengambil dimensi baru jendela agar dapat menyesuaikan dimensi game agar cocok. Temukan ini dengan menggunakan properti innerWidth dan innerHeight jendela.
var newWidth = window.innerWidth;
var newHeight = window.innerHeight;
Sama seperti menentukan rasio lebar ke tinggi yang Anda inginkan, sekarang Anda dapat menentukan rasio lebar ke tinggi jendela saat ini:
var newWidthToHeight = newWidth / newHeight;
Hal ini memungkinkan Anda memutuskan apakah akan membuat game mengisi layar secara vertikal atau horizontal, seperti yang ditunjukkan pada Gambar 3.

Jika bentuk area game yang diinginkan lebih lebar dari bentuk jendela (dan tingginya lebih pendek), Anda harus mengisi jendela secara horizontal dan membiarkan margin di bagian atas dan bawah. Demikian pula, jika bentuk area game yang diinginkan lebih tinggi dari bentuk jendela (dan lebarnya lebih sempit), Anda harus mengisi jendela secara vertikal dan membiarkan margin di sepanjang kiri dan kanan.
Untuk melakukannya, uji rasio lebar ke tinggi yang diinginkan dengan rasio lebar ke tinggi jendela saat ini dan lakukan penyesuaian yang sesuai sebagai berikut:
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';
}
Setelah menyesuaikan lebar dan tinggi area game, Anda perlu memusatkan semuanya dengan menempatkan margin negatif di bagian atas yang merupakan setengah dari tinggi dan di sebelah kiri yang merupakan setengah dari lebar. Ingat bahwa CSS sudah menempatkan sudut kiri atas div gameArea tepat di tengah jendela, sehingga area game akan berada di tengah jendela:
gameArea.style.marginTop = (-newHeight / 2) + 'px';
gameArea.style.marginLeft = (-newWidth / 2) + 'px';
Anda juga dapat menyesuaikan ukuran font secara otomatis. Jika semua elemen turunan menggunakan em, Anda cukup menetapkan properti CSS fontSize dari blok div gameArea ke nilai yang ditentukan oleh ukurannya.
gameArea.style.fontSize = (newWidth / 400) + 'em';
Terakhir, Anda ingin membuat dimensi gambar kanvas cocok dengan lebar dan tingginya yang baru. Perhatikan bahwa kode game lainnya harus menjaga dimensi game engine terpisah dari dimensi gambar kanvas untuk mengakomodasi resolusi kanvas dinamis.
var gameCanvas = document.getElementById('gameCanvas');
gameCanvas.width = newWidth;
gameCanvas.height = newHeight;
Jadi, fungsi pengubahan ukuran yang sudah selesai mungkin terlihat seperti ini:
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;
}
Sekarang, Anda ingin penyesuaian ini dilakukan secara otomatis setiap kali ukuran jendela diubah atau, dalam kasus perangkat seluler, orientasi layar diubah. Tangani peristiwa ini dengan memintanya memanggil fungsi resizeGame() Anda seperti ini:
window.addEventListener('resize', resizeGame, false);
window.addEventListener('orientationchange', resizeGame, false);
Jika jendela diubah ukurannya terlalu tinggi atau orientasi layar vertikal, Anda membuat lebar 100% dari jendela, dan jika jendela diubah ukurannya terlalu lebar atau orientasi layar horizontal, Anda membuat tinggi 100% dari jendela. Dimensi yang tersisa diukur sesuai dengan rasio lebar tinggi yang telah ditentukan sebelumnya.
Ringkasan
Gopherwood Studios telah menggunakan versi struktur ini untuk semua game HTML5 kami dan terbukti sangat berguna untuk mengakomodasi beberapa resolusi layar dan berbagai perangkat seluler. Selain itu, dengan bantuan browser layar penuh, game web kami akan memberikan pengalaman imersif yang lebih mirip dengan game desktop tradisional daripada banyak game berbasis browser. Kami berharap dapat melihat lebih banyak inovasi dalam game web seiring dengan terus berkembangnya HTML5 dan teknologi web.