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/6-space-game/4-collision-detection/translations/README.ms.md

11 KiB

Bina Permainan Angkasa Bahagian 4: Menambah Laser dan Mengesan Perlanggaran

Kuiz Pra Kuliah

Kuiz Pra Kuliah

Dalam pelajaran ini, anda akan belajar bagaimana menembak laser dengan JavaScript! Kami akan menambah dua perkara pada permainan kami:

  • Laser: laser ini ditembak dari kapal wira anda dan menegak ke atas
  • Pengesanan perlanggaran, sebagai bagian dari menerapkan kemampuan untuk menembak kami juga akan menambahkan beberapa peraturan permainan yang bagus:
    • Laser menyerang musuh: Musuh mati jika terkena laser
    • Laser mencecah skrin atas: Laser hancur jika memukul bahagian atas skrin
    • Pertempuran musuh dan pahlawan: Musuh dan pahlawan musnah jika saling memukul
    • Musuh memukul bahagian bawah layar: Musuh dan pahlawan hancur jika musuh memukul bahagian bawah layar

Pendek kata, anda - pahlawan - perlu memukul semua musuh dengan laser sebelum mereka berjaya bergerak ke bahagian bawah skrin.

Lakukan sedikit kajian mengenai permainan komputer pertama yang pernah ditulis. Apa fungsinya?

Mari sama-sama menjadi wira!

Pengesanan perlanggaran

Bagaimanakah kita melakukan pengesanan perlanggaran? Kita perlu memikirkan objek permainan kita sebagai segi empat tepat bergerak. Mengapa anda bertanya? Nah, gambar yang digunakan untuk menggambar objek permainan adalah persegi panjang: ia memiliki x, y, width dan height.

Sekiranya dua segi empat tepat, iaitu pahlawan dan musuh berpotongan, anda akan bertembung. Apa yang harus berlaku adalah mengikut peraturan permainan. Oleh itu, untuk melaksanakan pengesanan perlanggaran anda memerlukan perkara berikut:

  1. Cara untuk mendapatkan representasi segi empat tepat dari objek permainan, seperti ini:

    rectFromGameObject() {
      return {
        top: this.y,
        left: this.x,
        bottom: this.y + this.height,
        right: this.x + this.width
      }
    }
    
  2. Fungsi perbandingan, fungsi ini boleh kelihatan seperti ini:

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

Bagaimanakah kita memusnahkan perkara

Untuk menghancurkan sesuatu dalam permainan, anda perlu memberitahu permainan bahawa permainan ini tidak lagi harus melukis item ini dalam gelung permainan yang mencetuskan pada selang waktu tertentu. Cara untuk melakukannya adalah dengan menandakan objek permainan sebagai mati apabila sesuatu berlaku, seperti:

// collision happened
enemy.dead = true

Kemudian anda meneruskan untuk menyusun mati objek sebelum mengecat semula skrin, seperti:

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

Bagaimanakah kita menghidupkan laser

Menyalakan laser diterjemahkan untuk bertindak balas terhadap peristiwa penting dan membuat objek yang bergerak ke arah tertentu. Oleh itu, kita perlu melakukan langkah-langkah berikut:

  1. Buat objek laser: dari bahagian atas kapal pahlawan kita, bahawa setelah penciptaan mula bergerak ke atas menuju bahagian atas layar.
  2. Lampirkan kod ke acara utama: kita perlu memilih kunci pada papan kekunci yang mewakili pemain yang menembak laser.
  3. Buat objek permainan yang kelihatan seperti laser apabila kekunci ditekan.

Cooldown menggunakan laser kami

Laser perlu menyala setiap kali anda menekan kekunci, seperti ruang misalnya. Untuk mengelakkan permainan menghasilkan terlalu banyak laser dalam masa yang singkat, kita perlu memperbaikinya. Penyelesaiannya adalah dengan menerapkan cooldown, pemasa, yang memastikan bahawa laser hanya dapat dipecat begitu kerap. Anda boleh melaksanakannya dengan cara berikut:

class Cooldown {
  constructor(time) {
    this.cool = false;
    setTimeout(() => {
      this.cool = true;
    }, time)
  }
}

class Weapon {
  constructor {
  }
  fire() {
    if (!this.cooldown || this.cooldown.cool) {
      // menghasilkan laser
      this.cooldown = new Cooldown(500);
    } else {
      // buat apa-apa - ia belum cooldown.
    }
  }
}

Rujuk pelajaran 1 dalam siri permainan ruang untuk mengingatkan diri anda mengenai cooldowns.

