دراسة حالة - تغيير حجم ألعاب HTML5 تلقائيًا

مقدمة

في صيف عام 2010، أنشأنا لعبة Sand Trap، وهي لعبة شاركنا بها في مسابقة ألعاب HTML5 للهواتف الجوّالة. ولكن معظم الهواتف الجوّالة كانت تعرض جزءًا من اللعبة فقط أو كانت تجعلها صغيرة جدًا، ما يجعلها غير قابلة للّعب تمامًا. لذلك، حرصنا على أن تكون اللعبة قابلة للتعديل بسلاسة لتتلاءم مع أي درجة دقة. بعد إجراء بعض عمليات إعادة البرمجة واستخدام الأفكار الموضّحة في هذه المقالة، تمكّنا من إنشاء لعبة يمكن تشغيلها على أي متصفّح حديث، سواء كان على جهاز كمبيوتر مكتبي أو جهاز جوّال.

لقطة شاشة لموقع thwack الإلكتروني بملء الشاشة
لقطة شاشة لتطبيق thwack أصغر حجمًا في نافذة المتصفّح

وقد أثبت هذا النهج نجاحه في لعبة Sand Trap، لذا استخدمنا الطريقة نفسها في لعبتنا الأخيرة، Thwack!. تضبط اللعبة دقة الشاشة تلقائيًا لتلائم النوافذ التي تعمل في وضع ملء الشاشة والنوافذ ذات الحجم المخصّص، كما هو موضّح في لقطات الشاشة أدناه.

لتنفيذ ذلك، كان علينا الاستفادة من كلّ من CSS وJavaScript. إنّ استخدام CSS لملء الشاشة بأكملها أمر بسيط، ولكنّ CSS لا يسمح لك بالاحتفاظ بنسبة العرض إلى الارتفاع نفسها لمنع تمديد اللوحة ومساحة اللعب. وهنا يأتي دور JavaScript. يمكنك إعادة تغيير حجم عناصر المستند باستخدام JavaScript وبدء تغيير الحجم في أحداث النافذة.

إعداد الصفحة

الخطوة الأولى هي تحديد المنطقة على الصفحة التي ستُقام فيها اللعبة. في حال تضمين هذا العنصر ككتلة div، يمكنك وضع علامات أخرى أو عنصر لوحة داخله. من خلال ضبطها بشكل صحيح، ستكتسب هذه العناصر الفرعية نسبة تكبير/تصغير عنصر div الرئيسي.

إذا كانت منطقة اللعب تتضمّن جزءَين، جزءًا للعب وجزءًا لتسجيل النتائج، قد يبدو الأمر على النحو التالي:

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

بعد إنشاء بنية مستند أساسية، يمكنك منح هذه العناصر بعض خصائص CSS لإعدادها لتغيير حجمها. تتعامل JavaScript مباشرةً مع العديد من خصائص CSS الخاصة بـ "gameArea"، ولكن لكي تعمل هذه الخصائص، عليك إعداد بعض خصائص CSS الأخرى بدءًا من العنصر الرئيسي gameArea div:

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

يؤدي ذلك إلى وضع أعلى يمين اللوحة في وسط الشاشة. تتعامل دالة تغيير الحجم التلقائي في JavaScript الموضّحة في القسم التالي مع سمات CSS إضافية لتغيير حجم منطقة اللعبة ووضعها في منتصف النافذة.

بما أنّه يتم تغيير حجم منطقة اللعب تلقائيًا وفقًا لأبعاد النافذة، لا تريد استخدام الأبعاد بالبكسل للعناصر الثانوية في div gameArea، بل تريد استخدامها كنسب مئوية. لا تسمح قيم البكسل للعناصر الداخلية بالتكبير أو التصغير مع div الرئيسي عند تغييره. ومع ذلك، قد يكون من المفيد البدء بالبكسل ثم تحويله إلى نسبة مئوية بعد اختيار تنسيق يعجبك.

في هذا المثال، ابدأ بمساحة اللعب التي يبلغ ارتفاعها 300 بكسل وعرضها 400 بكسل. تغطّي اللوحة مساحة اللعبة بالكامل، وتظهر لوحة إحصاءات شبه شفافة أسفل الشاشة بارتفاع 24 بكسل، كما هو موضّح في الشكل 1.

أبعاد العناصر الفرعية لـ gameArea بالبكسل
الشكل 1: أبعاد العناصر الفرعية لعنصر gameArea بالبكسل

يؤدي تحويل هذه القيم إلى نسب مئوية إلى جعل اللوحة 100% من حيث العرض و100% من حيث الارتفاع (لمنطقة اللعب، وليس النافذة). تؤدي عملية قسمة 24 على 300 إلى الحصول على ارتفاع لوحة الإحصاءات بنسبة %8، وبما أنّها ستغطي أسفل منطقة اللعب، سيكون عرضها أيضًا %100، كما هو موضّح في الشكل 2.

