[دروس] كيفية إنشاء أول لعبة جافا سكريبت IDLE تزايدي

سأخبرك اليوم عن كيفية إنشاء أبسط قائمة في ToDo لأبسط لعبة IDLE تزايدي في JavaScript ، بعد أن قضيت أقل من يوم واحد في إجازة سنوية. للقيام بذلك ، أقترح اختيار لعبة البومة أسهل وعدم تخطي الخطوات بين البيضاوي ومشروع البومة الفارغة النهائية واللعبة النهائية.


الناس الذين يعرفون كيفية صنع هذه الألعاب سوف يشعرون بالملل ؛ الأشخاص الذين يعرفون JS ، أوصي بالنظر إلى الكود من خلال أصابعك (لتجنب الإصابات) والقراءة فقط عن الميكانيكا. تحت القطع ، دليل ثابت للمبتدئين.

الألعاب التزايدية هي ألعاب تعتمد على الدورة الرئيسية [التي لا نهاية لها] ، والتي تتألف من تراكم الموارد ، وإنفاقها المستمر وزيادة دخلها. الميزة الرئيسية هي النمو المستمر للأرقام. ستخبرك الإرشادات بكيفية إنشاء لعبة IDLE (كسول) يتم فيها تجديد الموارد بجهاز توقيت بدلاً من نقرة نشطة.

بادئ ذي بدء ، قم بإنشاء ملف نصي يسمى index.html واكتب ما يلي:
<html> <head> <meta http-equiv="Content-Type" content="text/html;charset=utf-8"><!--    ,     --> <title>     </title> <style> </style> </head> <body>  : 0<br> </body> </html> 

في الوقت الحالي ، لا توجد لعبة حتى الآن ، ولكن لا يوجد سوى نقش ثابت.

رابط اللعبة في الحالة الحالية: 0df7a27 .

تستند جميع الألعاب في هذا النوع إلى دورتين لا نهائيتين من الألعاب.
الدورة الأولى هي تراكم الموارد.
الدورة الثانية هي مضيعة للموارد.

لننفذ الدورة الأولى.

   : <span id="spnCoppersValue">0</span><br> <script> let coppers = 0; let copperGrowth = 1; myTimer = setInterval(endOfTurnCalc, 2000); function endOfTurnCalc() { coppers = coppers+copperGrowth; document.getElementById("spnCoppersValue").innerHTML = coppers; } </script> 

الخط الأول

 <span id="spnCoppersValue">0</span><br> 

يوفر لنا القدرة على الوصول إليه من خلال معرفه ، وتغيير المحتويات داخل العلامات ، في حالتنا ، قيمة العملات النقدية.

ثانياً ، ظهر سيناريو.

نقوم بإنشاء متغير coppers ، وتعيين نطاقه باستخدام الكلمة الرئيسية let. على غرار الإعلان عن copperGrowth ، والتي ستكون مسؤولة عن معدل نمو العملات النحاسية.

بعد ذلك ، قم بإنشاء كائن نضع فيه مؤقتنا ، والذي سيسحب وظيفة endOfTurnCalc كل 2000 مللي ثانية (2 ثانية). توفر الوظيفة زيادة في العملات النحاسية وتحديث للواجهة. الصيحة ، نصف اللعبة تتم: لدينا دورة من الموارد المتراكمة. المهمة التالية هي معرفة كيفية إنفاقها.

رابط اللعبة في الحالة الحالية: e5d96e1 .

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

 <button id="btnUpgCopperMine" onclick="upgCopperMine()">  , 10  </button><br> 

أضف رمزًا يسمح لزر الترقية بالعمل:

  let coppersUpgCost = 10; let coppersUpgLevel = 1; function upgCopperMine() { if (coppers>coppersUpgCost){ coppers = coppers-coppersUpgCost; coppersUpgLevel = coppersUpgLevel + 1; coppersUpgCost = coppersUpgCost*2; document.getElementById("spnCoppersValue").innerHTML = coppers; document.getElementById("btnUpgCopperMine").innerHTML = "  , "; document.getElementById("btnUpgCopperMine").innerHTML += coppersUpgCost.toString(); document.getElementById("btnUpgCopperMine").innerHTML += "  "; } } 

