12 KiB
Membangun Game Luar Angkasa Bagian 4: Menambahkan Laser dan Deteksi Tabrakan
Kuis Pra-Pelajaran
Dalam pelajaran ini, kamu akan belajar cara menembakkan laser menggunakan JavaScript! Kita akan menambahkan dua hal ke dalam game kita:
- Laser: laser ini ditembakkan dari kapal pahlawanmu dan bergerak vertikal ke atas.
- Deteksi tabrakan, sebagai bagian dari implementasi kemampuan menembak, kita juga akan menambahkan beberapa aturan permainan yang menarik:
- Laser mengenai musuh: Musuh akan mati jika terkena laser.
- Laser mengenai bagian atas layar: Laser akan dihancurkan jika menyentuh bagian atas layar.
- Tabrakan musuh dan pahlawan: Musuh dan pahlawan akan hancur jika saling bertabrakan.
- Musuh menyentuh bagian bawah layar: Musuh dan pahlawan akan hancur jika musuh mencapai bagian bawah layar.
Singkatnya, kamu -- sang pahlawan -- harus menghancurkan semua musuh dengan laser sebelum mereka berhasil mencapai bagian bawah layar.
✅ Lakukan sedikit riset tentang game komputer pertama yang pernah dibuat. Apa fungsinya?
Mari menjadi pahlawan bersama!
Deteksi Tabrakan
Bagaimana cara kita melakukan deteksi tabrakan? Kita perlu memikirkan objek game kita sebagai persegi panjang yang bergerak. Mengapa demikian? Karena gambar yang digunakan untuk menggambar objek game adalah persegi panjang: ia memiliki x
, y
, width
, dan height
.
Jika dua persegi panjang, misalnya pahlawan dan musuh berpotongan, maka terjadi tabrakan. Apa yang harus terjadi setelah itu tergantung pada aturan permainan. Untuk mengimplementasikan deteksi tabrakan, kamu memerlukan hal-hal berikut:
-
Cara untuk mendapatkan representasi persegi panjang dari sebuah objek game, seperti ini:
rectFromGameObject() { return { top: this.y, left: this.x, bottom: this.y + this.height, right: this.x + this.width } }
-
Fungsi perbandingan, fungsi ini dapat terlihat seperti ini:
function intersectRect(r1, r2) { return !(r2.left > r1.right || r2.right < r1.left || r2.top > r1.bottom || r2.bottom < r1.top); }
Bagaimana Cara Menghancurkan Sesuatu
Untuk menghancurkan sesuatu dalam game, kamu perlu memberi tahu game bahwa item tersebut tidak boleh lagi digambar dalam loop game yang dipicu pada interval tertentu. Salah satu cara untuk melakukannya adalah dengan menandai objek game sebagai mati ketika sesuatu terjadi, seperti ini:
// collision happened
enemy.dead = true
Kemudian kamu dapat melanjutkan untuk menyortir objek mati sebelum menggambar ulang layar, seperti ini:
gameObjects = gameObject.filter(go => !go.dead);
Bagaimana Cara Menembakkan Laser
Menembakkan laser berarti merespons sebuah event tombol dan membuat objek yang bergerak ke arah tertentu. Oleh karena itu, kita perlu melakukan langkah-langkah berikut:
- Membuat objek laser: dari bagian atas kapal pahlawan kita, yang setelah dibuat akan mulai bergerak ke atas menuju bagian atas layar.
- Menambahkan kode ke event tombol: kita perlu memilih tombol pada keyboard yang mewakili pemain menembakkan laser.
- Membuat objek game yang terlihat seperti laser ketika tombol ditekan.
Cooldown pada Laser
Laser perlu ditembakkan setiap kali kamu menekan tombol, misalnya spasi. Untuk mencegah game menghasilkan terlalu banyak laser dalam waktu singkat, kita perlu memperbaikinya. Perbaikan ini dilakukan dengan mengimplementasikan yang disebut cooldown, sebuah timer, yang memastikan bahwa laser hanya dapat ditembakkan dalam interval tertentu. Kamu dapat mengimplementasikannya seperti ini:
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.
}
}
}
✅ Lihat kembali pelajaran 1 dalam seri game luar angkasa untuk mengingat tentang cooldowns.
Apa yang Akan Dibangun
Kamu akan mengambil kode yang sudah ada (yang seharusnya sudah kamu bersihkan dan refactor) dari pelajaran sebelumnya, dan memperluasnya. Mulailah dengan kode dari bagian II atau gunakan kode di Bagian III - starter.
tip: laser yang akan kamu gunakan sudah ada di folder asetmu dan sudah direferensikan oleh kodenya
- Tambahkan deteksi tabrakan, ketika laser bertabrakan dengan sesuatu, aturan berikut harus diterapkan:
- Laser mengenai musuh: musuh mati jika terkena laser.
- Laser mengenai bagian atas layar: laser dihancurkan jika menyentuh bagian atas layar.
- Tabrakan musuh dan pahlawan: musuh dan pahlawan hancur jika saling bertabrakan.
- Musuh menyentuh bagian bawah layar: musuh dan pahlawan hancur jika musuh mencapai bagian bawah layar.
Langkah-Langkah yang Direkomendasikan
Temukan file yang telah dibuat untukmu di sub-folder your-work
. Folder ini seharusnya berisi:
-| assets
-| enemyShip.png
-| player.png
-| laserRed.png
-| index.html
-| app.js
-| package.json
Mulailah proyekmu di folder your_work
dengan mengetik:
cd your-work
npm start
Perintah di atas akan memulai HTTP Server di alamat http://localhost:5000
. Buka browser dan masukkan alamat tersebut, saat ini seharusnya hanya menampilkan pahlawan dan semua musuh, belum ada yang bergerak - belum :).
Tambahkan Kode
-
Siapkan representasi persegi panjang untuk objek game, untuk menangani tabrakan Kode di bawah ini memungkinkanmu mendapatkan representasi persegi panjang dari
GameObject
. Edit kelas GameObject-mu untuk memperluasnya:rectFromGameObject() { return { top: this.y, left: this.x, bottom: this.y + this.height, right: this.x + this.width, }; }
-
Tambahkan kode untuk memeriksa tabrakan Ini akan menjadi fungsi baru yang menguji apakah dua persegi panjang saling berpotongan:
function intersectRect(r1, r2) { return !( r2.left > r1.right || r2.right < r1.left || r2.top > r1.bottom || r2.bottom < r1.top ); }
-
Tambahkan kemampuan menembakkan laser
-
Tambahkan pesan event tombol. Tombol spasi harus membuat laser tepat di atas kapal pahlawan. Tambahkan tiga konstanta di objek Messages:
KEY_EVENT_SPACE: "KEY_EVENT_SPACE", COLLISION_ENEMY_LASER: "COLLISION_ENEMY_LASER", COLLISION_ENEMY_HERO: "COLLISION_ENEMY_HERO",
-
Tangani tombol spasi. Edit fungsi
window.addEventListener
keyup untuk menangani tombol spasi:} else if(evt.keyCode === 32) { eventEmitter.emit(Messages.KEY_EVENT_SPACE); }
-
Tambahkan pendengar event. Edit fungsi
initGame()
untuk memastikan pahlawan dapat menembak ketika tombol spasi ditekan:eventEmitter.on(Messages.KEY_EVENT_SPACE, () => { if (hero.canFire()) { hero.fire(); }
dan tambahkan fungsi
eventEmitter.on()
baru untuk memastikan perilaku ketika musuh bertabrakan dengan laser:eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => { first.dead = true; second.dead = true; })
-
Gerakkan objek, Pastikan laser bergerak ke atas layar secara bertahap. Kamu akan membuat kelas Laser baru yang memperluas
GameObject
, seperti yang telah kamu 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 tabrakan, Implementasikan aturan tabrakan untuk laser. Tambahkan fungsi
updateGameObjects()
yang menguji objek yang bertabrakan: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 menambahkan
updateGameObjects()
ke dalam loop game-mu diwindow.onload
. -
Implementasikan cooldown pada laser, sehingga hanya dapat ditembakkan dalam interval tertentu.
Terakhir, edit kelas Hero sehingga dapat melakukan cooldown:
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 titik ini, game-mu sudah memiliki beberapa fungsi! Kamu dapat bernavigasi dengan tombol panah, menembakkan laser dengan tombol spasi, dan musuh menghilang ketika kamu mengenainya. Kerja bagus!
🚀 Tantangan
Tambahkan ledakan! Lihat aset game di repo Space Art dan coba tambahkan efek ledakan ketika laser mengenai alien.
Kuis Pasca-Pelajaran
Tinjauan & Studi Mandiri
Bereksperimenlah dengan interval dalam game-mu sejauh ini. Apa yang terjadi ketika kamu mengubahnya? Baca lebih lanjut tentang event timing JavaScript.
Tugas
Penafian:
Dokumen ini telah diterjemahkan menggunakan layanan penerjemahan AI Co-op Translator. Meskipun kami berusaha untuk memberikan hasil yang akurat, harap diketahui bahwa terjemahan otomatis mungkin mengandung kesalahan atau ketidakakuratan. Dokumen asli dalam bahasa aslinya harus dianggap sebagai sumber yang otoritatif. Untuk informasi yang bersifat kritis, disarankan menggunakan jasa penerjemahan profesional oleh manusia. Kami tidak bertanggung jawab atas kesalahpahaman atau penafsiran yang keliru yang timbul dari penggunaan terjemahan ini.