17 KiB
Gumawa ng Space Game Bahagi 6: Pagtapos at Pag-restart
Ang bawat mahusay na laro ay nangangailangan ng malinaw na kondisyon ng pagtatapos at maayos na mekanismo ng pag-restart. Nakagawa ka na ng kahanga-hangang space game na may galaw, labanan, at pag-score - ngayon ay oras na para idagdag ang mga huling bahagi upang ito'y maging kumpleto.
Ang iyong laro ay kasalukuyang tumatakbo nang walang katapusan, tulad ng Voyager probes na inilunsad ng NASA noong 1977 - patuloy na naglalakbay sa kalawakan dekada na ang nakalipas. Bagamat ito'y maayos para sa eksplorasyon ng kalawakan, ang mga laro ay nangangailangan ng tiyak na mga endpoint upang lumikha ng kasiya-siyang karanasan.
Ngayon, magpapatupad tayo ng tamang kondisyon ng panalo/pagkatalo at sistema ng pag-restart. Sa pagtatapos ng araling ito, magkakaroon ka ng pinakinis na laro na maaaring tapusin at ulitin ng mga manlalaro, tulad ng mga klasikong arcade games na nagbigay-daan sa medium.
Pre-Lecture Quiz
Pag-unawa sa Kondisyon ng Pagtatapos ng Laro
Kailan dapat matapos ang iyong laro? Ang pangunahing tanong na ito ay humubog sa disenyo ng laro mula pa noong panahon ng mga arcade. Ang Pac-Man ay nagtatapos kapag nahuli ka ng mga multo o nalinis mo ang lahat ng mga tuldok, habang ang Space Invaders ay nagtatapos kapag ang mga alien ay umabot sa ibaba o nawasak mo silang lahat.
Bilang tagalikha ng laro, ikaw ang magtatakda ng mga kondisyon ng tagumpay at pagkatalo. Para sa ating space game, narito ang mga napatunayang paraan upang lumikha ng nakaka-engganyong gameplay:
NMga barko ng kaaway ang nawasak: Karaniwan ito kung hinahati mo ang laro sa iba't ibang antas kung saan kailangan mong wasakin angNbarko ng kaaway upang makumpleto ang isang antas.- Ang iyong barko ay nawasak: May mga laro kung saan talo ka kapag ang iyong barko ay nawasak. Isa pang karaniwang paraan ay ang konsepto ng buhay. Tuwing ang iyong barko ay nawasak, nababawasan ang isang buhay. Kapag naubos na ang lahat ng buhay, talo ka na.
- Nakolekta mo ang
Npuntos: Isa pang karaniwang kondisyon ng pagtatapos ay ang pagkolekta ng puntos. Paano ka makakakuha ng puntos ay depende sa iyo, ngunit karaniwan itong ibinibigay sa iba't ibang aktibidad tulad ng pagwasak sa barko ng kaaway o pagkolekta ng mga item na bumabagsak kapag sila'y nawasak. - Nakumpleto ang isang antas: Maaaring kabilang dito ang ilang kondisyon tulad ng
Xbarko ng kaaway na nawasak,Ypuntos na nakolekta, o maaaring isang tiyak na item ang nakolekta.
Pagpapatupad ng Pag-restart ng Laro
Ang magagandang laro ay naghihikayat ng replayability sa pamamagitan ng maayos na mekanismo ng pag-restart. Kapag natapos ng mga manlalaro ang isang laro (o natalo), madalas nilang gustong subukan ulit agad - upang talunin ang kanilang score o pagbutihin ang kanilang performance.
Ang Tetris ay perpektong halimbawa nito: kapag ang iyong mga bloke ay umabot sa itaas, maaari kang agad magsimula ng bagong laro nang hindi dumadaan sa mga komplikadong menu. Gagawa tayo ng katulad na sistema ng pag-restart na maayos na magre-reset ng estado ng laro at agad na maibabalik ang mga manlalaro sa aksyon.
✅ Pagmuni-muni: Isipin ang mga larong nilaro mo. Sa anong mga kondisyon sila nagtatapos, at paano ka hinihikayat na mag-restart? Ano ang nagpapadama ng maayos na karanasan sa pag-restart kumpara sa nakakainis?
Ano ang Iyong Itatayo
Ipapatupad mo ang mga huling tampok na magpapabago sa iyong proyekto sa isang kumpletong karanasan sa laro. Ang mga elementong ito ang nagtatangi sa mga pinakinis na laro mula sa mga simpleng prototype.
Narito ang idadagdag natin ngayon:
- Kondisyon ng tagumpay: Wasakin ang lahat ng kaaway at makakuha ng tamang selebrasyon (karapat-dapat ka dito!)
- Kondisyon ng pagkatalo: Maubos ang buhay at harapin ang musika gamit ang defeat screen
- Mekanismo ng pag-restart: Pindutin ang Enter upang agad bumalik - dahil hindi sapat ang isang laro
- Pamamahala ng estado: Malinis na simula sa bawat oras - walang natirang kaaway o kakaibang glitches mula sa nakaraang laro
Pagsisimula
Ihanda ang iyong development environment. Dapat mayroon kang lahat ng iyong space game files mula sa mga nakaraang aralin.
Ang iyong proyekto ay dapat magmukhang ganito:
-| assets
-| enemyShip.png
-| player.png
-| laserRed.png
-| life.png
-| index.html
-| app.js
-| package.json
Simulan ang iyong development server:
cd your-work
npm start
Ang utos na ito:
- Nagpapatakbo ng lokal na server sa
http://localhost:5000 - Maayos na nagsisilbi sa iyong mga file
- Awtomatikong nagre-refresh kapag may mga pagbabago
Buksan ang http://localhost:5000 sa iyong browser at tiyaking tumatakbo ang iyong laro. Dapat kang makagalaw, makaputok, at makipag-ugnayan sa mga kaaway. Kapag nakumpirma, maaari na tayong magpatuloy sa pagpapatupad.
💡 Pro Tip: Upang maiwasan ang mga babala sa Visual Studio Code, ideklara ang
gameLoopIdsa itaas ng iyong file bilanglet gameLoopId;sa halip na ideklara ito sa loob ngwindow.onloadfunction. Sinusunod nito ang modernong JavaScript variable declaration best practices.
Mga Hakbang sa Pagpapatupad
Hakbang 1: Gumawa ng Mga Function para sa Pagsubaybay sa Kondisyon ng Pagtatapos
Kailangan natin ng mga function upang subaybayan kung kailan dapat matapos ang laro. Tulad ng mga sensor sa International Space Station na patuloy na nagmo-monitor ng mga kritikal na sistema, ang mga function na ito ay patuloy na susuriin ang estado ng laro.
function isHeroDead() {
return hero.life <= 0;
}
function isEnemiesDead() {
const enemies = gameObjects.filter((go) => go.type === "Enemy" && !go.dead);
return enemies.length === 0;
}
Narito ang nangyayari sa ilalim:
- Sinusuri kung ang ating hero ay naubusan ng buhay (ouch!)
- Binibilang kung ilan pang kaaway ang buhay at lumalaban
- Nagbabalik ng
truekapag malinis na ang battlefield mula sa mga kaaway - Gumagamit ng simpleng true/false logic upang panatilihing direkta ang mga bagay
- Nagsasala sa lahat ng game objects upang hanapin ang mga nakaligtas
Hakbang 2: I-update ang Event Handlers para sa Kondisyon ng Pagtatapos
Ngayon ay ikokonekta natin ang mga pagsusuri ng kondisyon sa event system ng laro. Tuwing may nagaganap na banggaan, susuriin ng laro kung ito'y nag-trigger ng kondisyon ng pagtatapos. Ito'y lumilikha ng agarang feedback para sa mga kritikal na kaganapan sa laro.
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);
});
Narito ang nangyayari:
- Laser tumama sa kaaway: Parehong nawawala, nakakakuha ka ng puntos, at sinusuri kung nanalo ka
- Kaaway tumama sa iyo: Nawawala ka ng buhay, at sinusuri kung buhay ka pa
- Matalinong pagkakasunod-sunod: Sinusuri muna ang pagkatalo (walang gustong manalo at matalo nang sabay!)
- Agarang reaksyon: Kapag may mahalagang nangyari, alam ito ng laro
Hakbang 3: Magdagdag ng Bagong Constants para sa Mensahe
Kailangan mong magdagdag ng mga bagong uri ng mensahe sa iyong Messages constant object. Ang mga constants na ito ay tumutulong sa pagpapanatili ng pagkakapare-pareho at pag-iwas sa mga typo sa iyong event system.
GAME_END_LOSS: "GAME_END_LOSS",
GAME_END_WIN: "GAME_END_WIN",
Sa itaas, ginawa natin:
- Nagdagdag ng constants para sa mga event ng pagtatapos ng laro upang mapanatili ang pagkakapare-pareho
- Gumamit ng mga deskriptibong pangalan na malinaw na nagpapahiwatig ng layunin ng event
- Sinunod ang umiiral na naming convention para sa mga uri ng mensahe
Hakbang 4: Magpatupad ng Kontrol para sa Pag-restart
Ngayon ay magdadagdag ka ng keyboard controls na magpapahintulot sa mga manlalaro na i-restart ang laro. Ang Enter key ay natural na pagpipilian dahil karaniwan itong nauugnay sa pag-apruba ng mga aksyon at pagsisimula ng mga bagong laro.
Magdagdag ng Enter key detection sa iyong umiiral na keydown event listener:
else if(evt.key === "Enter") {
eventEmitter.emit(Messages.KEY_EVENT_ENTER);
}
Idagdag ang bagong constant para sa mensahe:
KEY_EVENT_ENTER: "KEY_EVENT_ENTER",
Ang kailangan mong malaman:
- Pinalawak ang umiiral na sistema ng paghawak ng keyboard event
- Ginamit ang Enter key bilang trigger para sa pag-restart para sa intuitive na karanasan ng user
- Naglabas ng custom na event na maaaring pakinggan ng ibang bahagi ng iyong laro
- Pinanatili ang parehong pattern tulad ng iyong iba pang keyboard controls
Hakbang 5: Gumawa ng Sistema ng Pag-display ng Mensahe
Ang iyong laro ay kailangang malinaw na makipag-usap ng resulta sa mga manlalaro. Gagawa tayo ng sistema ng mensahe na nagpapakita ng mga estado ng tagumpay at pagkatalo gamit ang color-coded na teksto, katulad ng mga terminal interface ng mga unang computer system kung saan ang berde ay nagpapahiwatig ng tagumpay at pula ay nagpapahiwatig ng error.
Gumawa ng displayMessage() function:
function displayMessage(message, color = "red") {
ctx.font = "30px Arial";
ctx.fillStyle = color;
ctx.textAlign = "center";
ctx.fillText(message, canvas.width / 2, canvas.height / 2);
}
Hakbang-hakbang, narito ang nangyayari:
- Itinatakda ang font size at family para sa malinaw at nababasang teksto
- Nag-aaplay ng color parameter na may "red" bilang default para sa mga babala
- Ine-center ang teksto nang pahalang at patayo sa canvas
- Gumagamit ng modernong default parameters ng JavaScript para sa flexible na color options
- Ginagamit ang canvas 2D context para sa direktang pag-render ng teksto
Gumawa ng endGame() function:
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)
}
Ang ginagawa ng function na ito:
- Pinipigil ang lahat ng galaw - wala nang gumagalaw na barko o laser
- Nagbibigay ng maliit na pause (200ms) upang matapos ang huling frame na ma-drawing
- Nililinis ang screen at pinipinturahan ito ng itim para sa dramatikong epekto
- Nagpapakita ng iba't ibang mensahe para sa mga nanalo at natalo
- Nagbibigay ng kulay sa balita - berde para sa maganda, pula para sa... hindi maganda
- Sinasabi sa mga manlalaro kung paano agad bumalik sa laro
Hakbang 6: Magpatupad ng Pag-reset ng Laro
Ang sistema ng pag-reset ay kailangang ganap na linisin ang kasalukuyang estado ng laro at mag-initialize ng bagong session ng laro. Tinitiyak nito na ang mga manlalaro ay makakakuha ng malinis na simula nang walang natirang data mula sa nakaraang laro.
Gumawa ng resetGame() function:
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);
}
}
Unawain ang bawat bahagi:
- Sinusuri kung may kasalukuyang game loop bago mag-reset
- Nililinis ang umiiral na game loop upang ihinto ang lahat ng kasalukuyang aktibidad ng laro
- Inaalis ang lahat ng event listeners upang maiwasan ang memory leaks
- Ini-reinitialize ang estado ng laro gamit ang mga bagong object at variable
- Sinisimulan ang bagong game loop na may lahat ng mahahalagang function ng laro
- Pinapanatili ang parehong 100ms interval para sa pare-parehong performance ng laro
Idagdag ang Enter key event handler sa iyong initGame() function:
eventEmitter.on(Messages.KEY_EVENT_ENTER, () => {
resetGame();
});
Idagdag ang clear() method sa iyong EventEmitter class:
clear() {
this.listeners = {};
}
Mga mahalagang punto na dapat tandaan:
- Ikokonekta ang Enter key press sa functionality ng pag-reset ng laro
- Ire-rehistro ang event listener na ito sa panahon ng initialization ng laro
- Nagbibigay ng malinis na paraan upang alisin ang lahat ng event listeners kapag nag-reset
- Pinipigilan ang memory leaks sa pamamagitan ng pag-clear ng event handlers sa pagitan ng mga laro
- Ire-reset ang listeners object sa isang empty state para sa sariwang initialization
Binabati kita! 🎉
👽 💥 🚀 Matagumpay mong naitayo ang isang kumpletong laro mula sa simula. Tulad ng mga programmer na lumikha ng mga unang video games noong 1970s, na-transform mo ang mga linya ng code sa isang interactive na karanasan na may tamang game mechanics at user feedback. 🚀 💥 👽
Na-accomplish mo:
- Naipatupad ang kumpletong kondisyon ng panalo at pagkatalo na may user feedback
- Nilikha ang seamless restart system para sa tuloy-tuloy na gameplay
- Dinisenyo ang malinaw na visual communication para sa mga estado ng laro
- Pinamahalaan ang mga kumplikadong transition ng estado ng laro at cleanup
- Pinagsama-sama ang lahat ng components sa isang cohesive, playable na laro
Hamon ng GitHub Copilot Agent 🚀
Gamitin ang Agent mode upang tapusin ang sumusunod na hamon:
Deskripsyon: Pagandahin ang space game sa pamamagitan ng pagpapatupad ng sistema ng level progression na may tumataas na kahirapan at bonus features.
Prompt: Gumawa ng multi-level space game system kung saan ang bawat level ay may mas maraming barko ng kaaway na may mas mataas na bilis at health. Magdagdag ng scoring multiplier na tumataas sa bawat level, at magpatupad ng power-ups (tulad ng rapid fire o shield) na random na lumalabas kapag nawasak ang mga kaaway. Isama ang level completion bonus at ipakita ang kasalukuyang level sa screen kasama ang umiiral na score at buhay.
Alamin ang higit pa tungkol sa agent mode dito.
🚀 Opsyonal na Hamon sa Pagpapahusay
Magdagdag ng Audio sa Iyong Laro: Pagandahin ang karanasan sa gameplay sa pamamagitan ng pagpapatupad ng mga sound effects! Isaalang-alang ang pagdagdag ng audio para sa:
- Laser shots kapag nagpaputok ang manlalaro
- Pagkawasak ng kaaway kapag tinamaan ang mga barko
- Pinsala sa hero kapag tinamaan ang manlalaro
- Victory music kapag nanalo ang laro
- Defeat sound kapag natalo ang laro
Halimbawa ng pagpapatupad ng audio:
// Create audio objects
const laserSound = new Audio('assets/laser.wav');
const explosionSound = new Audio('assets/explosion.wav');
// Play sounds during game events
function playLaserSound() {
laserSound.currentTime = 0; // Reset to beginning
laserSound.play();
}
Ang kailangan mong malaman:
- Gumagawa ng Audio objects para sa iba't ibang sound effects
- Ire-reset ang
currentTimeupang payagan ang mabilisang pag-play ng sound effects - Hinahawakan ang autoplay policies ng browser sa pamamagitan ng pag-trigger ng sounds mula sa user interactions
- Pinamamahalaan ang audio volume at timing para sa mas mahusay na karanasan sa laro
💡 Learning Resource: Tuklasin ang audio sandbox upang matuto pa tungkol sa pagpapatupad ng audio sa JavaScript games.
Post-Lecture Quiz
Review & Self Study
Ang iyong assignment ay gumawa ng bagong sample na laro, kaya't mag-explore ng ilang mga kawili-wiling laro upang makita kung anong uri ng laro ang maaari mong buuin.
Assignment
Paunawa:
Ang dokumentong ito ay isinalin gamit ang AI translation service Co-op Translator. Bagamat sinisikap naming maging tumpak, mangyaring tandaan na ang mga awtomatikong pagsasalin ay maaaring maglaman ng mga pagkakamali o hindi pagkakatugma. Ang orihinal na dokumento sa kanyang katutubong wika ang dapat ituring na opisyal na sanggunian. Para sa mahalagang impormasyon, inirerekomenda ang propesyonal na pagsasalin ng tao. Hindi kami mananagot sa anumang hindi pagkakaunawaan o maling interpretasyon na dulot ng paggamit ng pagsasaling ito.