# एक अंतरिक्ष खेल भाग 4 बनाएँ: एक लेजर और टकराव का पता लगाए

## लेक्चरसे पहलेकी क्विज

[लेक्चरसे पहलेकी क्विज](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/35?loc=hi)

इस पाठ में आप सीखेंगे कि जावास्क्रिप्ट के साथ लेज़रों को कैसे शूट किया जाए! हम अपने खेल में दो चीजें जोड़ेंगे:

- **A laser**: इस लेज़र को आपके नायकों के जहाज से और ऊपर की ओर सीधा खड़ा किया गया है
- **Collision detection**, _शूट_ करने की क्षमता को लागू करने के हिस्से के रूप में हम कुछ अच्छे गेम नियम भी जोड़ेंगे:
  - **Laser hits enemy**: लेजर से मारने पर दुश्मन की मौत हो जाती है
  - **Laser hits top screen**: एक लेजर यदि स्क्रीन के शीर्ष भाग से टकराने के नष्ट हो जाता है
  - **Enemy and hero collision**:एक दुश्मन और नायक नष्ट होजाता है अगर एक दूसरे को मारते हैं
  - **Enemy hits bottom of the screen**: एक दुश्मन और एक नायक को नष्ट कर दिया जाता है अगर दुश्मन स्क्रीन के नीचे हिट करता है

संक्षेप में, आप - _ नायक _ - इससे पहले कि वे स्क्रीन के निचले भाग में जाने का प्रबंधन करें, सभी दुश्मनों को एक लेजर के साथ हिट करने की आवश्यकता है.

✅ कभी लिखे गए पहले कंप्यूटर गेम पर थोड़ा शोध करें। इसकी कार्यक्षमता क्या थी?

चलो एक साथ वीर बने !

## टक्कर की पहचान

हम टकराव का पता कैसे लगाते हैं? हमें अपने खेल की वस्तुओं के बारे में सोचने की जरूरत है क्योंकि आयतें चलती हैं. आप ऐसा क्यों पूछ सकते हैं? खैर, किसी गेम ऑब्जेक्ट को खींचने के लिए उपयोग की जाने वाली छवि एक आयत है: इसमें एक `x`,` y`, `चौड़ाई` और `ऊँचाई` है।.

यदि दो आयतें, अर्थात् एक नायक और शत्रु प्रतिच्छेद करते हैं, तो आपकी टक्कर होती है.
तब क्या होना चाहिए यह खेल के नियमों पर निर्भर है. टक्कर का पता लगाने को लागू करने के लिए आपको निम्न की आवश्यकता है:

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 के कोड से शुरू करें या [Part III-Starter](/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` का आयत प्रतिनिधित्व प्राप्त कर सकते हैं। इसे बढ़ाने के लिए अपने गेमऑब्जेक्ट क्लास को संपादित करें:

   ```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. **की-ईवेंट संदेश जोड़ें**. _ स्पेस _ की को हीरो शिप के ठीक ऊपर एक लेजर बनाना चाहिए। संदेश ऑब्जेक्ट में तीन स्थिरांक जोड़ें:

      ```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. **बस्तु चाल**, धीरे-धीरे स्क्रीन के शीर्ष पर लेजर चाल सुनिश्चित करें। आप एक नया लेजर वर्ग बनाएंगे जो `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);
      }
      ```

      `Window.onload` में अपने गेम लूप में`updateGameObjects()`जोड़ना सुनिश्चित करें.

   1. लेजर पर **कुलदावन लागू** करें, इसलिए यह बार बार थोक सकता है.

      अंत में, हीरो वर्ग को संपादित करें ताकि यह कुलडाउन हो सके:

      ```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;
        }
      }
      ```

इस बिंदु पर, आपके गेम में कुछ कार्यक्षमता है! आप अपने तीर की के साथ नेविगेट कर सकते हैं, अपने स्पेस बार के साथ एक लेजर फायर कर सकते हैं, और जब आप उन्हें मारते हैं तो दुश्मन गायब हो जाते हैं। बहुत बढ़िया!

---

## 🚀 चुनौती

एक विस्फोट जोड़ें! [स्पेस आर्ट रेपो](../solution/spaceArt/readme.txt) में खेल की परिसंपत्तियों पर एक नज़र डालें और जब कोई एलियन टकराता है तो विस्फोट को जोड़ने का प्रयास करें

## पोस्ट-व्याख्यान प्रश्नोत्तरी

[पोस्ट-व्याख्यान प्रश्नोत्तरी](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/36?loc=hi)

## समीक्षा और स्व अध्ययन

इस प्रकार अपने खेल में अंतराल के साथ प्रयोग करें. जब आप उन्हें बदलते हैं तो क्या होता है? [जावास्क्रिप्ट समय घटनाओं](https://www.freecodecamp.org/news/javascript-timing-events-settimeout-and-setinterval/) के बारे में और पढ़ें.

## असाइनमेंट

[टक्करों का अन्वेषण करें](assignment.hi.md)
