10 KiB
بناء لعبة فضاء الجزء السادس: النهاية وإعادة البدء
اختبار ما قبل المحاضرة
هناك طرق مختلفة للتعبير عن شرط النهاية في اللعبة. الأمر متروك لك كمصمم للعبة لتحديد سبب انتهاء اللعبة. إليك بعض الأسباب، إذا افترضنا أننا نتحدث عن لعبة الفضاء التي كنت تبنيها حتى الآن:
- تم تدمير
N
من سفن الأعداء: من الشائع جدًا إذا قمت بتقسيم اللعبة إلى مستويات مختلفة أن تحتاج إلى تدميرN
من سفن الأعداء لإكمال المستوى. - تم تدمير سفينتك: هناك بالتأكيد ألعاب تخسر فيها إذا تم تدمير سفينتك. نهج شائع آخر هو وجود مفهوم "الحياة". في كل مرة يتم فيها تدمير سفينتك، يتم خصم حياة. بمجرد فقدان جميع الحيوات، تخسر اللعبة.
- جمعت
N
من النقاط: شرط نهاية شائع آخر هو جمع النقاط. كيفية الحصول على النقاط متروك لك، ولكن من الشائع جدًا تخصيص نقاط لأنشطة مختلفة مثل تدمير سفينة عدو أو جمع عناصر تسقط عند تدميرها. - إكمال مستوى: قد يتضمن ذلك عدة شروط مثل تدمير
X
من سفن الأعداء، جمعY
من النقاط، أو ربما جمع عنصر معين.
إعادة البدء
إذا استمتع اللاعبون بلعبتك، فمن المحتمل أن يرغبوا في إعادة لعبها. بمجرد انتهاء اللعبة لأي سبب كان، يجب أن تقدم خيارًا لإعادة البدء.
✅ فكر قليلاً في الظروف التي تجد فيها أن اللعبة تنتهي، ثم كيف يتم تحفيزك لإعادة البدء.
ما الذي ستبنيه
ستضيف هذه القواعد إلى لعبتك:
- الفوز باللعبة. بمجرد تدمير جميع سفن الأعداء، تفوز باللعبة. بالإضافة إلى ذلك، قم بعرض رسالة انتصار.
- إعادة البدء. بمجرد فقدان جميع الحيوات أو الفوز باللعبة، يجب أن تقدم طريقة لإعادة بدء اللعبة. تذكر! ستحتاج إلى إعادة تهيئة اللعبة ومسح حالة اللعبة السابقة.
الخطوات الموصى بها
حدد الملفات التي تم إنشاؤها لك في مجلد your-work
. يجب أن يحتوي على ما يلي:
-| assets
-| enemyShip.png
-| player.png
-| laserRed.png
-| life.png
-| index.html
-| app.js
-| package.json
ابدأ مشروعك في مجلد your_work
عن طريق كتابة:
cd your-work
npm start
سيؤدي ذلك إلى تشغيل خادم HTTP على العنوان http://localhost:5000
. افتح متصفحًا وأدخل هذا العنوان. يجب أن تكون لعبتك في حالة قابلة للعب.
نصيحة: لتجنب التحذيرات في Visual Studio Code، قم بتحرير وظيفة
window.onload
لاستدعاءgameLoopId
كما هي (بدونlet
)، وقم بتعريفgameLoopId
في أعلى الملف بشكل مستقل:let gameLoopId;
إضافة الكود
-
تتبع شرط النهاية. أضف كودًا يتتبع عدد الأعداء، أو إذا تم تدمير سفينة البطل عن طريق إضافة هاتين الوظيفتين:
function isHeroDead() { return hero.life <= 0; } function isEnemiesDead() { const enemies = gameObjects.filter((go) => go.type === "Enemy" && !go.dead); return enemies.length === 0; }
-
إضافة منطق إلى معالجات الرسائل. قم بتحرير
eventEmitter
للتعامل مع هذه الشروط:eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => { first.dead = true; second.dead = true; hero.incrementPoints(); if (isEnemiesDead()) { eventEmitter.emit(Messages.GAME_END_WIN); } }); eventEmitter.on(Messages.COLLISION_ENEMY_HERO, (_, { enemy }) => { enemy.dead = true; hero.decrementLife(); if (isHeroDead()) { eventEmitter.emit(Messages.GAME_END_LOSS); return; // loss before victory } if (isEnemiesDead()) { eventEmitter.emit(Messages.GAME_END_WIN); } }); eventEmitter.on(Messages.GAME_END_WIN, () => { endGame(true); }); eventEmitter.on(Messages.GAME_END_LOSS, () => { endGame(false); });
-
إضافة أنواع رسائل جديدة. أضف هذه الرسائل إلى كائن الثوابت:
GAME_END_LOSS: "GAME_END_LOSS", GAME_END_WIN: "GAME_END_WIN",
-
إضافة كود إعادة البدء. أضف كودًا يعيد تشغيل اللعبة عند الضغط على زر معين.
- الاستماع إلى الضغط على المفتاح
Enter
. قم بتحرير مستمع الأحداث الخاص بنافذتك للاستماع إلى هذا الضغط:
else if(evt.key === "Enter") { eventEmitter.emit(Messages.KEY_EVENT_ENTER); }
-
إضافة رسالة إعادة البدء. أضف هذه الرسالة إلى ثوابت الرسائل:
KEY_EVENT_ENTER: "KEY_EVENT_ENTER",
- الاستماع إلى الضغط على المفتاح
-
تنفيذ قواعد اللعبة. قم بتنفيذ قواعد اللعبة التالية:
-
شرط فوز اللاعب. عند تدمير جميع سفن الأعداء، قم بعرض رسالة انتصار.
- أولاً، قم بإنشاء وظيفة
displayMessage()
:
function displayMessage(message, color = "red") { ctx.font = "30px Arial"; ctx.fillStyle = color; ctx.textAlign = "center"; ctx.fillText(message, canvas.width / 2, canvas.height / 2); }
- قم بإنشاء وظيفة
endGame()
:
function endGame(win) { clearInterval(gameLoopId); // set a delay so we are sure any paints have finished setTimeout(() => { ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = "black"; ctx.fillRect(0, 0, canvas.width, canvas.height); if (win) { displayMessage( "Victory!!! Pew Pew... - Press [Enter] to start a new game Captain Pew Pew", "green" ); } else { displayMessage( "You died !!! Press [Enter] to start a new game Captain Pew Pew" ); } }, 200) }
- أولاً، قم بإنشاء وظيفة
-
منطق إعادة البدء. عند فقدان جميع الحيوات أو فوز اللاعب باللعبة، قم بعرض أن اللعبة يمكن إعادة تشغيلها. بالإضافة إلى ذلك، أعد تشغيل اللعبة عند الضغط على مفتاح إعادة البدء (يمكنك تحديد المفتاح الذي يجب تعيينه لإعادة البدء).
- قم بإنشاء وظيفة
resetGame()
:
function resetGame() { if (gameLoopId) { clearInterval(gameLoopId); eventEmitter.clear(); initGame(); gameLoopId = setInterval(() => { ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = "black"; ctx.fillRect(0, 0, canvas.width, canvas.height); drawPoints(); drawLife(); updateGameObjects(); drawGameObjects(ctx); }, 100); } }
- أضف استدعاءً إلى
eventEmitter
لإعادة تعيين اللعبة فيinitGame()
:
eventEmitter.on(Messages.KEY_EVENT_ENTER, () => { resetGame(); });
- أضف وظيفة
clear()
إلى EventEmitter:
clear() { this.listeners = {}; }
- قم بإنشاء وظيفة
-
👽 💥 🚀 تهانينا، أيها القبطان! لعبتك مكتملة! عمل رائع! 🚀 💥 👽
🚀 التحدي
أضف صوتًا! هل يمكنك إضافة صوت لتحسين تجربة اللعب، ربما عند إصابة الليزر، أو موت البطل، أو الفوز؟ ألقِ نظرة على هذا المثال لتتعلم كيفية تشغيل الصوت باستخدام JavaScript.
اختبار ما بعد المحاضرة
المراجعة والدراسة الذاتية
مهمتك هي إنشاء نموذج لعبة جديد، لذا استكشف بعض الألعاب المثيرة للاهتمام لمعرفة نوع اللعبة التي قد تبنيها.
المهمة
إخلاء المسؤولية:
تم ترجمة هذا المستند باستخدام خدمة الترجمة بالذكاء الاصطناعي Co-op Translator. بينما نسعى لتحقيق الدقة، يرجى العلم أن الترجمات الآلية قد تحتوي على أخطاء أو معلومات غير دقيقة. يجب اعتبار المستند الأصلي بلغته الأصلية المصدر الموثوق. للحصول على معلومات حاسمة، يُوصى بالاستعانة بترجمة بشرية احترافية. نحن غير مسؤولين عن أي سوء فهم أو تفسيرات خاطئة تنشأ عن استخدام هذه الترجمة.