You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Web-Dev-For-Beginners/translations/hu/6-space-game/4-collision-detection
leestott c0ca49b2cc
🌐 Update translations via Co-op Translator
1 week ago
..
solution 🌐 Update translations via Co-op Translator 1 week ago
your-work 🌐 Update translations via Co-op Translator 1 week ago
README.md 🌐 Update translations via Co-op Translator 1 week ago
assignment.md 🌐 Update translations via Co-op Translator 1 week ago

README.md

Űrjáték építése 4. rész: Lézer hozzáadása és ütközések detektálása

Előadás előtti kvíz

Előadás előtti kvíz

Ebben a leckében megtanulod, hogyan lőhetsz lézereket JavaScript segítségével! Két dolgot fogunk hozzáadni a játékunkhoz:

  • Egy lézer: ez a lézer a hős űrhajójából indul, és függőlegesen felfelé halad
  • Ütközésdetektálás, a lövés képességének megvalósítása során néhány játékszabályt is hozzáadunk:
    • Lézer eltalálja az ellenséget: Az ellenség meghal, ha eltalálja egy lézer
    • Lézer eléri a képernyő tetejét: A lézer megsemmisül, ha eléri a képernyő felső részét
    • Ellenség és hős ütközése: Az ellenség és a hős megsemmisül, ha összeütköznek
    • Ellenség eléri a képernyő alját: Az ellenség és a hős megsemmisül, ha az ellenség eléri a képernyő alját

Röviden, neked -- a hősnek -- el kell találnod az összes ellenséget egy lézerrel, mielőtt azok elérnék a képernyő alját.

Nézz utána, mi volt az első számítógépes játék, amit valaha írtak. Milyen funkciói voltak?

Legyünk együtt hősök!

Ütközésdetektálás

Hogyan valósítjuk meg az ütközésdetektálást? Úgy kell gondolnunk a játéktárgyainkra, mint mozgó téglalapokra. Miért? Mert a játéktárgyak megjelenítésére használt kép egy téglalap: van x, y, szélesség és magasság értéke.

Ha két téglalap, például a hős és az ellenség metszi egymást, akkor ütközés történik. Hogy mi történjen ilyenkor, az a játék szabályaitól függ. Az ütközésdetektálás megvalósításához a következőkre van szükség:

  1. Egy módszer, amellyel egy játéktárgy téglalapként reprezentálható, például így:

    rectFromGameObject() {
      return {
        top: this.y,
        left: this.x,
        bottom: this.y + this.height,
        right: this.x + this.width
      }
    }
    
  2. Egy összehasonlító függvény, amely így nézhet ki:

    function intersectRect(r1, r2) {
      return !(r2.left > r1.right ||
        r2.right < r1.left ||
        r2.top > r1.bottom ||
        r2.bottom < r1.top);
    }
    

Hogyan semmisítünk meg dolgokat

Ahhoz, hogy valamit megsemmisítsünk a játékban, tudatnunk kell a játékkal, hogy az adott elemet többé ne rajzolja ki a játékciklus során, amely bizonyos időközönként aktiválódik. Ennek egyik módja, hogy a játéktárgyat halottnak jelöljük, amikor valami történik, például így:

// collision happened
enemy.dead = true

Ezután a halott tárgyakat kiszűrhetjük, mielőtt újrarajzolnánk a képernyőt, például így:

gameObjects = gameObject.filter(go => !go.dead);

Hogyan lőjünk lézert

A lézerlövés azt jelenti, hogy reagálunk egy billentyűeseményre, és létrehozunk egy objektumot, amely egy bizonyos irányba mozog. Ehhez a következő lépéseket kell végrehajtanunk:

  1. Lézerobjektum létrehozása: a hős űrhajójának tetejéről, amely létrehozáskor felfelé kezd mozogni a képernyő teteje felé.
  2. Kód hozzárendelése egy billentyűeseményhez: ki kell választanunk egy billentyűt a billentyűzeten, amely a lézer kilövését jelképezi.
  3. Játéktárgy létrehozása, amely lézernek néz ki, amikor a billentyűt lenyomják.

Lézer hűtési idő

A lézernek minden alkalommal tüzelnie kell, amikor megnyomsz egy billentyűt, például a szóközt. Annak érdekében, hogy a játék ne hozzon létre túl sok lézert rövid idő alatt, ezt meg kell oldanunk. A megoldás egy úgynevezett hűtési idő (cooldown) bevezetése, egy időzítő, amely biztosítja, hogy a lézer csak bizonyos időközönként lőhető ki. Ezt a következő módon valósíthatod meg:

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.
    }
  }
}

Nézd meg az űrjáték sorozat 1. leckéjét, hogy emlékeztesd magad a hűtési idő működésére.

Mit kell megépíteni

A meglévő kódot (amit az előző leckében már kitisztítottál és átalakítottál) kell kiterjesztened. Vagy kezdj a II. rész kódjával, vagy használd a III. rész kezdő kódját.

Tipp: a lézer, amivel dolgozni fogsz, már az eszközök mappádban van, és a kódod hivatkozik rá.

  • Adj hozzá ütközésdetektálást, amikor egy lézer ütközik valamivel, a következő szabályok érvényesek:
    1. Lézer eltalálja az ellenséget: az ellenség meghal, ha eltalálja egy lézer
    2. Lézer eléri a képernyő tetejét: a lézer megsemmisül, ha eléri a képernyő felső részét
    3. Ellenség és hős ütközése: az ellenség és a hős megsemmisül, ha összeütköznek
    4. Ellenség eléri a képernyő alját: az ellenség és a hős megsemmisül, ha az ellenség eléri a képernyő alját