ورمز سيؤثر على معدل استخراج العملات المعدنية الجديدة:

  function endOfTurnCalc() { coppers = coppers+copperGrowth*coppersUpgLevel;; document.getElementById("spnCoppersValue").innerHTML = coppers; } 

حددنا سعر تحسين المنجم ، وتحديد مستوى المنجم الافتراضي ، والكتابة في وظيفة التحقق من كفاية العملات المعدنية لترقية المنجم.

إذا كان هناك ما يكفي من المال ، ثم شطب سعر الترقية ، وزيادة المستوى الحالي للمناجم ، وحساب سعر التحسين المقبل ؛ عرض القيم الحالية للعملات النحاسية وتكلفة التحسين التالي.

رابط اللعبة في الحالة الحالية: c731ec5 .

حسنًا ، يمكنك اللعب بالفعل - يمكنك الحفظ ، وبكل سرور ، إنفاق المتراكمة. لكننا بحاجة إلى تعزيز النجاح - لا يقوم اللاعب بحساب الزيادة في معدل تراكم العملات المعدنية فقط ، من خلال طرح القيمة الجديدة القديمة ، ولكن بطريقة سريعة ، نرى على الفور المعدل الحالي لتراكم العملات. سوف تفعل؟

أضف سطرًا إضافيًا إلى الواجهة:

    : <span id="spnCoppersRate">1</span>  2 <br> 

الآن يتم وصف الواجهة الخاصة بنا بالخطوط التالية:

  <button id="btnUpgCopperMine" onclick="upgCopperMine()" style="width: 240px;">  , 10  </button><br>  : <span id="spnCoppersValue">0</span><br>    : <span id="spnCoppersRate">1</span>  2 <br> 

نقوم بإجراء تغيير على البرنامج النصي ، إلى الدالة upgCopperMine ():

  if (coppers>coppersUpgCost){ coppers = coppers-coppersUpgCost; coppersUpgLevel = coppersUpgLevel + 1; coppersUpgCost = coppersUpgCost*2; document.getElementById("spnCoppersValue").innerHTML = coppers; document.getElementById("btnUpgCopperMine").innerHTML = "  , "; document.getElementById("btnUpgCopperMine").innerHTML += coppersUpgCost.toString(); document.getElementById("btnUpgCopperMine").innerHTML += "  "; document.getElementById("spnCoppersRate").innerHTML = copperGrowth*coppersUpgLevel; } 

رابط اللعبة في الحالة الحالية: 3ac06b6 .

! ممتاز لدينا لعبة لانهائية مشروطة. الآن نحن بحاجة إلى التوقف لفترة ثانية ، والتفكير في الأمر - بعض الأشخاص يعجبهم عندما لا يكون هناك هدف نهائي ، ويمكنك اللعب حتى تتعب ، ويعتقد الجزء الآخر أن شروط الدقة وسهولة الوصول إلى اللعبة يجب أن تكون. لقد صنعنا بالفعل لعبة للأول ، لكن ما الذي يمنعنا من إجراء تغيير صغير بحيث يكون الهدف هدفًا وشرطًا للفوز؟ دعونا نفعل ذلك.

  let win_condition = 50; myTimer = setInterval(endOfTurnCalc, 2000); function endOfTurnCalc() { if (coppers < win_condition) { coppers = coppers+copperGrowth*coppersUpgLevel; document.getElementById("spnCoppersValue").innerHTML = coppers; } else { clearTimeout(myTimer); alert("  !   "+win_condition.toString()); } } 

