# स्पेस गेम बनाउनुहोस् भाग ४: लेजर थप्नुहोस् र टक्कर पत्ता लगाउनुहोस् ## प्रि-लेक्चर क्विज [प्रि-लेक्चर क्विज](https://ff-quizzes.netlify.app/web/quiz/35) यस पाठमा तपाईंले JavaScript प्रयोग गरेर लेजर कसरी प्रहार गर्ने सिक्नुहुनेछ! हामी हाम्रो खेलमा दुई कुरा थप्नेछौं: - **लेजर**: यो लेजर तपाईंको नायकको जहाजबाट माथि तिर प्रहार गरिन्छ। - **टक्कर पत्ता लगाउने प्रणाली**, *प्रहार गर्ने* क्षमता कार्यान्वयनको भागको रूपमा, हामी केही राम्रो खेल नियमहरू पनि थप्नेछौं: - **लेजरले शत्रुलाई प्रहार गर्छ**: लेजरले प्रहार गर्दा शत्रु मर्छ। - **लेजरले स्क्रिनको माथिल्लो भागलाई प्रहार गर्छ**: स्क्रिनको माथिल्लो भागमा प्रहार गर्दा लेजर नष्ट हुन्छ। - **शत्रु र नायकको टक्कर**: शत्रु र नायक एकअर्कालाई प्रहार गर्दा नष्ट हुन्छन्। - **शत्रुले स्क्रिनको तल्लो भागलाई प्रहार गर्छ**: शत्रु र नायक नष्ट हुन्छन् यदि शत्रुले स्क्रिनको तल्लो भागलाई प्रहार गर्छ। सारांशमा, तपाईं -- *नायक* -- लेजरको प्रयोग गरेर सबै शत्रुहरूलाई प्रहार गर्नुपर्छ, उनीहरूले स्क्रिनको तल्लो भागमा पुग्नुअघि। ✅ पहिलो कम्प्युटर खेल कहिले लेखिएको थियो भनेर थोरै अनुसन्धान गर्नुहोस्। यसको कार्यक्षमता के थियो? आउनुहोस्, नायक बनौं! ## टक्कर पत्ता लगाउने प्रणाली टक्कर पत्ता लगाउने प्रणाली कसरी गर्ने? हामीले हाम्रो खेलका वस्तुहरूलाई आयतको रूपमा सोच्नुपर्छ। किनभने खेल वस्तुहरूलाई चित्रण गर्न प्रयोग गरिएको छवि आयत हो: यसमा `x`, `y`, `width` र `height` हुन्छ। यदि दुई आयतहरू, जस्तै नायक र शत्रु *अन्तरसेक्ट* गर्छन् भने, टक्कर हुन्छ। त्यसपछि के हुनुपर्छ भन्ने कुरा खेलका नियमहरूमा निर्भर गर्दछ। टक्कर पत्ता लगाउने प्रणाली कार्यान्वयन गर्न तपाईंलाई निम्न कुराहरू आवश्यक छ: 1. खेल वस्तुको आयत प्रतिनिधित्व प्राप्त गर्ने तरिका, यस्तो देखिन्छ: ```javascript rectFromGameObject() { return { top: this.y, left: this.x, bottom: this.y + this.height, right: this.x + this.width } } ``` 2. तुलना गर्ने कार्य, यो कार्य यस्तो देखिन सक्छ: ```javascript function intersectRect(r1, r2) { return !(r2.left > r1.right || r2.right < r1.left || r2.top > r1.bottom || r2.bottom < r1.top); } ``` ## वस्तुहरू कसरी नष्ट गर्ने खेलमा वस्तुहरू नष्ट गर्न तपाईंले खेललाई यो वस्तु अब खेल लूपमा चित्रण गर्न नपर्ने भनेर जानकारी दिनुपर्छ। यसको एउटा तरिका भनेको कुनै घटना हुँदा खेल वस्तुलाई *मृत* भनेर चिन्ह लगाउनु हो, यस्तो देखिन्छ: ```javascript // collision happened enemy.dead = true ``` त्यसपछि तपाईं *मृत* वस्तुहरूलाई स्क्रिन पुनःचित्रण गर्नु अघि छुट्याउन सक्नुहुन्छ, यस्तो देखिन्छ: ```javascript gameObjects = gameObject.filter(go => !go.dead); ``` ## लेजर कसरी प्रहार गर्ने लेजर प्रहार गर्नु भनेको कुञ्जी-घटनामा प्रतिक्रिया दिनु र एउटा वस्तु सिर्जना गर्नु हो जुन निश्चित दिशामा सर्छ। त्यसैले हामीले निम्न चरणहरू पूरा गर्नुपर्छ: 1. **लेजर वस्तु सिर्जना गर्नुहोस्**: नायकको जहाजको माथिबाट, जसले सिर्जना भएलगत्तै स्क्रिनको माथि तिर सर्न थाल्छ। 2. **कुञ्जी घटनामा कोड जोड्नुहोस्**: खेलाडीले लेजर प्रहार गरेको प्रतिनिधित्व गर्ने कुञ्जी चयन गर्नुपर्छ। 3. **लेजर जस्तो देखिने खेल वस्तु सिर्जना गर्नुहोस्** जब कुञ्जी थिचिन्छ। ## लेजरमा कूलडाउन लेजरले तपाईंले कुञ्जी थिच्दा प्रहार गर्नुपर्छ, जस्तै *स्पेस*। खेलले धेरै छोटो समयमा धेरै लेजर उत्पादन नगरोस् भनेर हामीले यसलाई ठीक गर्नुपर्छ। समाधान भनेको *कूलडाउन*, टाइमर कार्यान्वयन गरेर हो, जसले सुनिश्चित गर्दछ कि लेजर निश्चित समयको अन्तरालमा मात्र प्रहार गर्न सकिन्छ। तपाईं यसलाई निम्न तरिकामा कार्यान्वयन गर्न सक्नुहुन्छ: ```javascript class Cooldown { constructor(time) { this.cool = false; setTimeout(() => { this.cool = true; }, time) } } class Weapon { constructor { } fire() { if (!this.cooldown || this.cooldown.cool) { // produce a laser this.cooldown = new Cooldown(500); } else { // do nothing - it hasn't cooled down yet. } } } ``` ✅ स्पेस गेम श्रृंखलाको पाठ १ मा फर्केर *कूलडाउन*को बारेमा सम्झनुहोस्। ## के निर्माण गर्ने तपाईंले अघिल्लो पाठबाट रहेको कोड (जसलाई तपाईंले सफा र पुनःसंरचना गर्नुपर्छ) लिनेछ र यसलाई विस्तार गर्नेछ। भाग II को कोडबाट सुरु गर्नुहोस् वा [भाग III- स्टार्टर](../../../../../../../../../your-work) मा रहेको कोड प्रयोग गर्नुहोस्। > टिप: लेजर, जससँग तपाईं काम गर्नुहुनेछ, पहिले नै तपाईंको एसेट्स फोल्डरमा छ र तपाईंको कोडले सन्दर्भ गरेको छ। - **टक्कर पत्ता लगाउने प्रणाली थप्नुहोस्**, जब लेजरले केही वस्तुमा टक्कर गर्छ, निम्न नियमहरू लागू हुनुपर्छ: 1. **लेजरले शत्रुलाई प्रहार गर्छ**: लेजरले प्रहार गर्दा शत्रु मर्छ। 2. **लेजरले स्क्रिनको माथिल्लो भागलाई प्रहार गर्छ**: लेजर स्क्रिनको माथिल्लो भागमा प्रहार गर्दा नष्ट हुन्छ। 3. **शत्रु र नायकको टक्कर**: शत्रु र नायक एकअर्कालाई प्रहार गर्दा नष्ट हुन्छन्। 4. **शत्रुले स्क्रिनको तल्लो भागलाई प्रहार गर्छ**: शत्रु र नायक नष्ट हुन्छन् यदि शत्रुले स्क्रिनको तल्लो भागलाई प्रहार गर्छ। ## सिफारिस गरिएका चरणहरू `your-work` उप फोल्डरमा सिर्जना गरिएका फाइलहरू पत्ता लगाउनुहोस्। यसले निम्न समावेश गर्नुपर्छ: ```bash -| assets -| enemyShip.png -| player.png -| laserRed.png -| index.html -| app.js -| package.json ``` तपाईं आफ्नो परियोजना `your_work` फोल्डरबाट सुरु गर्नुहोस्: ```bash cd your-work npm start ``` माथिको कमाण्डले HTTP Server `http://localhost:5000` ठेगानामा सुरु गर्नेछ। ब्राउजर खोल्नुहोस् र उक्त ठेगाना इनपुट गर्नुहोस्, अहिले यो नायक र सबै शत्रुहरूलाई देखाउनेछ, केही चलिरहेको छैन - अझै :). ### कोड थप्नुहोस् 1. **आयत प्रतिनिधित्व सेटअप गर्नुहोस्, टक्कर पत्ता लगाउन** तलको कोडले `GameObject` को आयत प्रतिनिधित्व प्राप्त गर्न अनुमति दिन्छ। आफ्नो GameObject क्लासलाई यसलाई विस्तार गर्न सम्पादन गर्नुहोस्: ```javascript rectFromGameObject() { return { top: this.y, left: this.x, bottom: this.y + this.height, right: this.x + this.width, }; } ``` 2. **टक्कर पत्ता लगाउने कोड थप्नुहोस्** यो नयाँ कार्य हुनेछ जसले दुई आयतहरू अन्तरसेक्ट भएको परीक्षण गर्छ: ```javascript function intersectRect(r1, r2) { return !( r2.left > r1.right || r2.right < r1.left || r2.top > r1.bottom || r2.bottom < r1.top ); } ``` 3. **लेजर प्रहार गर्ने क्षमता थप्नुहोस्** 1. **कुञ्जी-घटना सन्देश थप्नुहोस्**। *स्पेस* कुञ्जीले नायकको जहाजको माथि लेजर सिर्जना गर्नुपर्छ। Messages वस्तुमा तीन स्थिरांकहरू थप्नुहोस्: ```javascript KEY_EVENT_SPACE: "KEY_EVENT_SPACE", COLLISION_ENEMY_LASER: "COLLISION_ENEMY_LASER", COLLISION_ENEMY_HERO: "COLLISION_ENEMY_HERO", ``` 1. **स्पेस कुञ्जी ह्यान्डल गर्नुहोस्**। `window.addEventListener` कुञ्जीअप कार्यलाई स्पेस ह्यान्डल गर्न सम्पादन गर्नुहोस्: ```javascript } else if(evt.keyCode === 32) { eventEmitter.emit(Messages.KEY_EVENT_SPACE); } ``` 1. **सुनुवाइकर्ता थप्नुहोस्**। `initGame()` कार्यलाई सम्पादन गर्नुहोस् ताकि नायकले स्पेस बार थिच्दा प्रहार गर्न सकून्: ```javascript eventEmitter.on(Messages.KEY_EVENT_SPACE, () => { if (hero.canFire()) { hero.fire(); } ``` र नयाँ `eventEmitter.on()` कार्य थप्नुहोस् ताकि शत्रु लेजरसँग टक्कर गर्दा व्यवहार सुनिश्चित होस्: ```javascript eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => { first.dead = true; second.dead = true; }) ``` 1. **वस्तु सर्नुहोस्**, लेजर स्क्रिनको माथि क्रमिक रूपमा सर्न सुनिश्चित गर्नुहोस्। तपाईंले नयाँ Laser क्लास सिर्जना गर्नुहुनेछ जसले `GameObject` लाई विस्तार गर्छ, जस्तै तपाईंले पहिले गरेका थियौं: ```javascript class Laser extends GameObject { constructor(x, y) { super(x,y); (this.width = 9), (this.height = 33); this.type = 'Laser'; this.img = laserImg; let id = setInterval(() => { if (this.y > 0) { this.y -= 15; } else { this.dead = true; clearInterval(id); } }, 100) } } ``` 1. **टक्कर ह्यान्डल गर्नुहोस्**, लेजरको लागि टक्कर नियम कार्यान्वयन गर्नुहोस्। टक्कर भएका वस्तुहरूलाई हिटको लागि परीक्षण गर्ने `updateGameObjects()` कार्य थप्नुहोस्: ```javascript function updateGameObjects() { const enemies = gameObjects.filter(go => go.type === 'Enemy'); const lasers = gameObjects.filter((go) => go.type === "Laser"); // laser hit something lasers.forEach((l) => { enemies.forEach((m) => { if (intersectRect(l.rectFromGameObject(), m.rectFromGameObject())) { eventEmitter.emit(Messages.COLLISION_ENEMY_LASER, { first: l, second: m, }); } }); }); gameObjects = gameObjects.filter(go => !go.dead); } ``` सुनिश्चित गर्नुहोस् कि `updateGameObjects()` लाई `window.onload` मा आफ्नो खेल लूपमा थपिएको छ। 4. **लेजरमा कूलडाउन कार्यान्वयन गर्नुहोस्**, ताकि यो निश्चित समयको अन्तरालमा मात्र प्रहार गर्न सकून्। अन्ततः, Hero क्लासलाई सम्पादन गर्नुहोस् ताकि यसले कूलडाउन गर्न सकून्: ```javascript class Hero extends GameObject { constructor(x, y) { super(x, y); (this.width = 99), (this.height = 75); this.type = "Hero"; this.speed = { x: 0, y: 0 }; this.cooldown = 0; } fire() { gameObjects.push(new Laser(this.x + 45, this.y - 10)); this.cooldown = 500; let id = setInterval(() => { if (this.cooldown > 0) { this.cooldown -= 100; } else { clearInterval(id); } }, 200); } canFire() { return this.cooldown === 0; } } ``` यस बिन्दुमा, तपाईंको खेलमा केही कार्यक्षमता छ! तपाईंले आफ्नो एरो कुञ्जीहरू प्रयोग गरेर नेभिगेट गर्न सक्नुहुन्छ, स्पेस बारले लेजर प्रहार गर्न सक्नुहुन्छ, र शत्रुहरू लेजरले प्रहार गर्दा हराउँछन्। राम्रो काम! ## GitHub Copilot Agent चुनौती 🚀 Agent मोड प्रयोग गरेर निम्न चुनौती पूरा गर्नुहोस्: **विवरण:** टक्कर पत्ता लगाउने प्रणालीलाई सुधार गरेर पावर-अप्स कार्यान्वयन गर्नुहोस्, जुन अनियमित रूपमा उत्पन्न हुन्छन् र नायकको जहाजले संकलन गर्दा अस्थायी क्षमता प्रदान गर्छन्। **प्रेरणा:** PowerUp क्लास सिर्जना गर्नुहोस् जसले GameObject लाई विस्तार गर्छ र नायक र पावर-अप्स बीच टक्कर पत्ता लगाउने प्रणाली कार्यान्वयन गर्नुहोस्। कम्तिमा दुई प्रकारका पावर-अप्स थप्नुहोस्: एउटा जसले फायर दर बढाउँछ (कूलडाउन घटाउँछ) र अर्को जसले अस्थायी शील्ड सिर्जना गर्छ। अनियमित अन्तराल र स्थानहरूमा पावर-अप्स सिर्जना गर्ने स्पन तर्क समावेश गर्नुहोस्। --- ## 🚀 चुनौती विस्फोट थप्नुहोस्! [Space Art repo](../../../../6-space-game/solution/spaceArt/readme.txt) मा खेल एसेट्स हेर्नुहोस् र लेजरले एलियनलाई प्रहार गर्दा विस्फोट थप्ने प्रयास गर्नुहोस्। ## पोस्ट-लेक्चर क्विज [पोस्ट-लेक्चर क्विज](https://ff-quizzes.netlify.app/web/quiz/36) ## समीक्षा र आत्म-अध्ययन अहिलेसम्मको खेलमा अन्तरालहरू प्रयोग गरेर प्रयोग गर्नुहोस्। तपाईंले तिनीहरूलाई परिवर्तन गर्दा के हुन्छ? [JavaScript timing events](https://www.freecodecamp.org/news/javascript-timing-events-settimeout-and-setinterval/) को बारेमा थप पढ्नुहोस्। ## असाइनमेन्ट [टक्करहरूको अन्वेषण गर्नुहोस्](assignment.md) --- **अस्वीकरण**: यो दस्तावेज AI अनुवाद सेवा [Co-op Translator](https://github.com/Azure/co-op-translator) प्रयोग गरेर अनुवाद गरिएको छ। हामी शुद्धताको लागि प्रयास गर्छौं, तर कृपया ध्यान दिनुहोस् कि स्वचालित अनुवादमा त्रुटिहरू वा अशुद्धताहरू हुन सक्छ। यसको मूल भाषा मा रहेको दस्तावेजलाई आधिकारिक स्रोत मानिनुपर्छ। महत्वपूर्ण जानकारीको लागि, व्यावसायिक मानव अनुवाद सिफारिस गरिन्छ। यस अनुवादको प्रयोगबाट उत्पन्न हुने कुनै पनि गलतफहमी वा गलत व्याख्याको लागि हामी जिम्मेवार हुनेछैनौं।