Ajánlott lépések

Keresd meg azokat a fájlokat, amelyeket a your-work almappában hoztak létre számodra. Ezeknek a következőket kell tartalmazniuk:

-| assets
  -| enemyShip.png
  -| player.png
  -| laserRed.png
-| index.html
-| app.js
-| package.json

A projektet a your_work mappában indíthatod el az alábbi paranccsal:

cd your-work
npm start

A fenti parancs egy HTTP szervert indít a http://localhost:5000 címen. Nyiss meg egy böngészőt, és írd be ezt a címet. Jelenleg a hős és az összes ellenség megjelenik, de még semmi sem mozog. :)

Kód hozzáadása

  1. Állíts be egy téglalap reprezentációt a játéktárgyakhoz az ütközések kezelésére Az alábbi kód lehetővé teszi, hogy egy GameObject téglalapként legyen reprezentálva. Szerkeszd a GameObject osztályt, hogy kiterjeszd:

    rectFromGameObject() {
        return {
          top: this.y,
          left: this.x,
          bottom: this.y + this.height,
          right: this.x + this.width,
        };
      }
    
  2. Adj hozzá kódot, amely ellenőrzi az ütközéseket Ez egy új függvény lesz, amely teszteli, hogy két téglalap metszi-e egymást:

    function intersectRect(r1, r2) {
      return !(
        r2.left > r1.right ||
        r2.right < r1.left ||
        r2.top > r1.bottom ||
        r2.bottom < r1.top
      );
    }
    
  3. Adj hozzá lézerlövési képességet

    1. Adj hozzá billentyűesemény üzenetet. A szóköz billentyűnek egy lézert kell létrehoznia közvetlenül a hős űrhajója felett. Adj hozzá három konstansot a Messages objektumhoz:

       KEY_EVENT_SPACE: "KEY_EVENT_SPACE",
       COLLISION_ENEMY_LASER: "COLLISION_ENEMY_LASER",
       COLLISION_ENEMY_HERO: "COLLISION_ENEMY_HERO",
      
    2. Kezeld a szóköz billentyűt. Szerkeszd a window.addEventListener keyup függvényt, hogy kezelje a szóközt:

        } else if(evt.keyCode === 32) {
          eventEmitter.emit(Messages.KEY_EVENT_SPACE);
        }
      
    3. Adj hozzá eseményfigyelőket. Szerkeszd az initGame() függvényt, hogy biztosítsd, a hős lőhessen, amikor a szóköz billentyűt lenyomják:

      eventEmitter.on(Messages.KEY_EVENT_SPACE, () => {
       if (hero.canFire()) {
         hero.fire();
       }
      

      és adj hozzá egy új eventEmitter.on() függvényt, hogy biztosítsd a viselkedést, amikor egy ellenség ütközik egy lézerrel:

      eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => {
        first.dead = true;
        second.dead = true;
      })
      
    4. Mozgasd az objektumot, Biztosítsd, hogy a lézer fokozatosan a képernyő teteje felé mozogjon. Hozz létre egy új Laser osztályt, amely kiterjeszti a GameObject-et, ahogy korábban is tetted:

        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)
        }
      }
      
    5. Kezeld az ütközéseket, Valósítsd meg a lézer ütközési szabályait. Adj hozzá egy updateGameObjects() függvényt, amely teszteli az ütköző objektumokat:

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

      Győződj meg róla, hogy az updateGameObjects()-et hozzáadod a játékciklushoz a window.onload-ban.

    6. Valósítsd meg a lézer hűtési idejét, hogy csak bizonyos időközönként lehessen lőni.

      Végül szerkeszd a Hero osztályt, hogy támogassa a hűtési időt:

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

Ezen a ponton a játékod már némi funkcionalitással rendelkezik! A nyílbillentyűkkel navigálhatsz, a szóköz billentyűvel lézert lőhetsz, és az ellenségek eltűnnek, amikor eltalálod őket. Szép munka!


🚀 Kihívás

Adj hozzá egy robbanást! Nézd meg a játékeszközöket a Space Art repóban, és próbálj meg robbanást hozzáadni, amikor a lézer eltalál egy idegent.

Előadás utáni kvíz

Előadás utáni kvíz

Áttekintés és önálló tanulás

Kísérletezz a játékod időközeivel. Mi történik, ha megváltoztatod őket? Olvass többet a JavaScript időzítési eseményekről.

Feladat

Fedezd fel az ütközéseket


Felelősség kizárása:
Ez a dokumentum az AI fordítási szolgáltatás Co-op Translator segítségével lett lefordítva. Bár törekszünk a pontosságra, kérjük, vegye figyelembe, hogy az automatikus fordítások hibákat vagy pontatlanságokat tartalmazhatnak. Az eredeti dokumentum az eredeti nyelvén tekintendő hiteles forrásnak. Kritikus információk esetén javasolt professzionális emberi fordítást igénybe venni. Nem vállalunk felelősséget semmilyen félreértésért vagy téves értelmezésért, amely a fordítás használatából eredhet.