เกริ่นนำ
ในฤดูร้อนปี 2010 เราได้สร้าง Sand Trap ซึ่งเป็นเกมที่เราเข้าร่วมการแข่งขันเกม HTML5 สำหรับโทรศัพท์มือถือ แต่โทรศัพท์มือถือส่วนใหญ่อาจแสดงเพียงบางส่วนของเกมหรือทำให้เกมเล็กเกินไป ทำให้เล่นไม่ได้เลย เราจึงพัฒนาเกมให้เข้ากับความละเอียดระดับใดก็ได้ด้วยตนเอง หลังจากได้ตั้งโปรแกรมใหม่และใช้ไอเดียที่ระบุไว้ในบทความนี้มาสักระยะหนึ่งแล้ว เราได้พัฒนาเกมให้เหมาะกับเบราว์เซอร์สมัยใหม่ต่างๆ ไม่ว่าจะเล่นในเดสก์ท็อปหรืออุปกรณ์เคลื่อนที่
วิธีนี้ได้ผลดีสำหรับ Sand Trap เราจึงใช้วิธีเดียวกันในเกมล่าสุดของเราที่ชื่อว่า Thwack! เกมจะปรับความละเอียดของหน้าจอเพื่อให้พอดีกับทั้งหน้าต่างเต็มหน้าจอและหน้าต่างที่กำหนดขนาดเองโดยอัตโนมัติ ดังที่แสดงในภาพหน้าจอด้านล่าง
การเชื่อมต่อที่จำเป็นนี้ต้องใช้ประโยชน์จากทั้ง CSS และ JavaScript การใช้ CSS เพื่อเติมทั้งหน้าจอนั้นเป็นเรื่องธรรมดา แต่ CSS จะไม่อนุญาตให้คุณรักษาอัตราส่วนความกว้างต่อความสูงไว้เท่าเดิมเพื่อป้องกันการยืดพื้นที่บนผืนผ้าใบและพื้นที่เกม ซึ่งเป็นจุดที่ JavaScript เข้ามาช่วย คุณปรับขนาดองค์ประกอบเอกสารใหม่ด้วย JavaScript และเรียกใช้การปรับขนาดเหตุการณ์ในหน้าต่างได้
การเตรียมหน้า
ขั้นตอนแรกคือการกำหนดพื้นที่บนหน้าเว็บที่จะมีเกมการแข่งขัน หากรวมส่วนนี้เป็นบล็อก div คุณจะวางแท็กอื่นๆ หรือองค์ประกอบ Canvas ไว้ภายในได้ เมื่อตั้งค่าอย่างถูกต้อง องค์ประกอบย่อยเหล่านี้จะรับช่วงการปรับขนาดของบล็อก div ระดับบน
หากคุณมีพื้นที่เกม 2 ส่วน ได้แก่ พื้นที่เล่น และพื้นที่สำหรับเก็บคะแนน พื้นที่ดังกล่าวอาจมีลักษณะดังนี้
<div id="gameArea">
<canvas id="gameCanvas"></canvas>
<div id="statsPanel"></div>
</div>
เมื่อมีโครงสร้างเอกสารพื้นฐานแล้ว คุณอาจมอบคุณสมบัติ CSS ไม่กี่รายการให้องค์ประกอบเหล่านี้เพื่อเตรียมองค์ประกอบสำหรับการปรับขนาด พร็อพเพอร์ตี้ CSS จำนวนมากสำหรับ "gameArea" ได้รับการจัดการโดย JavaScript โดยตรง แต่เพื่อให้ทำงานได้ ให้ตั้งค่าพร็อพเพอร์ตี้ CSS อื่นๆ อีก 2-3 รายการโดยเริ่มจากการบล็อก div ของ gameArea หลัก ดังนี้
#gameArea {
position: absolute;
left: 50%;
top: 50%;
}
ซึ่งจะเป็นการวางมุมซ้ายบนของผืนผ้าใบไว้ตรงกลางหน้าจอ ฟังก์ชันการปรับขนาดอัตโนมัติของ JavaScript ที่อธิบายไว้ในส่วนถัดไปจะควบคุมคุณสมบัติเพิ่มเติมของ CSS เพื่อปรับขนาดพื้นที่เกมและวางไว้ตรงกลางหน้าต่าง
เนื่องจากพื้นที่เกมจะได้รับการปรับขนาดโดยอัตโนมัติตามขนาดของหน้าต่าง คุณจึงไม่ต้องการขนาดเป็นพิกเซลสำหรับองค์ประกอบย่อยของบล็อก GameArea div แต่คุณต้องการให้เป็นเปอร์เซ็นต์แทน ค่าพิกเซลไม่อนุญาตให้องค์ประกอบภายในปรับขนาดด้วย div หลักเมื่อมีการเปลี่ยนแปลง อย่างไรก็ตาม ขอแนะนำให้เริ่มต้นด้วยพิกเซลแล้วแปลงเป็นเปอร์เซ็นต์เมื่อคุณมีเลย์เอาต์ที่ชอบ
สำหรับตัวอย่างนี้ ให้เริ่มที่พื้นที่เกมสูง 300 พิกเซลและกว้าง 400 พิกเซล ผืนผ้าใบครอบคลุมพื้นที่ทั้งหมดของเกม และแผงสถิติแบบกึ่งโปร่งใสจะอยู่บริเวณด้านล่างที่ความสูง 24 พิกเซล ดังที่แสดงในรูปที่ 1
การแปลค่าเหล่านี้เป็นเปอร์เซ็นต์ทำให้ภาพพิมพ์แคนวาสมีความกว้าง 100% และความสูง 100% (ของ GameArea ไม่ใช่หน้าต่าง) หาร 24 x 300 จะทำให้แผงสถิติมีความสูงอยู่ที่ 8% และเนื่องจากพื้นที่จะครอบคลุมด้านล่างของพื้นที่เกม ความกว้างก็จะเป็น 100% เช่นกัน ดังที่แสดงในรูปที่ 2
ตอนนี้คุณได้กำหนดขนาดของพื้นที่เกมและองค์ประกอบย่อยแล้ว คุณสามารถรวมคุณสมบัติ CSS สำหรับองค์ประกอบภายในทั้ง 2 ประเภทได้ดังนี้
#gameCanvas {
width: 100%;
height: 100%;
}
#statsPanel {
position: absolute;
width: 100%;
height: 8%;
bottom: 0;
opacity: 0.8;
}
การปรับขนาดเกม
ตอนนี้คุณก็พร้อมสร้างฟังก์ชันเพื่อจัดการหน้าต่างที่ปรับขนาดแล้ว ก่อนอื่นให้ดูการอ้างอิงถึงองค์ประกอบเอกสาร gameArea ระดับบนสุด
var gameArea = document.getElementById('gameArea');
เนื่องจากคุณไม่กังวลเกี่ยวกับความกว้างหรือความสูงที่แน่นอน ข้อมูลถัดมาที่คุณต้องตั้งค่าก็คืออัตราส่วนของความกว้างต่อความสูง จากการอ้างอิงก่อนหน้านี้ของพื้นที่เกมกว้าง 400 พิกเซลและสูง 300 พิกเซล คุณจะทราบว่าคุณต้องการตั้งค่าสัดส่วนภาพที่กว้าง 4 หน่วยและสูง 3 หน่วย
var widthToHeight = 4 / 3;
เนื่องจากมีการเรียกฟังก์ชันนี้ทุกครั้งที่มีการปรับขนาดหน้าต่าง คุณจึงต้องจับขนาดใหม่ของหน้าต่างด้วย เพื่อให้สามารถปรับขนาดของเกมให้สอดคล้องกันได้ หาสิ่งนี้โดยใช้คุณสมบัติ InsideWidth และ teriorHeight ของหน้าต่าง
var newWidth = window.innerWidth;
var newHeight = window.innerHeight;
ตอนนี้คุณสามารถกำหนดอัตราส่วนความกว้างต่อความสูงปัจจุบันของหน้าต่างได้ เช่นเดียวกับที่คุณระบุอัตราส่วนความกว้างต่อความสูง:
var newWidthToHeight = newWidth / newHeight;
ซึ่งช่วยให้คุณสามารถตัดสินใจได้ว่าจะให้เกมแสดงแบบเต็มหน้าจอในแนวตั้งหรือแนวนอน ดังแสดงในรูปที่ 3
หากรูปร่างพื้นที่เกมที่ต้องการกว้างกว่ารูปร่างหน้าต่าง (และความสูงสั้นกว่า) คุณต้องทำให้หน้าต่างเต็มในแนวนอนโดยวางขอบไว้ที่ด้านบนและด้านล่าง ในทำนองเดียวกัน หากรูปร่างพื้นที่เกมที่ต้องการสูงกว่ารูปร่างหน้าต่าง (และความกว้างแคบกว่า) คุณก็ต้องเติมพื้นที่หน้าต่างในแนวตั้งและปล่อยขอบไว้ทางด้านซ้ายและขวา
โดยทดสอบอัตราส่วนความกว้างต่อความสูงที่คุณต้องการด้วยอัตราส่วนความกว้างต่อความสูงของหน้าต่างปัจจุบัน และทำการปรับเปลี่ยนอย่างเหมาะสมดังนี้
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';
}
ตอนนี้เมื่อคุณปรับความกว้างและความสูงของพื้นที่เล่นเกมแล้ว คุณต้องจัดสิ่งต่างๆ ให้อยู่กึ่งกลางโดยวางระยะขอบลบที่ด้านบนเป็นครึ่งหนึ่งของความสูงและด้านซ้ายที่เป็นครึ่งหนึ่งของความกว้าง โปรดทราบว่า CSS วางมุมซ้ายบนของ GameArea div ไว้ที่กึ่งกลางของหน้าต่างอยู่แล้ว ดังนั้นจึงเป็นจุดศูนย์กลางของพื้นที่เกมในหน้าต่าง ดังนี้
gameArea.style.marginTop = (-newHeight / 2) + 'px';
gameArea.style.marginLeft = (-newWidth / 2) + 'px';
คุณยังต้องปรับขนาดแบบอักษรโดยอัตโนมัติด้วย หากคุณมีองค์ประกอบย่อยทั้งหมดที่ใช้ em คุณสามารถตั้งค่าคุณสมบัติ fontSize CSS ของบล็อก gameArea div เป็นค่าที่กำหนดโดยขนาด
gameArea.style.fontSize = (newWidth / 400) + 'em';
สุดท้าย คุณต้องการทำให้ขนาดของภาพวาดบนผืนผ้าใบตรงกับความกว้างและความสูงใหม่ โปรดทราบว่าโค้ดเกมที่เหลือจะต้องแยกขนาดของเครื่องมือเกมออกจากมิติข้อมูลการวาดของ Canvas เพื่อให้เหมาะสมกับความละเอียดของ Canvas แบบไดนามิก
var gameCanvas = document.getElementById('gameCanvas');
gameCanvas.width = newWidth;
gameCanvas.height = newHeight;
ดังนั้น ฟังก์ชันการปรับขนาดที่สมบูรณ์อาจมีลักษณะดังนี้
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;
}
แต่ตอนนี้คุณต้องการให้ปรับอัตโนมัติทุกครั้งที่มีการปรับขนาดหน้าต่าง หรือในกรณีที่อุปกรณ์เคลื่อนที่มีการเปลี่ยนการวางแนวหน้าจอ จัดการเหตุการณ์เหล่านี้โดยให้เหตุการณ์เหล่านี้เรียกใช้ฟังก์ชัน optimizeGame() ของคุณ ดังนี้
window.addEventListener('resize', resizeGame, false);
window.addEventListener('orientationchange', resizeGame, false);
หากมีการปรับขนาดหน้าต่างให้สูงเกินไปหรือการวางแนวของหน้าจอเป็นแนวตั้ง หมายความว่าคุณกำลังทำให้หน้าต่างมีความกว้าง 100% และหากมีการปรับขนาดหน้าต่างให้กว้างเกินไปหรือการวางหน้าจอในแนวนอน หมายความว่าคุณกำลังทำให้หน้าต่างมีความสูง 100% ขนาดที่เหลือจะปรับขนาดตามสัดส่วนภาพความกว้างต่อความสูงที่กำหนดไว้ล่วงหน้า
สรุป
Gopherwood Studios ได้ใช้โครงสร้างนี้ในเวอร์ชันต่างๆ กับเกม HTML5 ทั้งหมดของเรา และพิสูจน์แล้วว่ามีประโยชน์อย่างมากสำหรับการรองรับหน้าจอที่มีความละเอียดหลายระดับและอุปกรณ์เคลื่อนที่ต่างๆ นอกจากนี้ เบราว์เซอร์แบบเต็มหน้าจอยังช่วยให้ประสบการณ์การเล่นเกมแบบสมจริงคล้ายกับเกมบนเดสก์ท็อปแบบเดิมมากกว่าเกมที่เล่นบนเบราว์เซอร์หลายๆ เกม เรามุ่งหวังที่จะมีนวัตกรรมอื่นๆ ในเกมบนเว็บเพิ่มเข้ามาเนื่องจาก HTML5 และเทคโนโลยีเว็บมีการพัฒนาอย่างต่อเนื่อง