أضفنا متغيرًا نضع فيه القيمة التي نحتاجها لتحقيق وتغيير الوظيفة من الحلقة ، مع إضافة تحقق لتحقيق الهدف. عند الوصول إلى الهدف ، نقوم بمسح الفاصل الزمني من كائننا باستخدام مؤقت وعرض رسالة منبثقة في المستعرض.

هناك نقطة صغيرة: بعض برامج مكافحة الفيروسات لا تحب التنبيهات وتحظر الصفحة لاستخدامها.

رابط اللعبة في الوضع الحالي: 8fa4041 .

الوظيفة التالية التي يتوقعها الأشخاص من لعبة أطول من خمس دقائق هي القدرة على حفظ اللعبة وتحميلها. دعنا نعطيها لها!

نضيف سطرين إلى الواجهة ، ولا ننسى إضافة علامة تغذية السطر إلى السطر السابق:

  <button id="btnSaveGame" onclick="saveGame()" style="width: 240px;"> </button><br> <button id="btnLoadGame" onclick="loadGame()" style="width: 240px;"> </button><br> 

والآن سنقوم بتوسيع نصوصنا بحيث تعمل الأزرار:

  function saveGame() { localStorage.setItem('coppers', coppers); localStorage.setItem('coppersUpgCost', coppersUpgCost); localStorage.setItem('coppersUpgLevel', coppersUpgLevel); } function loadGame() { coppers = parseInt(localStorage.getItem('coppers')); coppersUpgCost = parseInt(localStorage.getItem('coppersUpgCost')); coppersUpgLevel = parseInt(localStorage.getItem('coppersUpgLevel')); document.getElementById("spnCoppersValue").innerHTML = coppers; document.getElementById("btnUpgCopperMine").innerHTML = "  , "; document.getElementById("btnUpgCopperMine").innerHTML += coppersUpgCost.toString(); document.getElementById("btnUpgCopperMine").innerHTML += "  "; document.getElementById("spnCoppersRate").innerHTML = copperGrowth*coppersUpgLevel; } 

نضع جميع الموارد القابلة للتغيير في التخزين المحلي للمتصفح عند الحفظ ، وأثناء قراءتنا نعيد قراءتها وتحديث الواجهة.

رابط اللعبة في الحالة الحالية: 54b1ea0 .

كل شيء ، الجزء الرئيسي من اللعبة جاهز.

حتى الآن ، لقد استعرضنا:

- إنشاء مورد ؛
- استخراج الموارد ؛
- هدر الموارد في ترقية نظام الإنتاج الخاص بها ؛
- انعكاس سرعة استخراج المورد ؛
- حالة النصر ؛
- كتابة وقراءة حفظ اللعبة في التخزين المحلي للمتصفح.

سنواصل؟ قبل الانتقال إلى الموضوع التالي ، أي إضافة مورد ثانٍ لنظامنا (الفضة) ، أقترح إجراء إعادة بيع صغيرة للشفرة الحالية.

ما الذي يجب القيام به كجزء من إعادة البناء؟

أولاً ، دعونا ننشئ كائنًا واحدًا للعبة ، ونضع العملات النحاسية ، ومستوى مناجم النحاس ، وما إلى ذلك ، في الداخل كخصائص لهذا الكائن. سيساعد هذا الأمر بشكل كبير في المستقبل مع توسيع التخزين والتحميل إلى كيانات الألعاب الجديدة.

ثانياً ، سنجعل حساب سعر الترقية ديناميكيًا.

ثالثًا ، نتخلص من ازدواجية التعليمات البرمجية ، المسؤولة عن تحديث الواجهة.

