18 KiB
Bina Permainan Angkasa Bahagian 4: Menambah Laser dan Mengesan Perlanggaran
Kuiz Pra-Kuliah
Fikirkan saat dalam Star Wars apabila torpedo proton Luke mengenai lubang ekzos Death Star. Pengesanan perlanggaran yang tepat itu mengubah nasib galaksi! Dalam permainan, pengesanan perlanggaran berfungsi dengan cara yang sama - ia menentukan bila objek berinteraksi dan apa yang berlaku seterusnya.
Dalam pelajaran ini, anda akan menambah senjata laser ke permainan angkasa anda dan melaksanakan pengesanan perlanggaran. Sama seperti perancang misi NASA mengira trajektori kapal angkasa untuk mengelakkan serpihan, anda akan belajar mengesan apabila objek permainan bersilang. Kami akan memecahkannya kepada langkah-langkah yang mudah difahami.
Pada akhirnya, anda akan mempunyai sistem pertempuran yang berfungsi di mana laser memusnahkan musuh dan perlanggaran mencetuskan acara permainan. Prinsip perlanggaran yang sama digunakan dalam segala-galanya daripada simulasi fizik hingga antara muka web interaktif.
✅ Lakukan sedikit penyelidikan tentang permainan komputer pertama yang pernah ditulis. Apakah fungsinya?
Pengesanan Perlanggaran
Pengesanan perlanggaran berfungsi seperti sensor jarak pada modul lunar Apollo - ia sentiasa memeriksa jarak dan mencetuskan amaran apabila objek terlalu dekat. Dalam permainan, sistem ini menentukan bila objek berinteraksi dan apa yang perlu berlaku seterusnya.
Pendekatan yang akan kita gunakan menganggap setiap objek permainan sebagai segi empat tepat, sama seperti sistem kawalan trafik udara menggunakan bentuk geometri yang dipermudahkan untuk menjejaki pesawat. Kaedah segi empat tepat ini mungkin kelihatan asas, tetapi ia cekap dari segi pengiraan dan berfungsi dengan baik untuk kebanyakan senario permainan.
Representasi Segi Empat Tepat
Setiap objek permainan memerlukan sempadan koordinat, sama seperti rover Mars Pathfinder memetakan lokasinya di permukaan Marikh. Berikut adalah cara kita menentukan koordinat sempadan ini:
rectFromGameObject() {
return {
top: this.y,
left: this.x,
bottom: this.y + this.height,
right: this.x + this.width
}
}
Mari kita pecahkan:
- Tepi atas: Di mana objek anda bermula secara menegak (posisi y)
- Tepi kiri: Di mana ia bermula secara mendatar (posisi x)
- Tepi bawah: Tambahkan ketinggian kepada posisi y - sekarang anda tahu di mana ia berakhir!
- Tepi kanan: Tambahkan lebar kepada posisi x - dan anda mempunyai sempadan lengkap
Algoritma Persilangan
Mengesan persilangan segi empat tepat menggunakan logik yang serupa dengan cara Teleskop Angkasa Hubble menentukan jika objek cakerawala bertindih dalam medan pandangannya. Algoritma ini memeriksa pemisahan:
function intersectRect(r1, r2) {
return !(r2.left > r1.right ||
r2.right < r1.left ||
r2.top > r1.bottom ||
r2.bottom < r1.top);
}
Ujian pemisahan berfungsi seperti sistem radar:
- Adakah segi empat tepat 2 sepenuhnya di sebelah kanan segi empat tepat 1?
- Adakah segi empat tepat 2 sepenuhnya di sebelah kiri segi empat tepat 1?
- Adakah segi empat tepat 2 sepenuhnya di bawah segi empat tepat 1?
- Adakah segi empat tepat 2 sepenuhnya di atas segi empat tepat 1?
Jika tiada satu pun daripada syarat ini benar, segi empat tepat mesti bertindih. Pendekatan ini mencerminkan cara pengendali radar menentukan jika dua pesawat berada pada jarak yang selamat.
Mengurus Kitaran Hayat Objek
Apabila laser mengenai musuh, kedua-dua objek perlu dikeluarkan dari permainan. Walau bagaimanapun, memadamkan objek semasa gelung boleh menyebabkan kerosakan - pelajaran yang dipelajari dengan susah payah dalam sistem komputer awal seperti Apollo Guidance Computer. Sebaliknya, kita menggunakan pendekatan "tandakan untuk penghapusan" yang selamat mengeluarkan objek antara bingkai.
Berikut adalah cara kita menandakan sesuatu untuk penghapusan:
// Mark object for removal
enemy.dead = true;
Mengapa pendekatan ini berfungsi:
- Kita menandakan objek sebagai "mati" tetapi tidak memadamkannya dengan segera
- Ini membolehkan bingkai permainan semasa selesai dengan selamat
- Tiada kerosakan daripada cuba menggunakan sesuatu yang sudah tiada!
Kemudian tapis objek yang ditandakan sebelum kitaran render seterusnya:
gameObjects = gameObjects.filter(go => !go.dead);
Apa yang penapisan ini lakukan:
- Membuat senarai baru dengan hanya objek "hidup"
- Membuang apa sahaja yang ditandakan sebagai mati
- Menjaga permainan anda berjalan lancar
- Mengelakkan pembaziran memori daripada pengumpulan objek yang dimusnahkan
Melaksanakan Mekanik Laser
Projektil laser dalam permainan berfungsi berdasarkan prinsip yang sama seperti torpedo foton dalam Star Trek - ia adalah objek diskret yang bergerak dalam garis lurus sehingga ia mengenai sesuatu. Setiap tekan bar ruang mencipta objek laser baru yang bergerak di skrin.
Untuk membuat ini berfungsi, kita perlu menyelaraskan beberapa bahagian yang berbeza:
Komponen utama untuk dilaksanakan:
- Cipta objek laser yang muncul dari posisi hero
- Kendalikan input papan kekunci untuk mencetuskan penciptaan laser
- Urus pergerakan dan kitaran hayat laser
- Laksanakan representasi visual untuk projektil laser
Melaksanakan Kawalan Kadar Tembakan
Kadar tembakan tanpa had akan membebankan enjin permainan dan menjadikan permainan terlalu mudah. Sistem senjata sebenar menghadapi kekangan yang sama - bahkan phaser USS Enterprise memerlukan masa untuk mengecas semula antara tembakan.
Kami akan melaksanakan sistem cooldown yang menghalang spam tembakan pantas sambil mengekalkan kawalan yang responsif:
class Cooldown {
constructor(time) {
this.cool = false;
setTimeout(() => {
this.cool = true;
}, time);
}
}
class Weapon {
constructor() {
this.cooldown = null;
}
fire() {
if (!this.cooldown || this.cooldown.cool) {
// Create laser projectile
this.cooldown = new Cooldown(500);
} else {
// Weapon is still cooling down
}
}
}
Bagaimana cooldown berfungsi:
- Apabila dicipta, senjata bermula "panas" (tidak boleh menembak lagi)
- Selepas tempoh timeout, ia menjadi "sejuk" (sedia untuk menembak)
- Sebelum menembak, kita periksa: "Adakah senjata sejuk?"
- Ini menghalang spam klik sambil mengekalkan kawalan yang responsif
✅ Rujuk pelajaran 1 dalam siri permainan angkasa untuk mengingatkan diri anda tentang cooldown.
Membina Sistem Pengesanan Perlanggaran
Anda akan melanjutkan kod permainan angkasa sedia ada anda untuk mencipta sistem pengesanan perlanggaran. Seperti sistem pengelakan perlanggaran automatik Stesen Angkasa Antarabangsa, permainan anda akan sentiasa memantau posisi objek dan bertindak balas terhadap persilangan.
Bermula dari kod pelajaran sebelumnya, anda akan menambah pengesanan perlanggaran dengan peraturan khusus yang mengawal interaksi objek.
💡 Tip Pro: Sprite laser sudah termasuk dalam folder aset anda dan dirujuk dalam kod anda, sedia untuk dilaksanakan.
Peraturan Perlanggaran untuk Dilaksanakan
Mekanisme permainan untuk ditambah:
- Laser mengenai musuh: Objek musuh dimusnahkan apabila terkena projektil laser
- Laser mengenai sempadan skrin: Laser dikeluarkan apabila mencapai tepi atas skrin
- Perlanggaran musuh dan hero: Kedua-dua objek dimusnahkan apabila mereka bersilang
- Musuh mencapai bawah: Keadaan tamat permainan apabila musuh mencapai bahagian bawah skrin
Menyediakan Persekitaran Pembangunan Anda
Berita baik - kami telah menyediakan kebanyakan asas untuk anda! Semua aset permainan dan struktur asas anda menunggu dalam subfolder your-work, sedia untuk anda menambah ciri perlanggaran yang menarik.
Struktur Projek
-| assets
-| enemyShip.png
-| player.png
-| laserRed.png
-| index.html
-| app.js
-| package.json
Memahami struktur fail:
- Mengandungi semua imej sprite yang diperlukan untuk objek permainan
- Termasuk dokumen HTML utama dan fail aplikasi JavaScript
- Menyediakan konfigurasi pakej untuk pelayan pembangunan tempatan
Memulakan Pelayan Pembangunan
Navigasi ke folder projek anda dan mulakan pelayan tempatan:
cd your-work
npm start
Urutan arahan ini:
- Menukar direktori ke folder projek kerja anda
- Memulakan pelayan HTTP tempatan pada
http://localhost:5000 - Menyajikan fail permainan anda untuk ujian dan pembangunan
- Membolehkan pembangunan langsung dengan pemuatan semula automatik
Buka pelayar anda dan navigasi ke http://localhost:5000 untuk melihat keadaan permainan semasa anda dengan hero dan musuh yang dirender di skrin.
Pelaksanaan Langkah Demi Langkah
Seperti pendekatan sistematik yang digunakan NASA untuk memprogramkan kapal angkasa Voyager, kami akan melaksanakan pengesanan perlanggaran secara metodik, membina setiap komponen langkah demi langkah.
1. Tambah Sempadan Perlanggaran Segi Empat Tepat
Pertama, mari ajar objek permainan kita bagaimana untuk menerangkan sempadan mereka. Tambahkan kaedah ini ke kelas GameObject anda:
rectFromGameObject() {
return {
top: this.y,
left: this.x,
bottom: this.y + this.height,
right: this.x + this.width,
};
}
Kaedah ini mencapai:
- Mencipta objek segi empat tepat dengan koordinat sempadan yang tepat
- Mengira tepi bawah dan kanan menggunakan posisi ditambah dimensi
- Mengembalikan objek sedia untuk algoritma pengesanan perlanggaran
- Menyediakan antara muka standard untuk semua objek permainan
2. Laksanakan Pengesanan Persilangan
Sekarang mari kita cipta detektif perlanggaran kita - fungsi yang boleh memberitahu bila dua segi empat tepat bertindih:
function intersectRect(r1, r2) {
return !(
r2.left > r1.right ||
r2.right < r1.left ||
r2.top > r1.bottom ||
r2.bottom < r1.top
);
}
Algoritma ini berfungsi dengan:
- Menguji empat syarat pemisahan antara segi empat tepat
- Mengembalikan
falsejika mana-mana syarat pemisahan adalah benar - Menunjukkan perlanggaran apabila tiada pemisahan wujud
- Menggunakan logik penafian untuk ujian persilangan yang cekap
3. Laksanakan Sistem Tembakan Laser
Di sinilah perkara menjadi menarik! Mari kita sediakan sistem tembakan laser.
Konstanta Mesej
Pertama, mari kita tentukan beberapa jenis mesej supaya bahagian-bahagian permainan kita boleh berkomunikasi antara satu sama lain:
KEY_EVENT_SPACE: "KEY_EVENT_SPACE",
COLLISION_ENEMY_LASER: "COLLISION_ENEMY_LASER",
COLLISION_ENEMY_HERO: "COLLISION_ENEMY_HERO",
Konstanta ini menyediakan:
- Menstandardkan nama acara di seluruh aplikasi
- Membolehkan komunikasi konsisten antara sistem permainan
- Mengelakkan kesilapan dalam pendaftaran pengendali acara
Pengendalian Input Papan Kekunci
Tambahkan pengesanan kekunci ruang ke pendengar acara kekunci anda:
} else if(evt.keyCode === 32) {
eventEmitter.emit(Messages.KEY_EVENT_SPACE);
}
Pengendali input ini:
- Mengesan tekan kekunci ruang menggunakan keyCode 32
- Menghantar mesej acara yang standard
- Membolehkan logik tembakan yang tidak bergantung
Persediaan Pendengar Acara
Daftarkan tingkah laku tembakan dalam fungsi initGame() anda:
eventEmitter.on(Messages.KEY_EVENT_SPACE, () => {
if (hero.canFire()) {
hero.fire();
}
});
Pendengar acara ini:
- Bertindak balas kepada acara kekunci ruang
- Memeriksa status cooldown tembakan
- Mencetuskan penciptaan laser apabila dibenarkan
Tambahkan pengendalian perlanggaran untuk interaksi laser-musuh:
eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => {
first.dead = true;
second.dead = true;
});
Pengendali perlanggaran ini:
- Menerima data acara perlanggaran dengan kedua-dua objek
- Menandakan kedua-dua objek untuk penghapusan
- Memastikan pembersihan yang betul selepas perlanggaran
4. Cipta Kelas Laser
Laksanakan projektil laser yang bergerak ke atas dan menguruskan kitaran hayatnya sendiri:
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);
}
}
Pelaksanaan kelas ini:
- Melanjutkan GameObject untuk mewarisi fungsi asas
- Menetapkan dimensi yang sesuai untuk sprite laser
- Mencipta pergerakan automatik ke atas menggunakan
setInterval() - Mengendalikan pemusnahan diri apabila mencapai bahagian atas skrin
- Menguruskan masa animasi dan pembersihan sendiri
5. Laksanakan Sistem Pengesanan Perlanggaran
Cipta fungsi pengesanan perlanggaran yang komprehensif:
function updateGameObjects() {
const enemies = gameObjects.filter(go => go.type === 'Enemy');
const lasers = gameObjects.filter(go => go.type === "Laser");
// Test laser-enemy collisions
lasers.forEach((laser) => {
enemies.forEach((enemy) => {
if (intersectRect(laser.rectFromGameObject(), enemy.rectFromGameObject())) {
eventEmitter.emit(Messages.COLLISION_ENEMY_LASER, {
first: laser,
second: enemy,
});
}
});
});
// Remove destroyed objects
gameObjects = gameObjects.filter(go => !go.dead);
}
Sistem perlanggaran ini:
- Menapis objek permainan mengikut jenis untuk ujian yang cekap
- Menguji setiap laser terhadap setiap musuh untuk persilangan
- Menghantar acara perlanggaran apabila persilangan dikesan
- Membersihkan objek yang dimusnahkan selepas pemprosesan perlanggaran
⚠️ Penting: Tambahkan
updateGameObjects()ke gelung permainan utama anda dalamwindow.onloaduntuk mengaktifkan pengesanan perlanggaran.
6. Tambahkan Sistem Cooldown ke Kelas Hero
Tingkatkan kelas Hero dengan mekanik tembakan dan had kadar tembakan:
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;
}
}
Memahami kelas Hero yang ditingkatkan:
- Memulakan pemasa cooldown pada sifar (sedia untuk menembak)
- Mencipta objek laser yang diposisikan di atas kapal hero
- Menetapkan tempoh cooldown untuk menghalang tembakan pantas
- Mengurangkan pemasa cooldown menggunakan kemas kini berasaskan selang
- Menyediakan pemeriksaan status tembakan melalui kaedah
canFire()
Menguji Pelaksanaan Anda
Permainan angkasa anda kini mempunyai pengesanan perlanggaran lengkap dan mekanik pertempuran. 🚀 Uji keupayaan baru ini:
- Navigasi dengan kekunci anak panah untuk mengesahkan kawalan pergerakan
- Tembak laser dengan bar ruang - perhatikan bagaimana cooldown menghalang spam klik
- Perhatikan perlanggaran apabila laser mengenai musuh, mencetuskan penghapusan
- Sahkan pembersihan apabila objek yang dimusnahkan hilang dari permainan
Anda telah berjaya melaksanakan sistem pengesanan perlanggaran menggunakan prinsip matematik yang sama yang membimbing navigasi kapal angkasa dan robotik.
Cabaran Ejen GitHub Copilot 🚀
Gunakan mod Ejen untuk menyelesaikan cabaran berikut:
Penerangan: Tingkatkan sistem pengesanan perlanggaran dengan melaksanakan power-up yang muncul secara rawak dan memberikan keupayaan sementara apabila dikumpulkan oleh kapal hero.
Arahan: Cipta kelas PowerUp yang melanjutkan GameObject dan laksanakan pengesanan perlanggaran antara hero dan power-up. Tambahkan sekurang-kurangnya dua jenis power-up: satu yang meningkatkan kadar tembakan (mengurangkan cooldown) dan satu lagi yang mencipta perisai sementara. Sertakan logik spawn yang mencipta power-up pada selang dan posisi rawak.
🚀 Cabaran
Tambahkan letupan! Lihat aset permainan dalam repo Seni Angkasa dan cuba tambahkan letupan apabila laser mengenai alien.
Kuiz Pasca-Kuliah
Ulasan & Kajian Sendiri
Eksperimen dengan selang dalam permainan anda setakat ini. Apa yang berlaku apabila anda mengubahnya? Baca lebih lanjut tentang acara masa JavaScript.
Tugasan
Penafian:
Dokumen ini telah diterjemahkan menggunakan perkhidmatan terjemahan AI Co-op Translator. Walaupun kami berusaha untuk ketepatan, sila ambil perhatian bahawa terjemahan automatik mungkin mengandungi kesilapan atau ketidaktepatan. Dokumen asal dalam bahasa asalnya harus dianggap sebagai sumber yang berwibawa. Untuk maklumat kritikal, terjemahan manusia profesional adalah disyorkan. Kami tidak bertanggungjawab atas sebarang salah faham atau salah tafsir yang timbul daripada penggunaan terjemahan ini.