12 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); });
-
اضافه کردن انواع جدید پیامها. این پیامها را به شیء constants اضافه کنید:
GAME_END_LOSS: "GAME_END_LOSS", GAME_END_WIN: "GAME_END_WIN",
-
اضافه کردن کد شروع مجدد کدی که بازی را با فشار یک دکمه انتخابی دوباره شروع کند.
- گوش دادن به فشار کلید
Enter
. EventListener پنجره خود را ویرایش کنید تا به این فشار گوش دهد:
else if(evt.key === "Enter") { eventEmitter.emit(Messages.KEY_EVENT_ENTER); }
-
اضافه کردن پیام شروع مجدد. این پیام را به ثابت Messages اضافه کنید:
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 = {}; }
-
👽 💥 🚀 تبریک میگویم، کاپیتان! بازی شما کامل شد! آفرین! 🚀 💥 👽
🚀 چالش
یک صدا اضافه کنید! آیا میتوانید یک صدا برای بهبود تجربه بازی اضافه کنید، مثلاً وقتی لیزر برخورد میکند، یا قهرمان میمیرد یا برنده میشود؟ به این sandbox نگاهی بیندازید تا یاد بگیرید چگونه با استفاده از JavaScript صدا پخش کنید.
آزمون پس از درس
مرور و مطالعه شخصی
تکلیف شما این است که یک نمونه بازی جدید ایجاد کنید، بنابراین برخی از بازیهای جالب موجود را بررسی کنید تا ببینید چه نوع بازیای ممکن است بسازید.
تکلیف
سلب مسئولیت:
این سند با استفاده از سرویس ترجمه هوش مصنوعی Co-op Translator ترجمه شده است. در حالی که ما برای دقت تلاش میکنیم، لطفاً توجه داشته باشید که ترجمههای خودکار ممکن است شامل خطاها یا نادرستیهایی باشند. سند اصلی به زبان بومی آن باید به عنوان منبع معتبر در نظر گرفته شود. برای اطلاعات حساس، ترجمه حرفهای انسانی توصیه میشود. ما هیچ مسئولیتی در قبال سوءتفاهمها یا تفسیرهای نادرست ناشی از استفاده از این ترجمه نداریم.