سوف يأخذ الرمز النموذج التالي:

  let game = { coppers: 1, copperGrowth: 1, coppersUpgCost: 10, coppersUpgLevel: 1, } let win_condition = 50; myTimer = setInterval(endOfTurnCalc, 2000); function endOfTurnCalc() { if (game.coppers < win_condition) { game.coppers = game.coppers+game.copperGrowth*game.coppersUpgLevel; document.getElementById("spnCoppersValue").innerHTML = game.coppers; } else { clearTimeout(myTimer); alert("  !   "+win_condition.toString()); } } function upgCopperMine() { if (game.coppers>game.coppersUpgCost){ game.coppers = game.coppers-game.coppersUpgCost; game.coppersUpgLevel = game.coppersUpgLevel + 1; game.coppersUpgCost = game.coppersUpgCost*2; document.getElementById("spnCoppersValue").innerHTML = game.coppers; document.getElementById("btnUpgCopperMine").innerHTML = "  , "; document.getElementById("btnUpgCopperMine").innerHTML += game.coppersUpgCost.toString(); document.getElementById("btnUpgCopperMine").innerHTML += "  "; document.getElementById("spnCoppersRate").innerHTML = game.copperGrowth*game.coppersUpgLevel; } } function saveGame() { localStorage.setItem('coppers', game.coppers); localStorage.setItem('coppersUpgCost', game.coppersUpgCost); localStorage.setItem('coppersUpgLevel', game.coppersUpgLevel); } function loadGame() { game.coppers = parseInt(localStorage.getItem('coppers')); game.coppersUpgCost = parseInt(localStorage.getItem('coppersUpgCost')); game.coppersUpgLevel = parseInt(localStorage.getItem('coppersUpgLevel')); document.getElementById("spnCoppersValue").innerHTML = game.coppers; document.getElementById("btnUpgCopperMine").innerHTML = "  , "; document.getElementById("btnUpgCopperMine").innerHTML += game.coppersUpgCost.toString(); document.getElementById("btnUpgCopperMine").innerHTML += "  "; document.getElementById("spnCoppersRate").innerHTML = game.copperGrowth*game.coppersUpgLevel; } </script> 

من الواضح تمامًا أننا أنشأنا كائن اللعبة ، وداخل الكائن سجلنا خصائصه وقيم خصائصه. علاوة على ذلك ، حيثما اعتدنا على الوصول إلى المتغيرات مباشرة ، فإننا نشير الآن إلى نفس خصائص كائن اللعبة.

رابط اللعبة في الوضع الحالي: 8a07f4d .

دعونا الآن تحديث نظام الحفظ والتحميل.

  function saveGame() { localStorage.setItem('gameTutorial', JSON.stringify(game)); } function loadGame() { game = JSON.parse(localStorage.getItem('gameTutorial')); document.getElementById("spnCoppersValue").innerHTML = game.coppers; document.getElementById("btnUpgCopperMine").innerHTML = "  , "; document.getElementById("btnUpgCopperMine").innerHTML += game.coppersUpgCost.toString(); document.getElementById("btnUpgCopperMine").innerHTML += "  "; document.getElementById("spnCoppersRate").innerHTML = game.copperGrowth*game.coppersUpgLevel; } 

الآن ، بدلاً من حفظ الخصائص الفردية ، نقوم بحفظ الكائن بأكمله ككل. لكن كن حذرًا: إذا أضفت طرقًا إلى الكائن ، فلن يتم حفظها بهذه الطريقة ، وستؤدي إعادة الكتابة اللاحقة للكائن من الحفظ إلى حذف جميع الطرق ...

رابط اللعبة في الوضع الحالي: 8eba059 .