سمات العناصر الفرعية gameArea بالنسبة المئوية
الشكل 2: سمات العناصر الفرعية gameArea بالنسبة المئوية

بعد تحديد أبعاد منطقة اللعب والعناصر الفرعية لها، يمكنك تجميع سمات CSS للعنصرَين الداخليَين على النحو التالي:

#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;

وبما أنّ هذه الدالة يتمّ استدعاؤها عند تغيير حجم النافذة، عليك أيضًا الحصول على السمات الجديدة للنافذة حتى تتمكّن من تعديل سمات لعبتك لتتطابق معها. يمكنك العثور على ذلك باستخدام السمتَين innerWidth وinnerHeight للنافذة.

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

تمامًا كما حدّدت نسبة العرض إلى الارتفاع التي تريدها، يمكنك الآن تحديد نسبة العرض إلى الارتفاع الحالية للنافذة:

var newWidthToHeight = newWidth / newHeight;

يتيح لك ذلك تحديد ما إذا كنت تريد عرض اللعبة بملء الشاشة عموديًا أو أفقيًا، كما هو موضّح في الشكل 3.

ملاءمة عنصر gameArea في النافذة مع الحفاظ على نسبة العرض إلى الارتفاع
الشكل 3: ملاءمة عنصر gameArea للنافذة مع الحفاظ على نسبة العرض إلى الارتفاع

إذا كان شكل منطقة اللعب المطلوبة أعرض من شكل النافذة (وارتفاعه أقصر)، عليك ملء النافذة أفقيًا وترك هوامش في أعلى الشاشة وأسفلها. وبالمثل، إذا كان شكل منطقة اللعب المطلوبة أعلى من شكل النافذة (وكان العرض أضيق)، عليك ملء النافذة عموديًا وترك هوامش على يمينها ويسارها.

لإجراء ذلك، اختبِر نسبة العرض إلى الارتفاع المطلوبة مع نسبة العرض إلى الارتفاع الحالية للنافذة وأدخِل التعديلات المناسبة على النحو التالي:

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 تضع حاليًا أعلى يمين div gameArea في منتصف النافذة بالضبط، لذا يؤدي ذلك إلى وضع منطقة اللعب في منتصف النافذة:

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

ويمكنك أيضًا ضبط حجم الخط تلقائيًا. إذا كانت كل العناصر الفرعية تستخدم em، يمكنك ببساطة ضبط سمة FontSize في CSS لوحدة div gameArea على قيمة يتم تحديدها حسب حجمها.

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

أخيرًا، عليك جعل سمات رسم اللوحة تتطابق مع العرض والارتفاع الجديدَين. يُرجى العِلم أنّه يجب أن تحافظ بقية رموز اللعبة على فصل سمات محرّك اللعبة عن سمات رسم اللوحة من أجل استيعاب درجة دقة اللوحة الديناميكية.

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;
}

الآن، تريد إجراء هذه التعديلات تلقائيًا عند تغيير حجم النافذة أو تغيير اتجاه الشاشة في الأجهزة الجوّالة. يمكنك معالجة هذه الأحداث من خلال جعلها تستدعي دالة resizeGame()‎ على النحو التالي:

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

إذا تم تغيير حجم النافذة إلى ارتفاع كبير جدًا أو كان اتجاه الشاشة عموديًا، يعني ذلك أنّك تجعل العرض يساوي ‎100% من النافذة، وإذا تم تغيير حجم النافذة إلى عرض كبير جدًا أو كان اتجاه الشاشة أفقيًا، يعني ذلك أنّك تجعل الارتفاع يساوي ‎100% من النافذة. ويتم تحديد حجم السمة المتبقية وفقًا لنسبة العرض إلى الارتفاع المحدّدة مسبقًا.

ملخّص

استخدمت شركة Gopherwood Studios إصدارات من هذه البنية لجميع ألعاب HTML5 التي نطوّرها، وقد أثبتت هذه البنية أنّها مفيدة جدًا لاستيعاب درجات دقة متعددة للشاشات ومختلف الأجهزة الجوّالة. بالإضافة إلى ذلك، باستخدام متصفّح في وضع ملء الشاشة، توفّر ألعاب الويب تجربة غامرة تشبه تجربة الألعاب التقليدية على الكمبيوتر المكتبي أكثر من العديد من الألعاب المستندة إلى المتصفّح. نحن نتطلّع إلى المزيد من الابتكارات في ألعاب الويب مع استمرار تطوير HTML5 وتقنيات الويب.