# स्पेस गेम बनाएं भाग 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) का उपयोग करके अनुवादित किया गया है। जबकि हम सटीकता सुनिश्चित करने का प्रयास करते हैं, कृपया ध्यान दें कि स्वचालित अनुवाद में त्रुटियां या अशुद्धियां हो सकती हैं। मूल भाषा में उपलब्ध मूल दस्तावेज़ को प्रामाणिक स्रोत माना जाना चाहिए। महत्वपूर्ण जानकारी के लिए, पेशेवर मानव अनुवाद की सिफारिश की जाती है। इस अनुवाद के उपयोग से उत्पन्न किसी भी गलतफहमी या गलत व्याख्या के लिए हम जिम्मेदार नहीं हैं।