# स्पेस गेम बनाएं भाग 4: लेज़र जोड़ें और टकराव का पता लगाएं ## प्री-लेक्चर क्विज़ [प्री-लेक्चर क्विज़](https://ff-quizzes.netlify.app/web/quiz/35) इस पाठ में आप सीखेंगे कि जावास्क्रिप्ट के साथ लेज़र कैसे शूट करें! हम अपने गेम में दो चीजें जोड़ेंगे: - **एक लेज़र**: यह लेज़र आपके हीरो के जहाज से ऊपर की ओर शूट होता है। - **टकराव का पता लगाना**, शूटिंग की क्षमता को लागू करने के हिस्से के रूप में हम कुछ अच्छे गेम नियम भी जोड़ेंगे: - **लेज़र दुश्मन को हिट करता है**: लेज़र से हिट होने पर दुश्मन मर जाता है। - **लेज़र स्क्रीन के शीर्ष को हिट करता है**: स्क्रीन के शीर्ष भाग को हिट करने पर लेज़र नष्ट हो जाता है। - **दुश्मन और हीरो का टकराव**: यदि दुश्मन और हीरो एक-दूसरे से टकराते हैं तो दोनों नष्ट हो जाते हैं। - **दुश्मन स्क्रीन के नीचे पहुंचता है**: यदि दुश्मन स्क्रीन के नीचे पहुंचता है तो दुश्मन और हीरो दोनों नष्ट हो जाते हैं। संक्षेप में, आप -- *हीरो* -- को सभी दुश्मनों को लेज़र से हिट करना होगा इससे पहले कि वे स्क्रीन के नीचे पहुंच जाएं। ✅ सबसे पहले लिखे गए कंप्यूटर गेम के बारे में थोड़ा शोध करें। इसकी कार्यक्षमता क्या थी? आइए साथ मिलकर हीरो बनें! ## टकराव का पता लगाना हम टकराव का पता कैसे लगाते हैं? हमें अपने गेम ऑब्जेक्ट्स को आयतों के रूप में सोचना होगा जो इधर-उधर घूमते हैं। आप पूछ सकते हैं कि ऐसा क्यों? खैर, गेम ऑब्जेक्ट को ड्रॉ करने के लिए उपयोग की गई छवि एक आयत है: इसमें `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. } } } ``` ✅ स्पेस गेम श्रृंखला के पाठ 1 को देखें ताकि *कूलडाउन* के बारे में याद दिलाया जा सके। ## क्या बनाना है आप पिछले पाठ से मौजूदा कोड (जिसे आपने साफ और पुनर्गठित किया होना चाहिए) लेंगे और इसे बढ़ाएंगे। या तो भाग 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 सर्वर को `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` के keyup फ़ंक्शन को स्पेस को संभालने के लिए संपादित करें: ```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; } } ``` इस बिंदु पर, आपके गेम में कुछ कार्यक्षमता है! आप अपने एरो कीज़ के साथ नेविगेट कर सकते हैं, अपने स्पेस बार के साथ लेज़र फायर कर सकते हैं, और जब आप दुश्मनों को हिट करते हैं तो वे गायब हो जाते हैं। बहुत अच्छा! --- ## 🚀 चुनौती एक विस्फोट जोड़ें! [स्पेस आर्ट रिपो](../../../../6-space-game/solution/spaceArt/readme.txt) में गेम एसेट्स पर एक नज़र डालें और जब लेज़र एलियन को हिट करे तो विस्फोट जोड़ने का प्रयास करें। ## पोस्ट-लेक्चर क्विज़ [पोस्ट-लेक्चर क्विज़](https://ff-quizzes.netlify.app/web/quiz/36) ## समीक्षा और स्व-अध्ययन अब तक आपके गेम में अंतराल के साथ प्रयोग करें। जब आप उन्हें बदलते हैं तो क्या होता है? [जावास्क्रिप्ट टाइमिंग इवेंट्स](https://www.freecodecamp.org/news/javascript-timing-events-settimeout-and-setinterval/) के बारे में अधिक पढ़ें। ## असाइनमेंट [टकराव का अन्वेषण करें](assignment.md) **अस्वीकरण**: यह दस्तावेज़ AI अनुवाद सेवा [Co-op Translator](https://github.com/Azure/co-op-translator) का उपयोग करके अनुवादित किया गया है। जबकि हम सटीकता के लिए प्रयासरत हैं, कृपया ध्यान दें कि स्वचालित अनुवाद में त्रुटियां या अशुद्धियां हो सकती हैं। मूल भाषा में उपलब्ध मूल दस्तावेज़ को प्रामाणिक स्रोत माना जाना चाहिए। महत्वपूर्ण जानकारी के लिए, पेशेवर मानव अनुवाद की सिफारिश की जाती है। इस अनुवाद के उपयोग से उत्पन्न किसी भी गलतफहमी या गलत व्याख्या के लिए हम उत्तरदायी नहीं हैं।