11 KiB
Bina Permainan Angkasa Bahagian 4: Menambah Laser dan Mengesan Perlanggaran
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:
-
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 } }
-
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:
- Buat objek laser: dari bahagian atas kapal pahlawan kita, bahawa setelah penciptaan mula bergerak ke atas menuju bahagian atas layar.
- Lampirkan kod ke acara utama: kita perlu memilih kunci pada papan kekunci yang mewakili pemain yang menembak laser.
- 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:
- Laser memukul musuh: musuh mati jika terkena laser
- Laser mencecah skrin atas: Laser hancur jika menyentuh bahagian atas skrin kita
- Pertembungan musuh dan pahlawan: musuh dan pahlawan musnah jika saling memukul
- 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
-
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, }; }
-
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 ); }
-
Tambahkan keupayaan menembak laser
-
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",
- Kendalikan kekunci ruang. Edit fungsi kekunci
window.addEventListener
untuk menangani ruang:
} else if(evt.keyCode === 32) { eventEmitter.emit(Messages.KEY_EVENT_SPACE); }
-
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; }) ```
-
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) } }
-
** 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 diwindow.onload
. - Kendalikan kekunci ruang. Edit fungsi kekunci
-
** 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
Mengkaji & Belajar Sendiri
Percubaan dengan selang permainan anda setakat ini. Apa yang berlaku apabila anda menukarnya? Baca lebih lanjut mengenai acara pemasaan JavaScript.