دعنا نزيل الخاصية غير الضرورية - سعر ترقية المنجم وإنشاء وظيفة لحساب الترقية وسوف نسميها في الأماكن الضرورية.

  function coppersUpgCost() { return game.coppersUpgLevel*10; } function upgCopperMine() { if (game.coppers>=coppersUpgCost()){ game.coppers = game.coppers-coppersUpgCost(); game.coppersUpgLevel = game.coppersUpgLevel + 1; document.getElementById("spnCoppersValue").innerHTML = game.coppers; document.getElementById("btnUpgCopperMine").innerHTML = "  , "; document.getElementById("btnUpgCopperMine").innerHTML += coppersUpgCost().toString(); document.getElementById("btnUpgCopperMine").innerHTML += "  "; document.getElementById("spnCoppersRate").innerHTML = game.copperGrowth*game.coppersUpgLevel; } } function saveGame() { localStorage.setItem('gameTutorial', JSON.stringify(game)); } function loadGame() { game = JSON.parse(localStorage.getItem('gameTutorial')); document.getElementById("spnCoppersValue").innerHTML = game.coppers; document.getElementById("btnUpgCopperMine").innerHTML = "  , "; document.getElementById("btnUpgCopperMine").innerHTML += coppersUpgCost().toString(); document.getElementById("btnUpgCopperMine").innerHTML += "  "; document.getElementById("spnCoppersRate").innerHTML = game.copperGrowth*game.coppersUpgLevel; } 

رابط اللعبة في الوضع الحالي: 4007924 .

أخيرًا ، نضع الأجزاء المكررة من رمز تحديث الواجهة في وظيفة منفصلة.

  function updateUI() { document.getElementById("spnCoppersValue").innerHTML = game.coppers; document.getElementById("btnUpgCopperMine").innerHTML = "  , "; document.getElementById("btnUpgCopperMine").innerHTML += coppersUpgCost().toString(); document.getElementById("btnUpgCopperMine").innerHTML += "  "; document.getElementById("spnCoppersRate").innerHTML = game.copperGrowth*game.coppersUpgLevel; } 

بدوره ، في جميع الأماكن الأخرى حيث وصلنا إلى بعض كائنات DOM ، سنقوم الآن باستدعاء وظيفة updateUI ():

  function endOfTurnCalc() { if (game.coppers < win_condition) { game.coppers = game.coppers+game.copperGrowth*game.coppersUpgLevel; updateUI(); } else { clearTimeout(myTimer); alert("  !   "+win_condition.toString()); } } function upgCopperMine() { if (game.coppers>=coppersUpgCost()){ game.coppers = game.coppers-coppersUpgCost(); game.coppersUpgLevel = game.coppersUpgLevel + 1; updateUI(); } } function loadGame() { game = JSON.parse(localStorage.getItem('gameTutorial')); updateUI(); } 

رابط اللعبة في الحالة الحالية: 2245f97 .