Apakah yang hendak dibina

Anda akan mengambil kod yang ada (yang seharusnya anda bersihkan dan refactored) dari pelajaran sebelumnya, dan memperpanjangnya. Mulakan dengan kod dari bahagian II atau gunakan kod di Bahagian III-starter

tip: laser yang akan anda gunakan sudah ada di folder aset anda dan dirujuk oleh kod anda

  • Tambahkan pengesanan perlanggaran, apabila laser bertabrakan dengan sesuatu peraturan berikut harus berlaku:
    1. Laser memukul musuh: musuh mati jika terkena laser
    2. Laser mencecah skrin atas: Laser hancur jika menyentuh bahagian atas skrin kita
    3. Pertembungan musuh dan pahlawan: musuh dan pahlawan musnah jika saling memukul
    4. Musuh memukul bahagian bawah skrin: Musuh dan pahlawan hancur jika musuh memukul bahagian bawah skrin

Langkah-langkah yang disyorkan

Cari fail yang telah dibuat untuk anda dalam sub folder your-work. Ia harus mengandungi yang berikut:

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

Anda memulakan projek anda folder your_work dengan mengetik:

cd your-work
npm start

Perkara di atas akan memulakan Pelayan HTTP pada alamat http: // localhost: 5000. Buka penyemak imbas dan masukkan alamatnya, sekarang ia harus menjadikan pahlawan dan semua musuh, tidak ada yang bergerak - namun :).

Tambah kod

  1. Siapkan representasi segi empat tepat dari objek permainan anda, untuk menangani perlanggaran Kod di bawah ini membolehkan anda mendapatkan representasi segi empat tepat dari GameObject. Edit kelas GameObject anda untuk memperluasnya:

    rectFromGameObject() {
        return {
          top: this.y,
          left: this.x,
          bottom: this.y + this.height,
          right: this.x + this.width,
        };
      }
    
  2. Tambahkan kod yang memeriksa perlanggaran Ini akan menjadi fungsi baru yang menguji sama ada dua segi empat tepat bersilang:

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

    1. Tambah mesej peristiwa penting. Kekunci ruang harus membuat laser tepat di atas kapal wira. Tambahkan tiga pemalar dalam objek Mesej:

       KEY_EVENT_SPACE: "KEY_EVENT_SPACE",
       COLLISION_ENEMY_LASER: "COLLISION_ENEMY_LASER",
       COLLISION_ENEMY_HERO: "COLLISION_ENEMY_HERO",
      
      1. Kendalikan kekunci ruang. Edit fungsi kekunci window.addEventListener untuk menangani ruang:
      } else if(evt.keyCode === 32) {
        eventEmitter.emit(Messages.KEY_EVENT_SPACE);
      }
      
      1. Tambah pendengar. Edit fungsi initGame () untuk memastikan bahawa pahlawan dapat melepaskan tembakan ketika spasi terkena:

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

      and add a new eventEmitter.on() function to ensure behavior when an enemy collides with a laser:

      ```javascript
      eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => {
        first.dead = true;
        second.dead = true;
      })
      ```
      
      1. Pindahkan objek, Pastikan laser bergerak ke bahagian atas skrin secara beransur-ansur. Anda akan membuat kelas Laser baru yang meluaskan GameObject, seperti yang telah anda lakukan sebelumnya:

        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)
         }
        }
        
      2. ** Tangani perlanggaran **, Terapkan peraturan perlanggaran untuk laser. Tambahkan fungsi updateGameObjects () yang menguji objek bertembung untuk hits

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

      Pastikan untuk menambah updateGameObjects () ke gelung permainan anda di window.onload.

    2. ** Terapkan cooldown ** pada laser, sehingga hanya dapat dipecat begitu kerap.

    Akhir sekali, edit kelas Wira sehingga dapat dikembalikan:

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

Pada ketika ini, permainan anda mempunyai beberapa fungsi! Anda boleh menavigasi dengan kekunci anak panah anda, menembak laser dengan bar ruang anda, dan musuh hilang ketika anda memukulnya. Bagus!


🚀 Cabaran

Tambah letupan! Lihat aset permainan di Space Art repo dan cuba tambahkan letupan ketika laser memukul makhluk asing

Kuiz Pasca Kuliah

Kuiz Pasca Kuliah

Mengkaji & Belajar Sendiri

Percubaan dengan selang permainan anda setakat ini. Apa yang berlaku apabila anda menukarnya? Baca lebih lanjut mengenai acara pemasaan JavaScript.

Tugasan

Menerokai Perlanggaran