# အာကာသဂိမ်းတည်ဆောက်ခြင်း အပိုင်း ၆: အဆုံးနှင့် ပြန်စတင်ခြင်း တစ်ခုတည်းသောဂိမ်းတစ်ခုမှာ အဆုံးသတ်အခြေအနေများနှင့် ပြန်စတင်နိုင်သောစနစ်တစ်ခု ရှင်းလင်းစွာရှိရမည်။ သင်တည်ဆောက်ထားသော အာကာသဂိမ်းသည် လှုပ်ရှားမှု၊ တိုက်ခိုက်မှုနှင့် အမှတ်ရရှိမှုတို့ပါဝင်ပြီး အံ့ဩဖွယ်ကောင်းသည် - ယခုအချိန်တွင် အဆုံးသတ်အပိုင်းများကို ထည့်သွင်းရန် အချိန်ရောက်ပါပြီ။ သင်၏ဂိမ်းသည် ယခုအချိန်တွင် NASA မှ ၁၉၇၇ ခုနှစ်တွင် ပျံသန်းခဲ့သော Voyager ပရိုဘ်များကဲ့သို့ အဆုံးမရှိဘဲ လည်ပတ်နေသည် - ဆယ်စုနှစ်များစွာအကြာတွင် အာကာသတွင် ခရီးဆက်နေဆဲဖြစ်သည်။ အာကာသလေ့လာမှုအတွက် အဆင်ပြေသော်လည်း၊ ဂိမ်းများသည် စိတ်ကျေနပ်မှုကို ဖန်တီးရန် အဆုံးသတ်အချက်များလိုအပ်သည်။ ယနေ့တွင် ကျွန်ုပ်တို့သည် အနိုင်/အရှုံးအခြေအနေများနှင့် ပြန်စတင်စနစ်ကို အကောင်အထည်ဖော်မည်။ ဒီသင်ခန်းစာအဆုံးတွင် သင်သည် ကစားသူများအတွက် ပြီးမြောက်ပြီး ပြန်ကစားနိုင်သော polished game တစ်ခုကို ရရှိမည်ဖြစ်သည်။ ၎င်းသည် ဂိမ်းမီဒီယမ်ကို သတ်မှတ်ခဲ့သော arcade game များကဲ့သို့ဖြစ်သည်။ ## သင်ခန်းစာမတိုင်မီမေးခွန်း [Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/39) ## ဂိမ်းအဆုံးသတ်အခြေအနေများကို နားလည်ခြင်း သင်၏ဂိမ်းသည် မည်သည့်အချိန်တွင် အဆုံးသတ်သင့်သနည်း။ ဤအခြေခံမေးခွန်းသည် arcade game အချိန်ကာလမှစ၍ ဂိမ်းဒီဇိုင်းကို ပုံဖော်ခဲ့သည်။ Pac-Man သည် သင်သည် သရဲများထံတွင် ဖမ်းမိသို့မဟုတ် dot အားလုံးကို ရှင်းလင်းသောအခါ အဆုံးသတ်သည်။ Space Invaders သည် ဂြိုလ်သားများသည် အောက်ခြေသို့ ရောက်သောအခါ သို့မဟုတ် သင်သည် ၎င်းတို့အား ဖျက်ဆီးသောအခါ အဆုံးသတ်သည်။ ဂိမ်းဖန်တီးသူအနေဖြင့် သင်သည် အနိုင်နှင့် အရှုံးအခြေအနေများကို သတ်မှတ်သည်။ ကျွန်ုပ်တို့၏ အာကာသဂိမ်းအတွက် စိတ်ဝင်စားဖွယ်ကောင်းသော gameplay ကို ဖန်တီးသော အောက်ပါနည်းလမ်းများကို အသုံးပြုနိုင်သည်- - **`N` ရန်သူသင်္ဘောများ ဖျက်ဆီးပြီး**: ဂိမ်းကို အဆင့်အလိုက် ခွဲခြားထားသောအခါ `N` ရန်သူသင်္ဘောများကို ဖျက်ဆီးရန်လိုအပ်သည်။ - **သင်၏သင်္ဘော ဖျက်ဆီးခံရသည်**: သင်၏သင်္ဘော ဖျက်ဆီးခံရသောအခါ ဂိမ်းကို ရှုံးနိမ့်ရမည်ဖြစ်သော ဂိမ်းများလည်း ရှိသည်။ အခြားနည်းလမ်းတစ်ခုမှာ အသက်များ၏ အယူအဆကို အသုံးပြုခြင်းဖြစ်သည်။ သင်၏သင်္ဘော ဖျက်ဆီးခံရသောအခါ အသက်တစ်ခုကို လျော့ချပေးသည်။ အသက်အားလုံးဆုံးရှုံးသွားသောအခါ ဂိမ်းကို ရှုံးနိမ့်ရမည်။ - **`N` အမှတ်များ ရရှိထားသည်**: အခြားသော အဆုံးသတ်အခြေအနေမှာ အမှတ်များကို ရရှိထားခြင်းဖြစ်သည်။ သင်သည် အမှတ်ရရှိရန် နည်းလမ်းများကို သတ်မှတ်နိုင်သည်။ ရန်သူသင်္ဘောကို ဖျက်ဆီးခြင်း သို့မဟုတ် ဖျက်ဆီးသောအခါ items များကို စုဆောင်းခြင်းကဲ့သို့သော လှုပ်ရှားမှုများကို အမှတ်ပေးခြင်းသည် အလွန်ရိုးရှင်းသော နည်းလမ်းဖြစ်သည်။ - **အဆင့်တစ်ခုကို ပြီးမြောက်စေခြင်း**: ဤအဆင့်တွင် `X` ရန်သူသင်္ဘောများ ဖျက်ဆီးခြင်း၊ `Y` အမှတ်များ ရရှိခြင်း သို့မဟုတ် အထူးပစ္စည်းတစ်ခုကို ရရှိထားခြင်းကဲ့သို့သော အခြေအနေများစွာ ပါဝင်နိုင်သည်။ ## ဂိမ်းပြန်စတင်စနစ်ကို အကောင်အထည်ဖော်ခြင်း ကောင်းမွန်သောဂိမ်းများသည် ပြန်ကစားနိုင်မှုကို အဆင်ပြေသော ပြန်စတင်စနစ်များမှတစ်ဆင့် အားပေးသည်။ ကစားသူများသည် ဂိမ်းကို ပြီးမြောက်သောအခါ (သို့မဟုတ် ရှုံးနိမ့်သောအခါ) ချက်ချင်း ပြန်စတင်လိုကြသည် - ၎င်းသည် ၎င်းတို့၏ အမှတ်ကို ကျော်လွန်ရန် သို့မဟုတ် ၎င်းတို့၏ စွမ်းဆောင်ရည်ကို တိုးတက်စေရန် ဖြစ်သည်။ Tetris သည် ဤအချက်ကို အလွန်ကောင်းစွာ ဖော်ပြထားသည် - သင်၏ block များသည် ထိပ်သို့ ရောက်သောအခါ သင်သည် ရှုပ်ထွေးသော menu များကို မဖြတ်သန်းဘဲ ချက်ချင်း ဂိမ်းအသစ်ကို စတင်နိုင်သည်။ ကျွန်ုပ်တို့သည် ဤကဲ့သို့သော ပြန်စတင်စနစ်ကို တည်ဆောက်မည်ဖြစ်ပြီး ဂိမ်းအခြေအနေကို သန့်ရှင်းစွာ ပြန်စတင်ပြီး ကစားသူများကို အလျင်အမြန် လှုပ်ရှားမှုထဲသို့ ပြန်လည်ရောက်ရှိစေမည်။ ✅ **အတွေးအမြင်**: သင်ကစားဖူးသောဂိမ်းများအကြောင်းတွင် စဉ်းစားပါ။ ၎င်းတို့သည် မည်သည့်အခြေအနေတွင် အဆုံးသတ်ပြီး သင်ကို ပြန်စတင်ရန် မည်သို့ အကြောင်းပြုသနည်း။ ပြန်စတင်ခြင်းအတွေ့အကြုံကို အဆင်ပြေစေသောအရာများနှင့် စိတ်ပျက်စေသောအရာများက ဘာတွေလဲ။ ## သင်တည်ဆောက်မည့်အရာ သင်၏ပရောဂျက်ကို ပြီးမြောက်သောဂိမ်းအတွေ့အကြုံတစ်ခုအဖြစ် ပြောင်းလဲစေမည့် နောက်ဆုံးအင်္ဂါရပ်များကို သင်တည်ဆောက်မည်။ ဤအရာများသည် polished game များကို အခြေခံ prototype များနှင့် ခွဲခြားစေသည်။ **ယနေ့တွင် ကျွန်ုပ်တို့ထည့်သွင်းမည့်အရာများမှာ**- 1. **အနိုင်အခြေအနေ**: ရန်သူအားလုံးကို ဖျက်ဆီးပြီး အောင်ပွဲခံစားမှုကို ရယူပါ (သင်သည် ၎င်းကို ရရှိရန် အကျိုးရှိသည်!) 2. **အရှုံးအခြေအနေ**: အသက်များကုန်ဆုံးပြီး အရှုံးအခြေအနေ screen ကို ကြုံတွေ့ရမည် 3. **ပြန်စတင်စနစ်**: Enter ကိုနှိပ်ပြီး ချက်ချင်း ပြန်စတင်ပါ - ဂိမ်းတစ်ခုသည် တစ်ခါတည်းမှာ မလုံလောက်ပါ 4. **အခြေအနေ စီမံခန့်ခွဲမှု**: တစ်ခါစတင်တိုင်း သန့်ရှင်းသောအခြေအနေ - ရန်သူများ သို့မဟုတ် အရင်ဂိမ်းမှ အမှားများမရှိပါ ## စတင်ရန် သင်၏ development environment ကို ပြင်ဆင်ပါ။ အရင် lessons များမှ အာကာသဂိမ်းဖိုင်များအားလုံးကို သင်မှာရှိထားသင့်သည်။ **သင်၏ပရောဂျက်သည် ဤကဲ့သို့ ဖြစ်သင့်သည်**- ```bash -| assets -| enemyShip.png -| player.png -| laserRed.png -| life.png -| index.html -| app.js -| package.json ``` **သင်၏ development server ကို စတင်ပါ**- ```bash cd your-work npm start ``` **ဤ command သည်**- - `http://localhost:5000` တွင် local server ကို လည်ပတ်စေသည် - သင်၏ဖိုင်များကို သေချာစွာ ပေးဆောင်သည် - သင်ပြောင်းလဲမှုများပြုလုပ်သောအခါ အလိုအလျောက် refresh လုပ်သည် `http://localhost:5000` ကို သင်၏ browser တွင် ဖွင့်ပြီး သင်၏ဂိမ်းကို လည်ပတ်နေကြောင်း အတည်ပြုပါ။ သင်သည် လှုပ်ရှားနိုင်၊ ပစ်ခတ်နိုင်၊ ရန်သူများနှင့် အပြန်အလှန်လုပ်ဆောင်နိုင်သည်။ အတည်ပြုပြီးပါက ကျွန်ုပ်တို့သည် အကောင်အထည်ဖော်မှုကို ဆက်လက်လုပ်ဆောင်နိုင်ပါပြီ။ > 💡 **အကြံပေးချက်**: Visual Studio Code တွင် warning များကို ရှောင်ရှားရန် `gameLoopId` ကို သင်၏ဖိုင်၏ထိပ်တွင် `let gameLoopId;` အဖြစ် ကြေညာပါ။ ၎င်းသည် ခေတ်မီ JavaScript variable ကြေညာမှုအကောင်းဆုံးအလေ့အထ၏ နောက်လိုက်ခြင်းဖြစ်သည်။ ## အကောင်အထည်ဖော်မှုအဆင့်များ ### အဆင့် ၁: အဆုံးသတ်အခြေအနေများကို စောင့်ကြည့်သော function များဖန်တီးခြင်း ဂိမ်းသည် မည်သည့်အချိန်တွင် အဆုံးသတ်သင့်သည်ကို စောင့်ကြည့်ရန် function များလိုအပ်သည်။ International Space Station တွင် အရေးကြီးသောစနစ်များကို အမြဲတမ်း စောင့်ကြည့်နေသော sensor များကဲ့သို့ ဤ function များသည် ဂိမ်းအခြေအနေကို အမြဲတမ်း စစ်ဆေးမည်။ ```javascript function isHeroDead() { return hero.life <= 0; } function isEnemiesDead() { const enemies = gameObjects.filter((go) => go.type === "Enemy" && !go.dead); return enemies.length === 0; } ``` **ဤနေရာတွင် အောက်ပါအရာများကို လုပ်ဆောင်ထားသည်**- - **စစ်ဆေးသည်** ကျွန်ုပ်တို့၏ hero သက်ရှိမရှိ (အန္တရာယ်!) - **ရေတွက်သည်** ရန်သူများ အလုံးအရေအတွက် - **အတည်ပြုသည်** ရန်သူများအားလုံး ဖျက်ဆီးပြီးပါက `true` ပြန်ပေးသည် - **ရိုးရှင်းသော true/false logic ကို အသုံးပြုသည်** - **filter လုပ်သည်** ဂိမ်း object အားလုံးကို စစ်ဆေးပြီး အသက်ရှင်သောသူများကို ရှာဖွေသည် ### အဆင့် ၂: အဆုံးသတ်အခြေအနေများအတွက် Event Handler များကို update လုပ်ခြင်း ယခုအခါ ကျွန်ုပ်တို့သည် ဤအခြေအနေစစ်ဆေးမှုများကို ဂိမ်း၏ event system နှင့် ချိတ်ဆက်မည်။ collision ဖြစ်ပွားသောအခါတိုင်း ဂိမ်းသည် အဆုံးသတ်အခြေအနေကို ဖြစ်စေမည်မဟုတ်မည်ကို အကဲဖြတ်မည်။ ဤအရာသည် အရေးကြီးသောဂိမ်းဖြစ်ရပ်များအတွက် ချက်ချင်းတုံ့ပြန်မှုကို ဖန်တီးပေးသည်။ ```javascript 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); }); ``` **ဤနေရာတွင် ဖြစ်ပျက်နေသောအရာများ**- - **Laser သည် ရန်သူကို ထိသည်**: နှစ်ခုလုံးပျောက်ကွယ်ပြီး သင်သည် အမှတ်ရရှိပြီး သင်အနိုင်ရသွားကြောင်း စစ်ဆေးသည် - **ရန်သူသည် သင်ကို ထိသည်**: သင်၏အသက်တစ်ခုကို ဆုံးရှုံးပြီး သင်အသက်ရှင်နေသေးသလား စစ်ဆေးသည် - **စဉ်စီမှု**: အရှုံးကို အရင်စစ်ဆေးသည် (အနိုင်ရပြီး အရှုံးနိမ့်ရတာကို မည်သူမျှ မကြိုက်ပါ!) - **ချက်ချင်းတုံ့ပြန်မှု**: အရေးကြီးသောအရာတစ်ခု ဖြစ်ပွားသောအခါ ဂိမ်းသည် ၎င်းကို သိရှိသည် ### အဆင့် ၃: Message Constants အသစ်များ ထည့်သွင်းခြင်း သင်၏ `Messages` constant object တွင် ဂိမ်းအဆုံးသတ်ဖြစ်ရပ်များအတွက် message အမျိုးအစားအသစ်များကို ထည့်သွင်းရန် လိုအပ်သည်။ ဤ constant များသည် consistency ကို ထိန်းသိမ်းရန်နှင့် event system တွင် စာလုံးပေါင်းမှားမှုများကို ကာကွယ်ရန် အထောက်အကူပြုသည်။ ```javascript GAME_END_LOSS: "GAME_END_LOSS", GAME_END_WIN: "GAME_END_WIN", ``` **အထက်တွင် ကျွန်ုပ်တို့**- - **ထည့်သွင်းထားသည်** ဂိမ်းအဆုံးသတ်ဖြစ်ရပ်များအတွက် constant များ - **အသုံးပြုထားသည်** ဖြစ်ရပ်ရည်ရွယ်ချက်ကို ရှင်းလင်းစွာ ဖော်ပြသော အမည်များ - **နာမည်ပုံစံကို** ရှိပြီးသား naming convention ကို လိုက်နာထားသည် ### အဆင့် ၄: ပြန်စတင်ရန် ထိန်းချုပ်မှုများကို အကောင်အထည်ဖော်ခြင်း ယခုအခါ သင်သည် ကစားသူများအား ဂိမ်းကို ပြန်စတင်ရန် ခလုတ်ထိန်းချုပ်မှုများကို ထည့်သွင်းမည်။ Enter key သည် အလွန်သဘာဝကျပြီး အတည်ပြုမှုများနှင့် ဂိမ်းအသစ်များစတင်ခြင်းနှင့် ဆက်စပ်နေသောကြောင့် သင့်လျော်သည်။ **သင်၏ keydown event listener တွင် Enter key ကို detect လုပ်ပါ**- ```javascript else if(evt.key === "Enter") { eventEmitter.emit(Messages.KEY_EVENT_ENTER); } ``` **Message constant အသစ်ကို ထည့်သွင်းပါ**- ```javascript KEY_EVENT_ENTER: "KEY_EVENT_ENTER", ``` **သင်သိထားသင့်သောအရာများ**- - **ရှိပြီးသား keyboard event handling system ကို** တိုးချဲ့သည် - **Enter key ကို** ပြန်စတင်မှု trigger အဖြစ် အသုံးပြုသည် - **custom event ကို** emit လုပ်ပြီး ဂိမ်း၏ အခြားအစိတ်အပိုင်းများက ၎င်းကို နားထောင်နိုင်သည် - **အခြား keyboard controls များနှင့်** တူညီသော pattern ကို ထိန်းသိမ်းထားသည် ### အဆင့် ၅: Message Display System ကို ဖန်တီးခြင်း သင်၏ဂိမ်းသည် ကစားသူများအား ရလဒ်များကို ရှင်းလင်းစွာ ဆက်သွယ်ရန် လိုအပ်သည်။ ကျွန်ုပ်တို့သည် victory နှင့် defeat state များကို အရောင်သတ်မှတ်ထားသော text ဖြင့် ဖော်ပြမည့် message system ကို ဖန်တီးမည်။ ဤအရာသည် အောင်မြင်မှုကို အစိမ်းရောင်ဖြင့် ဖော်ပြပြီး အမှားများကို အနီရောင်ဖြင့် ဖော်ပြသော computer system interface များကဲ့သို့ ဖြစ်သည်။ **`displayMessage()` function ကို ဖန်တီးပါ**- ```javascript function displayMessage(message, color = "red") { ctx.font = "30px Arial"; ctx.fillStyle = color; ctx.textAlign = "center"; ctx.fillText(message, canvas.width / 2, canvas.height / 2); } ``` **အဆင့်ဆင့် ဖြစ်ပျက်နေသောအရာများ**- - **font size နှင့် family ကို** သတ်မှတ်ထားပြီး စာသားကို ရှင်းလင်းစွာ ဖတ်နိုင်သည် - **အရောင် parameter ကို** အသုံးပြုပြီး warning များအတွက် "red" ကို default အဖြစ် သတ်မှတ်ထားသည် - **စာသားကို** canvas ၏ horizontal နှင့် vertical အလယ်တွင် အလယ်ထားသည် - **modern JavaScript default parameters ကို** အသုံးပြုပြီး flexible color options ရရှိစေသည် - **canvas 2D context ကို** အသုံးပြုပြီး text ကို တိုက်ရိုက် render လုပ်သည် **`endGame()` function ကို ဖန်တီးပါ**- ```javascript function endGame(win) { clearInterval(gameLoopId); // Set a delay to ensure any pending renders complete 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) } ``` **ဤ function သည်**- - **အရာအားလုံးကို** ရပ်တန့်စေသည် - သင်္ဘောများ သို့မဟုတ် laser များ မလှုပ်ရှားတော့ - **200ms အနည်းငယ်ရပ်နားပြီး** နောက်ဆုံး frame ကို finish drawing လုပ်စေသည် - **screen ကို** သန့်စင်ပြီး အနက်ရောင်ဖြင့် dramatic effect ရရှိစေသည် - **အနိုင်ရသူများနှင့် အရှုံးနိမ့်သူများအတွက်** မတူညီသော message များကို ဖော်ပြသည် - **အရောင်သတ်မှတ်ထားသည်** - အောင်မြင်မှု --- **အကြောင်းကြားချက်**: ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု [Co-op Translator](https://github.com/Azure/co-op-translator) ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း အလိုအလျောက် ဘာသာပြန်ခြင်းတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါဝင်နိုင်သည်ကို သတိပြုပါ။ မူရင်းဘာသာစကားဖြင့် ရေးသားထားသော စာရွက်စာတမ်းကို အာဏာတရားရှိသော အရင်းအမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များကို အသုံးပြုရန် အကြံပြုပါသည်။ ဤဘာသာပြန်ကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအမှားများ သို့မဟုတ် အနားလွဲမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။