الآن أقترح إدخال مورد ثان: الفضة ، وبناء وتحسين مناجم الفضة.

  <button id="btnUpgCopperMine" onclick="upgCopperMine()" style="width: 240px;">  , 10  </button><br>  : <span id="spnCoppersValue">0</span><br>    : <span id="spnCoppersRate">1</span>  2 <br> <button id="btnUpgSilverMine" onclick="upgSilverMine()" style="width: 240px;">  , 50  </button><br>  : <span id="spnSilversValue">0</span><br>    : <span id="spnSilversRate">1</span>  2 <br> <button id="btnSaveGame" onclick="saveGame()" style="width: 240px;"> </button><br> <button id="btnLoadGame" onclick="loadGame()" style="width: 240px;"> </button><br> <script> let game = { coppers: 1, copperGrowth: 1, coppersUpgLevel: 1, silvers: 0, silverGrowth: 1, silversUpgLevel: 0, } let win_condition = 50; let silverMineBasePriceCoppers = 100; myTimer = setInterval(endOfTurnCalc, 2000); function endOfTurnCalc() { if (game.silvers < win_condition) { game.coppers = game.coppers+game.copperGrowth*game.coppersUpgLevel; game.silvers = game.silvers+game.silverGrowth*game.silversUpgLevel; updateUI(); } else { clearTimeout(myTimer); alert("  !   "+win_condition.toString()); } } function coppersUpgCost() { return game.coppersUpgLevel*10+5; } function silversUpgCost() { return game.silversUpgLevel*10+5; } function upgCopperMine() { if (game.coppers>=coppersUpgCost()){ game.coppers = game.coppers-coppersUpgCost(); game.coppersUpgLevel = game.coppersUpgLevel + 1; updateUI(); } } function upgSilverMine() { if (game.silversUpgLevel===0){ if (game.coppers>=silverMineBasePriceCoppers){ game.coppers = game.coppers-silverMineBasePriceCoppers; game.silversUpgLevel = 1; updateUI(); } } else { if (game.silvers>=silversUpgCost()){ game.silvers = game.silvers-silversUpgCost(); game.silversUpgLevel = game.silversUpgLevel + 1; updateUI(); } } } function updateUI() { document.getElementById("spnCoppersValue").innerHTML = game.coppers; document.getElementById("btnUpgCopperMine").innerHTML = "  , "; document.getElementById("btnUpgCopperMine").innerHTML += coppersUpgCost().toString(); document.getElementById("btnUpgCopperMine").innerHTML += "  "; document.getElementById("spnCoppersRate").innerHTML = game.copperGrowth*game.coppersUpgLevel; document.getElementById("spnSilversValue").innerHTML = game.silvers; if (game.silversUpgLevel===0) { document.getElementById("btnUpgSilverMine").innerHTML = "  , "; document.getElementById("btnUpgSilverMine").innerHTML += silverMineBasePriceCoppers.toString(); document.getElementById("btnUpgSilverMine").innerHTML += "  "; } else { document.getElementById("btnUpgSilverMine").innerHTML = "  , "; document.getElementById("btnUpgSilverMine").innerHTML += silversUpgCost().toString(); document.getElementById("btnUpgSilverMine").innerHTML += "  "; } document.getElementById("spnSilversRate").innerHTML = game.silverGrowth*game.silversUpgLevel; } function saveGame() { localStorage.setItem('gameTutorial', JSON.stringify(game)); } function loadGame() { game = JSON.parse(localStorage.getItem('gameTutorial')); updateUI(); } </script> 

ما الذي يتم؟ تم إضافة حقول لعرض العملات المعدنية الفضية وسرعة استخراجها وزر لبناء المنجم الفضي أو تحسينه.

يتم نسخ خصائص silvers ، silverGrowth ، silversUpgLevel داخل كائن اللعبة ، ولكن يتم تعيين الأخير على 0 ، لأنه ليس لدينا منجم فضي بشكل افتراضي.
وأضاف silverMineBasePriceCoppers متغير ، والتي سوف تعكس سعر بناء منجم الفضة في العملات النحاسية (لأنه لا يمكننا دفع ثمن منجم الفضة مع الفضة ، والتي ليس لدينا حتى الآن).

تم تعديل وظيفة coppersUpgCost وتكرارها كـ silversUpgCost بحيث يكون سعر الترقية غير صفري إذا كان مستوى المنجم الحالي هو 0.
لقد قمنا بتغيير وظيفة حساب نهاية المنعطف ، بإضافة حساب الدخل من المنجم الفضي هناك ، وتغيير حالة النصر أيضًا - نحتاج الآن إلى مقارنة عدد العملات النحاسية ، لكن عدد العملات الفضية.

لقد أنشأنا وظيفة upgSilverMine ، والتي نعكس فيها منطق الخصم من الأموال (إذا لم يكن هناك منجم بعد ، فإننا سنشطب العملات المعدنية النحاسية ، إذا كان المنجم قد تم بناؤه بالفعل ، فسنشطب الفضة لتحسين المنجم).
تمت إضافة الأسطر اللازمة للفضة إلى وظيفة updateUI ، وكذلك تم تقسيم منطق إخراج النص إلى زر لتحسين المنجم الفضي ، لذلك يعمل زر واحد على حد سواء لبناء المنجم وتحسينه.

حفظ وتحميل وظائف ظلت دون تغيير.

رابط اللعبة في الوضع الحالي: 03eb0eb .

قد يحدث أن هناك الكثير من العملات النحاسية التي تتراكم أكثر من اللازم ، بينما لا يزال يتعين الحصول على الفضة. لهذا ، في مثل هذه الألعاب ، كقاعدة عامة ، هناك إمكانية لتبادل الموارد المختلفة لبعضها البعض.

دعنا نضيف بضعة أزرار إلى الواجهة:

 <button id="btnUpgCopperMine" onclick="upgCopperMine()" style="width: 240px;">  , 15  </button><br>  : <span id="spnCoppersValue">0</span><br>    : <span id="spnCoppersRate">1</span>  2 <br> <button id="btnBuySilver" onclick="buySilver()" style="width: 240px;"> 1   100 </button><br> <hr> <button id="btnUpgSilverMine" onclick="upgSilverMine()" style="width: 240px;">  , 50  </button><br>  : <span id="spnSilversValue">0</span><br>    : <span id="spnSilversRate">0</span>  2 <br> <button id="btnBuySilver" onclick="buyCoppers()" style="width: 240px;"> 100   1  </button><br> <hr> <button id="btnSaveGame" onclick="saveGame()" style="width: 240px;"> </button><br> <button id="btnLoadGame" onclick="loadGame()" style="width: 240px;"> </button><br> 

وأضف بعض الوظائف إلى هذه الأزرار:

  function buySilver() { if (game.coppers>=100) { game.coppers = game.coppers - 100; game.silvers = game.silvers + 1; updateUI(); } } function buyCoppers() { if (game.silvers>=1) { game.coppers = game.coppers + 100; game.silvers = game.silvers - 1; updateUI(); } } 

رابط اللعبة في الحالة الحالية: 92219b2 .

إذن ما الذي يمكن إضافته إلى اللعبة الإضافية؟ هيبة جير! بالطبع ، هذا أكثر من اللازم ، ولكن إذا تطورت اللعبة أكثر ، فستكون في متناول يديك. اللاعبون يحبونه!

في الألعاب المختلفة ، يتم ذلك بشكل مختلف ، ولكن بشكل عام - تمنح الآلية نقاط Prestige إما بعد الانتهاء بنجاح (التمرير) من اللعبة ، أو إلغاء القفل أثناء اللعبة بعد بلوغ حد معين مستهدف.

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

ماذا نحتاج لهذا؟ تحتاج إلى آلية إعادة تشغيل اللعبة مع القيم الافتراضية. على سبيل المكافأة الدائمة ، سنضيف نقاط Prestige إلى الخصائص التي لم تتغير سابقًا من copperGrowth و silverGrowth.

أضف الوظائف التالية winGame ، restartGameDialog ، restartGame ، وأيضًا قم بتغيير endOfTurnCalc لاستدعاء وظائف جديدة وتحديث updateUI:

  function endOfTurnCalc() { if (game.silvers < win_condition) { game.coppers = game.coppers+game.copperGrowth*game.coppersUpgLevel; game.silvers = game.silvers+game.silverGrowth*game.silversUpgLevel; updateUI(); } else { winGame(); } } function winGame() { clearTimeout(myTimer); alert("  !   "+win_condition.toString()); myRestartTimer = setInterval(restartGameDialog, 2000); } function restartGameDialog() { if (confirm('      ?')) { restartGame(); } else { clearTimeout(myRestartTimer); } } function restartGame() { game.coppers = 1; game.copperGrowth = game.copperGrowth+1; game.coppersUpgLevel = 1; game.silvers = 0; game.silverGrowth = game.silverGrowth+1; game.silversUpgLevel = 0; clearTimeout(myRestartTimer); myTimer = setInterval(endOfTurnCalc, 2000); updateUI(); } function updateUI() { ... if (game.copperGrowth!==1) { document.getElementById("divLblPrestige").innerHTML = "     "+game.copperGrowth.toString(); document.getElementById("divLblPrestige").style.display = "block"; } else { document.getElementById("divLblPrestige").style.display = "none"; } } 

تبدأ وظيفة winGame جهاز توقيت ، وبعد ذلك يتم استدعاء مربع حوار التأكيد. في حالة التأكيد ، يتم استدعاء وظيفة إعادة التشغيل ، والتي تعيد تعيين جميع القيم إلى الافتراضي ، ولكنها تزيد من خصائص النمو الأساسي للعملات المعدنية.

بشكل عام ، اللعبة جاهزة:

- إنشاء مورد ؛
- استخراج الموارد ؛
- هدر الموارد في ترقية نظام الإنتاج الخاص بها ؛
- انعكاس سرعة استخراج المورد ؛
- حالة النصر ؛
- كتابة وقراءة حفظ اللعبة في التخزين المحلي للمتصفح.
- إضافة مورد واحد آخر مع إنتاج وتحديث إنتاجه ؛
- تبادل الموارد ؛
- آلية إعادة تشغيل اللعبة وآلية برستيج.

رابط اللعبة في الحالة الحالية: 92219b2 .

أخيرًا ، آخر شيء في هذه المقالة أرغب في عرضه هو آلية تخزين مختلفة ، لأن الآلية الحالية بها واحدة ، ولكنها مشكلة كبيرة.

تخيل أنك تقوم بتطوير لعبة ، ونشرها على خادم ويب (ربما على صفحات github) ، وأن الناس يلعبونها. بمرور الوقت ، يمكنك إجراء تغييرات على اللعبة التي تضيف خصائص جديدة إلى كائن لعبة اللعبة.

الآن مشاهدة يديك.

يدخل اللاعب بالحفظ القديم ، الذي يحتوي على جميع خصائص المرصّمات الفضية والفضية ، ولكن ليس ، على سبيل المثال ، الملكية الذهبية. يتم تحميل كائن اللعبة الخاص بنا ويقوم بالكتابة فوق الكائن الذي تم إنشاؤه عندما تم تحميل صفحة الويب ، والآن يوجد داخل الكائن فقط تلك الخصائص التي تم حفظها. وقمنا بالفعل بتحديث الرمز! ويشير هذا الرمز إلى الخصائص المحدثة غير الموجودة. وبالتالي ، يبدأ الرمز في تلقي أخطاء متعددة ، حتى عدم القدرة الكاملة على تشغيل اللعبة. من المستغرب ، لإصلاح هذه المشكلة ، تحتاج إلى إعادة كتابة سطرين فقط في وظيفة تنزيل اللعبة:

  function loadGame() { gameTemp = JSON.parse(localStorage.getItem('gameTutorial')); for (var propertyName in gameTemp) { game[propertyName] = gameTemp[propertyName]; } updateUI(); } 

, game = { gold: 1, } , , .
: 83c258d .

. , .

  <hr> <button id="btnSaveGame" onclick="saveGame()" style="width: 240px;"> </button><br> <br> <button id="btnExportGame" onclick="exportGame()" style="width: 240px;"> </button><br> <div id="divLblExport" style="display: none"></div> <br> <hr> <button id="btnLoadGame" onclick="loadGame()" style="width: 240px;"> </button><br> <br> <button id="btnImportGame" onclick="importGame()" style="width: 240px;"> </button><br> 

.

  let countdown = 30; let showExport = 0; function updateUI() { ... if (showExport===1){ document.getElementById("divLblExport").style.display = "block"; } else { document.getElementById("divLblExport").style.display = "none"; } } function exportGame() { exportTimer = setInterval(exportCountdown, 1000); document.getElementById("divLblExport").innerHTML = btoa(JSON.stringify(game)); showExport = 1; updateUI(); } function exportCountdown() { if (countdown > 0) { countdown = countdown - 1; } else { clearTimeout(exportTimer); countdown = 30; showExport = 0; updateUI(); } } function importGame() { let importString = prompt('   '); gameTemp = JSON.parse(atob(importString)); for (var propertyName in gameTemp) { game[propertyName] = gameTemp[propertyName]; } updateUI(); } 

, updateUI(), — , , , , «» 30 .

.

Source: https://habr.com/ru/post/ar465829/


All Articles