38 KiB
Bina Permainan Angkasa Bahagian 3: Menambah Pergerakan
journey
title Your Game Animation Journey
section Movement Basics
Understand motion principles: 3: Student
Learn coordinate updates: 4: Student
Implement basic movement: 4: Student
section Player Controls
Handle keyboard events: 4: Student
Prevent default behaviors: 5: Student
Create responsive controls: 5: Student
section Game Systems
Build game loop: 5: Student
Manage object lifecycle: 5: Student
Implement pub/sub pattern: 5: Student
Fikirkan tentang permainan kegemaran anda – apa yang membuatkan ia menarik bukan hanya grafik yang cantik, tetapi cara semuanya bergerak dan bertindak balas terhadap tindakan anda. Sekarang, permainan angkasa anda seperti lukisan yang indah, tetapi kita akan menambah pergerakan yang menghidupkannya.
Apabila jurutera NASA memprogramkan komputer panduan untuk misi Apollo, mereka menghadapi cabaran yang sama: bagaimana membuat kapal angkasa bertindak balas terhadap input juruterbang sambil secara automatik mengekalkan pembetulan kursus? Prinsip yang akan kita pelajari hari ini mencerminkan konsep yang sama – menguruskan pergerakan yang dikawal pemain bersama tingkah laku sistem automatik.
Dalam pelajaran ini, anda akan belajar bagaimana membuat kapal angkasa meluncur di skrin, bertindak balas terhadap arahan pemain, dan mencipta corak pergerakan yang lancar. Kami akan memecahkan semuanya kepada konsep yang mudah difahami dan saling berkaitan.
Pada akhirnya, pemain akan dapat mengemudi kapal hero mereka di skrin sementara kapal musuh berpatroli di atas. Lebih penting lagi, anda akan memahami prinsip asas yang menggerakkan sistem pergerakan permainan.
mindmap
root((Game Animation))
Movement Types
Player Controlled
Automatic Motion
Physics Based
Scripted Paths
Event Handling
Keyboard Input
Mouse Events
Touch Controls
Default Prevention
Game Loop
Update Logic
Render Frame
Clear Canvas
Frame Rate Control
Object Management
Position Updates
Collision Detection
Lifecycle Management
State Tracking
Communication
Pub/Sub Pattern
Event Emitters
Message Passing
Loose Coupling
Kuiz Pra-Pelajaran
Memahami Pergerakan Permainan
Permainan menjadi hidup apabila objek mula bergerak, dan secara asasnya terdapat dua cara ini berlaku:
- Pergerakan yang dikawal pemain: Apabila anda menekan kekunci atau klik tetikus, sesuatu bergerak. Ini adalah hubungan langsung antara anda dan dunia permainan.
- Pergerakan automatik: Apabila permainan itu sendiri memutuskan untuk menggerakkan objek – seperti kapal musuh yang perlu berpatroli di skrin tanpa mengira apa yang anda lakukan.
Membuat objek bergerak di skrin komputer lebih mudah daripada yang anda fikirkan. Ingat koordinat x dan y dari kelas matematik? Itulah yang kita gunakan di sini. Apabila Galileo menjejaki bulan Jupiter pada tahun 1610, dia pada dasarnya melakukan perkara yang sama – memplot kedudukan dari masa ke masa untuk memahami corak pergerakan.
Menggerakkan objek di skrin adalah seperti mencipta animasi buku flip – anda perlu mengikuti tiga langkah mudah ini:
flowchart LR
A["Frame N"] --> B["Update Positions"]
B --> C["Clear Canvas"]
C --> D["Draw Objects"]
D --> E["Frame N+1"]
E --> F{Continue?}
F -->|Yes| B
F -->|No| G["Game Over"]
subgraph "Animation Cycle"
H["1. Calculate new positions"]
I["2. Erase previous frame"]
J["3. Render new frame"]
end
style B fill:#e1f5fe
style C fill:#ffebee
style D fill:#e8f5e8
- Kemas kini kedudukan – Tukar di mana objek anda sepatutnya berada (mungkin gerakkannya 5 piksel ke kanan)
- Padam bingkai lama – Kosongkan skrin supaya anda tidak melihat jejak bayangan di mana-mana
- Lukis bingkai baru – Letakkan objek anda di tempat barunya
Lakukan ini dengan cukup pantas, dan boom! Anda mendapat pergerakan yang lancar yang terasa semula jadi kepada pemain.
Inilah rupa kodnya:
// Set the hero's location
hero.x += 5;
// Clear the rectangle that hosts the hero
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Redraw the game background and hero
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "black";
ctx.drawImage(heroImg, hero.x, hero.y);
Apa yang dilakukan oleh kod ini:
- Mengemas kini koordinat x hero sebanyak 5 piksel untuk menggerakkannya secara mendatar
- Membersihkan seluruh kawasan kanvas untuk menghapus bingkai sebelumnya
- Mengisi kanvas dengan warna latar belakang hitam
- Melukis semula imej hero di kedudukan barunya
✅ Bolehkah anda memikirkan sebab mengapa melukis semula hero anda banyak bingkai sesaat mungkin menyebabkan kos prestasi? Baca tentang alternatif kepada corak ini.
Mengendalikan acara papan kekunci
Di sinilah kita menghubungkan input pemain kepada tindakan permainan. Apabila seseorang menekan bar ruang untuk menembak laser atau mengetuk kekunci anak panah untuk mengelak asteroid, permainan anda perlu mengesan dan bertindak balas terhadap input tersebut.
Acara papan kekunci berlaku di peringkat tetingkap, bermakna seluruh tetingkap pelayar anda mendengar penekanan kekunci tersebut. Klik tetikus, sebaliknya, boleh diikat kepada elemen tertentu (seperti mengklik butang). Untuk permainan angkasa kita, kita akan fokus pada kawalan papan kekunci kerana itulah yang memberikan pemain rasa arked klasik.
Ini mengingatkan saya kepada bagaimana operator telegraf pada tahun 1800-an perlu menterjemah input kod morse kepada mesej yang bermakna – kita melakukan sesuatu yang serupa, menterjemah penekanan kekunci kepada arahan permainan.
Untuk mengendalikan acara, anda perlu menggunakan kaedah addEventListener() tetingkap dan memberikannya dua parameter input. Parameter pertama adalah nama acara, contohnya keyup. Parameter kedua adalah fungsi yang harus dipanggil sebagai hasil daripada acara yang berlaku.
Berikut adalah contoh:
window.addEventListener('keyup', (evt) => {
// evt.key = string representation of the key
if (evt.key === 'ArrowUp') {
// do something
}
});
Memecahkan apa yang berlaku di sini:
- Mendengar acara papan kekunci pada seluruh tetingkap
- Menangkap objek acara yang mengandungi maklumat tentang kekunci mana yang ditekan
- Memeriksa jika kekunci yang ditekan sepadan dengan kekunci tertentu (dalam kes ini, anak panah atas)
- Melaksanakan kod apabila syarat dipenuhi
Untuk acara kekunci terdapat dua sifat pada acara yang boleh anda gunakan untuk melihat kekunci mana yang ditekan:
key- ini adalah representasi string kekunci yang ditekan, contohnya'ArrowUp'keyCode- ini adalah representasi nombor, contohnya37, sepadan denganArrowLeft
✅ Manipulasi acara kekunci berguna di luar pembangunan permainan. Apakah kegunaan lain yang boleh anda fikirkan untuk teknik ini?
sequenceDiagram
participant User
participant Browser
participant EventSystem
participant GameLogic
participant Hero
User->>Browser: Presses ArrowUp key
Browser->>EventSystem: keydown event
EventSystem->>EventSystem: preventDefault()
EventSystem->>GameLogic: emit('KEY_EVENT_UP')
GameLogic->>Hero: hero.y -= 5
Hero->>Hero: Update position
Note over Browser,GameLogic: Event flow prevents browser defaults
Note over GameLogic,Hero: Pub/sub pattern enables clean communication
Kekunci khas: perhatian!
Sesetengah kekunci mempunyai tingkah laku terbina dalam pelayar yang boleh mengganggu permainan anda. Kekunci anak panah menatal halaman dan bar ruang melompat ke bawah – tingkah laku yang tidak anda inginkan apabila seseorang cuba mengemudi kapal angkasa mereka.
Kita boleh menghalang tingkah laku lalai ini dan membiarkan permainan kita mengendalikan input sebaliknya. Ini serupa dengan bagaimana pengaturcara komputer awal perlu mengatasi gangguan sistem untuk mencipta tingkah laku tersuai – kita hanya melakukannya di peringkat pelayar. Berikut adalah caranya:
const onKeyDown = function (e) {
console.log(e.keyCode);
switch (e.keyCode) {
case 37:
case 39:
case 38:
case 40: // Arrow keys
case 32:
e.preventDefault();
break; // Space
default:
break; // do not block other keys
}
};
window.addEventListener('keydown', onKeyDown);
Memahami kod pencegahan ini:
- Memeriksa kod kekunci tertentu yang mungkin menyebabkan tingkah laku pelayar yang tidak diingini
- Menghalang tindakan pelayar lalai untuk kekunci anak panah dan bar ruang
- Membenarkan kekunci lain berfungsi seperti biasa
- Menggunakan
e.preventDefault()untuk menghentikan tingkah laku terbina dalam pelayar
🔄 Pemeriksaan Pedagogi
Pemahaman Pengendalian Acara: Sebelum beralih kepada pergerakan automatik, pastikan anda boleh:
- ✅ Jelaskan perbezaan antara acara
keydowndankeyup - ✅ Fahami mengapa kita menghalang tingkah laku lalai pelayar
- ✅ Terangkan bagaimana pendengar acara menghubungkan input pengguna kepada logik permainan
- ✅ Kenal pasti kekunci mana yang mungkin mengganggu kawalan permainan
Ujian Kendiri Cepat: Apa yang akan berlaku jika anda tidak menghalang tingkah laku lalai untuk kekunci anak panah? Jawapan: Pelayar akan menatal halaman, mengganggu pergerakan permainan
Seni Bina Sistem Acara: Anda kini memahami:
- Pendengaran peringkat tetingkap: Menangkap acara di peringkat pelayar
- Sifat objek acara: String
keyvs nomborkeyCode - Pencegahan lalai: Menghentikan tingkah laku pelayar yang tidak diingini
- Logik bersyarat: Bertindak balas kepada kombinasi kekunci tertentu
Pergerakan yang disebabkan oleh permainan
Sekarang mari kita bincangkan objek yang bergerak tanpa input pemain. Fikirkan tentang kapal musuh yang meluncur di skrin, peluru yang terbang dalam garis lurus, atau awan yang melayang di latar belakang. Pergerakan autonomi ini membuatkan dunia permainan anda terasa hidup walaupun tiada siapa yang menyentuh kawalan.
Kita menggunakan pemasa terbina dalam JavaScript untuk mengemas kini kedudukan pada selang masa tetap. Konsep ini serupa dengan bagaimana jam pendulum berfungsi – mekanisme tetap yang mencetuskan tindakan yang konsisten dan berjadual. Berikut adalah betapa mudahnya:
const id = setInterval(() => {
// Move the enemy on the y axis
enemy.y += 10;
}, 100);
Apa yang dilakukan oleh kod pergerakan ini:
- Mencipta pemasa yang berjalan setiap 100 milisaat
- Mengemas kini koordinat y musuh sebanyak 10 piksel setiap kali
- Menyimpan ID selang supaya kita boleh menghentikannya kemudian jika diperlukan
- Menggerakkan musuh ke bawah skrin secara automatik
Gelung permainan
Inilah konsep yang mengikat semuanya – gelung permainan. Jika permainan anda adalah sebuah filem, gelung permainan akan menjadi projektor filem, menunjukkan bingkai demi bingkai dengan cukup pantas sehingga semuanya kelihatan bergerak dengan lancar.
Setiap permainan mempunyai salah satu gelung ini berjalan di belakang tabir. Ia adalah fungsi yang mengemas kini semua objek permainan, melukis semula skrin, dan mengulangi proses ini secara berterusan. Ini menjejaki hero anda, semua musuh, mana-mana laser yang terbang – keseluruhan keadaan permainan.
Konsep ini mengingatkan saya kepada bagaimana animator filem awal seperti Walt Disney perlu melukis semula watak bingkai demi bingkai untuk mencipta ilusi pergerakan. Kita melakukan perkara yang sama, hanya dengan kod dan bukannya pensel.
Berikut adalah rupa gelung permainan, yang dinyatakan dalam kod:
flowchart TD
A["Start Game Loop"] --> B["Clear Canvas"]
B --> C["Fill Background"]
C --> D["Update Game Objects"]
D --> E["Draw Hero"]
E --> F["Draw Enemies"]
F --> G["Draw UI Elements"]
G --> H["Wait for Next Frame"]
H --> I{Game Running?}
I -->|Yes| B
I -->|No| J["End Game"]
subgraph "Frame Rate Control"
K["60 FPS = 16.67ms"]
L["30 FPS = 33.33ms"]
M["10 FPS = 100ms"]
end
style B fill:#ffebee
style D fill:#e1f5fe
style E fill:#e8f5e8
style F fill:#e8f5e8
const gameLoopId = setInterval(() => {
function gameLoop() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canvas.width, canvas.height);
drawHero();
drawEnemies();
drawStaticObjects();
}
gameLoop();
}, 200);
Memahami struktur gelung permainan:
- Membersihkan seluruh kanvas untuk menghapus bingkai sebelumnya
- Mengisi latar belakang dengan warna solid
- Melukis semua objek permainan di kedudukan semasa mereka
- Mengulangi proses ini setiap 200 milisaat untuk mencipta animasi yang lancar
- Menguruskan kadar bingkai dengan mengawal masa selang
Meneruskan Permainan Angkasa
Sekarang kita akan menambah pergerakan kepada adegan statik yang anda bina sebelum ini. Kita akan mengubahnya daripada tangkapan skrin kepada pengalaman interaktif. Kita akan bekerja melalui langkah ini satu persatu untuk memastikan setiap bahagian saling berkaitan.
Ambil kod dari tempat kita berhenti dalam pelajaran sebelumnya (atau mulakan dengan kod dalam folder Bahagian II - permulaan jika anda memerlukan permulaan baru).
Inilah yang kita bina hari ini:
- Kawalan hero: Kekunci anak panah akan mengemudi kapal angkasa anda di skrin
- Pergerakan musuh: Kapal alien itu akan mula mara
Mari kita mulakan pelaksanaan ciri-ciri ini.
Langkah yang disyorkan
Cari fail yang telah dibuat untuk anda dalam sub folder your-work. Ia sepatutnya mengandungi:
-| assets
-| enemyShip.png
-| player.png
-| index.html
-| app.js
-| package.json
Anda memulakan projek anda dalam folder your-work dengan menaip:
cd your-work
npm start
Apa yang dilakukan oleh arahan ini:
- Menavigasi ke direktori projek anda
- Memulakan HTTP Server pada alamat
http://localhost:5000 - Menyajikan fail permainan anda supaya anda boleh mengujinya dalam pelayar
Arahan di atas akan memulakan HTTP Server pada alamat http://localhost:5000. Buka pelayar dan masukkan alamat itu, sekarang ia sepatutnya memaparkan hero dan semua musuh; tiada apa yang bergerak - lagi!
Tambah kod
-
Tambah objek khusus untuk
herodanenemydangame object, mereka sepatutnya mempunyai sifatxdany. (Ingat bahagian tentang Pewarisan atau komposisi).PETUNJUK
game objectsepatutnya menjadi yang mempunyaixdanyserta keupayaan untuk melukis dirinya ke kanvas.Tip: Mulakan dengan menambah kelas
GameObjectbaru dengan pembinaannya seperti di bawah, dan kemudian lukisnya ke kanvas:class GameObject { constructor(x, y) { this.x = x; this.y = y; this.dead = false; this.type = ""; this.width = 0; this.height = 0; this.img = undefined; } draw(ctx) { ctx.drawImage(this.img, this.x, this.y, this.width, this.height); } }Memahami kelas asas ini:
- Menentukan sifat umum yang dikongsi oleh semua objek permainan (kedudukan, saiz, imej)
- Termasuk bendera
deaduntuk menjejaki sama ada objek itu perlu dikeluarkan - Menyediakan kaedah
draw()yang melukis objek pada kanvas - Menetapkan nilai lalai untuk semua sifat yang boleh diatasi oleh kelas anak
classDiagram class GameObject { +x: number +y: number +dead: boolean +type: string +width: number +height: number +img: Image +draw(ctx) } class Hero { +speed: number +type: "Hero" +width: 98 +height: 75 } class Enemy { +type: "Enemy" +width: 98 +height: 50 +setInterval() } GameObject <|-- Hero GameObject <|-- Enemy class EventEmitter { +listeners: object +on(message, listener) +emit(message, payload) }Sekarang, kembangkan
GameObjectini untuk menciptaHerodanEnemy:class Hero extends GameObject { constructor(x, y) { super(x, y); this.width = 98; this.height = 75; this.type = "Hero"; this.speed = 5; } }class Enemy extends GameObject { constructor(x, y) { super(x, y); this.width = 98; this.height = 50; this.type = "Enemy"; const id = setInterval(() => { if (this.y < canvas.height - this.height) { this.y += 5; } else { console.log('Stopped at', this.y); clearInterval(id); } }, 300); } }Konsep utama dalam kelas ini:
- Mewarisi daripada
GameObjectmenggunakan kata kunciextends - Memanggil pembina induk dengan
super(x, y) - Menetapkan dimensi dan sifat khusus untuk setiap jenis objek
- Melaksanakan pergerakan automatik untuk musuh menggunakan
setInterval()
-
Tambah pengendali acara kekunci untuk mengendalikan navigasi kekunci (gerakkan hero ke atas/bawah kiri/kanan)
INGAT ia adalah sistem kartesian, sudut kiri atas adalah
0,0. Juga ingat untuk menambah kod untuk menghentikan tingkah laku lalaiTip: Cipta fungsi
onKeyDownanda dan lampirkan kepada tetingkap:const onKeyDown = function (e) { console.log(e.keyCode); // Add the code from the lesson above to stop default behavior switch (e.keyCode) { case 37: case 39: case 38: case 40: // Arrow keys case 32: e.preventDefault(); break; // Space default: break; // do not block other keys } }; window.addEventListener("keydown", onKeyDown);Apa yang dilakukan oleh pengendali acara ini:
- Mendengar acara
keydownpada seluruh tetingkap - Mencatat kod kekunci untuk membantu anda menyahpepijat kekunci mana yang ditekan
- Menghalang tingkah laku lalai pelayar untuk kekunci anak panah dan bar ruang
- Membenarkan kekunci lain berfungsi seperti biasa
Periksa konsol pelayar anda pada ketika ini, dan lihat penekanan kekunci yang dicatatkan.
- Mendengar acara
-
Laksanakan Corak Pub sub, ini akan memastikan kod anda bersih semasa anda mengikuti bahagian yang tinggal.
Corak Publish-Subscribe membantu mengatur kod anda dengan memisahkan pengesanan acara daripada pengendalian acara. Ini menjadikan kod anda lebih modular dan mudah diselenggara.
Untuk melakukan bahagian terakhir ini, anda boleh:
-
Tambah pendengar acara pada tetingkap:
window.addEventListener("keyup", (evt) => { if (evt.key === "ArrowUp") { eventEmitter.emit(Messages.KEY_EVENT_UP); } else if (evt.key === "ArrowDown") { eventEmitter.emit(Messages.KEY_EVENT_DOWN); } else if (evt.key === "ArrowLeft") { eventEmitter.emit(Messages.KEY_EVENT_LEFT); } else if (evt.key === "ArrowRight") { eventEmitter.emit(Messages.KEY_EVENT_RIGHT); } });
Apa yang dilakukan oleh sistem acara ini:
- Mengesan input papan kekunci dan menukarkannya kepada acara permainan tersuai
- Memisahkan pengesanan input daripada logik permainan
- Memudahkan perubahan kawalan kemudian tanpa menjejaskan kod permainan
- Membenarkan pelbagai sistem bertindak balas kepada input yang sama
flowchart TD A["Keyboard Input"] --> B["Window Event Listener"] B --> C["Event Emitter"] C --> D["KEY_EVENT_UP"] C --> E["KEY_EVENT_DOWN"] C --> F["KEY_EVENT_LEFT"] C --> G["KEY_EVENT_RIGHT"] D --> H["Hero Movement"] D --> I["Sound System"] D --> J["Visual Effects"] E --> H F --> H G --> H style A fill:#e1f5fe style C fill:#e8f5e8 style H fill:#fff3e0-
Cipta kelas EventEmitter untuk menerbitkan dan melanggan mesej:
class EventEmitter { constructor() { this.listeners = {}; } on(message, listener) { if (!this.listeners[message]) { this.listeners[message] = []; } this.listeners[message].push(listener); } -
Tambah pemalar dan sediakan EventEmitter:
const Messages = { KEY_EVENT_UP: "KEY_EVENT_UP", KEY_EVENT_DOWN: "KEY_EVENT_DOWN", KEY_EVENT_LEFT: "KEY_EVENT_LEFT", KEY_EVENT_RIGHT: "KEY_EVENT_RIGHT", }; let heroImg, enemyImg, laserImg, canvas, ctx, gameObjects = [], hero, eventEmitter = new EventEmitter();
Memahami persediaan:
- Menentukan pemalar mesej untuk mengelakkan kesilapan dan memudahkan penstrukturan semula
- Mengisytiharkan pembolehubah untuk imej, konteks kanvas, dan keadaan permainan
- Mencipta pemancar acara global untuk sistem pub-sub
- Memulakan array untuk menyimpan semua objek permainan
-
Mulakan permainan
function initGame() { gameObjects = []; createEnemies(); createHero(); eventEmitter.on(Messages.KEY_EVENT_UP, () => { hero.y -= 5; }); eventEmitter.on(Messages.KEY_EVENT_DOWN, () => { hero.y += 5; }); eventEmitter.on(Messages.KEY_EVENT_LEFT, () => { hero.x -= 5; });
-
-
Tetapkan gelung permainan
Refactor fungsi
window.onloaduntuk memulakan permainan dan menetapkan gelung permainan pada selang masa yang sesuai. Anda juga akan menambah pancaran laser:window.onload = async () => { canvas = document.getElementById("canvas"); ctx = canvas.getContext("2d"); heroImg = await loadTexture("assets/player.png"); enemyImg = await loadTexture("assets/enemyShip.png"); laserImg = await loadTexture("assets/laserRed.png"); initGame(); const gameLoopId = setInterval(() => { ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = "black"; ctx.fillRect(0, 0, canvas.width, canvas.height); drawGameObjects(ctx); }, 100); };Memahami tetapan permainan:
- Menunggu halaman dimuat sepenuhnya sebelum memulakan
- Mendapatkan elemen kanvas dan konteks rendering 2D-nya
- Memuatkan semua aset imej secara asinkron menggunakan
await - Memulakan gelung permainan berjalan pada selang masa 100ms (10 FPS)
- Membersihkan dan melukis semula keseluruhan skrin setiap bingkai
-
Tambah kod untuk menggerakkan musuh pada selang masa tertentu
Refactor fungsi
createEnemies()untuk mencipta musuh dan menambah mereka ke dalam kelas gameObjects yang baru:function createEnemies() { const MONSTER_TOTAL = 5; const MONSTER_WIDTH = MONSTER_TOTAL * 98; const START_X = (canvas.width - MONSTER_WIDTH) / 2; const STOP_X = START_X + MONSTER_WIDTH; for (let x = START_X; x < STOP_X; x += 98) { for (let y = 0; y < 50 * 5; y += 50) { const enemy = new Enemy(x, y); enemy.img = enemyImg; gameObjects.push(enemy); } } }Apa yang dilakukan oleh penciptaan musuh:
- Mengira posisi untuk memusatkan musuh di skrin
- Mencipta grid musuh menggunakan gelung bersarang
- Menetapkan imej musuh kepada setiap objek musuh
- Menambah setiap musuh ke dalam array objek permainan global
dan tambah fungsi
createHero()untuk melakukan proses serupa bagi hero.function createHero() { hero = new Hero( canvas.width / 2 - 45, canvas.height - canvas.height / 4 ); hero.img = heroImg; gameObjects.push(hero); }Apa yang dilakukan oleh penciptaan hero:
- Memposisikan hero di bahagian bawah tengah skrin
- Menetapkan imej hero kepada objek hero
- Menambah hero ke dalam array objek permainan untuk rendering
dan akhirnya, tambah fungsi
drawGameObjects()untuk memulakan lukisan:function drawGameObjects(ctx) { gameObjects.forEach(go => go.draw(ctx)); }Memahami fungsi lukisan:
- Mengiterasi semua objek permainan dalam array
- Memanggil kaedah
draw()pada setiap objek - Menyampaikan konteks kanvas supaya objek boleh melukis diri mereka sendiri
🔄 Pemeriksaan Pedagogi
Pemahaman Sistem Permainan Lengkap: Sahkan penguasaan anda terhadap keseluruhan seni bina:
- ✅ Bagaimana pewarisan membolehkan Hero dan Musuh berkongsi sifat GameObject yang sama?
- ✅ Mengapa corak pub/sub menjadikan kod anda lebih mudah diselenggara?
- ✅ Apa peranan gelung permainan dalam mencipta animasi yang lancar?
- ✅ Bagaimana pendengar acara menghubungkan input pengguna kepada tingkah laku objek permainan?
Integrasi Sistem: Permainan anda kini menunjukkan:
- Reka Bentuk Berorientasikan Objek: Kelas asas dengan pewarisan khusus
- Seni Bina Berasaskan Acara: Corak pub/sub untuk penggandingan longgar
- Kerangka Animasi: Gelung permainan dengan kemas kini bingkai yang konsisten
- Pengendalian Input: Acara papan kekunci dengan pencegahan lalai
- Pengurusan Aset: Pemuatan imej dan rendering sprite
Corak Profesional: Anda telah melaksanakan:
- Pemisahan Kebimbangan: Input, logik, dan rendering dipisahkan
- Polimorfisme: Semua objek permainan berkongsi antara muka lukisan yang sama
- Penghantaran Mesej: Komunikasi bersih antara komponen
- Pengurusan Sumber: Pengendalian sprite dan animasi yang cekap
Musuh anda sepatutnya mula maju ke arah kapal angkasa hero anda! } }
and add a `createHero()` function to do a similar process for the hero. ```javascript function createHero() { hero = new Hero( canvas.width / 2 - 45, canvas.height - canvas.height / 4 ); hero.img = heroImg; gameObjects.push(hero); }dan akhirnya, tambah fungsi
drawGameObjects()untuk memulakan lukisan:function drawGameObjects(ctx) { gameObjects.forEach(go => go.draw(ctx)); }Musuh anda sepatutnya mula maju ke arah kapal angkasa hero anda!
Cabaran Ejen GitHub Copilot 🚀
Berikut adalah cabaran yang akan meningkatkan kemasan permainan anda: menambah sempadan dan kawalan yang lancar. Pada masa ini, hero anda boleh terbang keluar dari skrin, dan pergerakan mungkin terasa terputus-putus.
Misi Anda: Jadikan kapal angkasa anda terasa lebih realistik dengan melaksanakan sempadan skrin dan pergerakan yang lancar. Ini serupa dengan bagaimana sistem kawalan penerbangan NASA menghalang kapal angkasa daripada melebihi parameter operasi yang selamat.
Apa yang perlu dibina: Cipta sistem yang memastikan kapal angkasa hero anda kekal di skrin, dan buat kawalan terasa lancar. Apabila pemain menekan kekunci anak panah, kapal itu sepatutnya meluncur secara berterusan dan bukannya bergerak dalam langkah diskret. Pertimbangkan untuk menambah maklum balas visual apabila kapal mencapai sempadan skrin – mungkin kesan halus untuk menunjukkan tepi kawasan permainan.
Ketahui lebih lanjut tentang mod ejen di sini.
🚀 Cabaran
Pengorganisasian kod menjadi semakin penting apabila projek berkembang. Anda mungkin telah perasan fail anda menjadi sesak dengan fungsi, pembolehubah, dan kelas yang bercampur-campur. Ini mengingatkan saya kepada bagaimana jurutera yang mengatur kod misi Apollo perlu mencipta sistem yang jelas dan boleh diselenggara yang boleh digunakan oleh pelbagai pasukan secara serentak.
Misi Anda: Fikir seperti seorang arkitek perisian. Bagaimana anda akan mengatur kod anda supaya enam bulan dari sekarang, anda (atau rakan sepasukan) boleh memahami apa yang sedang berlaku? Walaupun semuanya kekal dalam satu fail buat masa ini, anda boleh mencipta pengorganisasian yang lebih baik:
- Mengelompokkan fungsi berkaitan bersama dengan tajuk komen yang jelas
- Memisahkan kebimbangan - simpan logik permainan berasingan daripada rendering
- Menggunakan konvensi penamaan yang konsisten untuk pembolehubah dan fungsi
- Mencipta modul atau namespace untuk mengatur aspek permainan yang berbeza
- Menambah dokumentasi yang menerangkan tujuan setiap bahagian utama
Soalan refleksi:
- Bahagian mana dalam kod anda yang paling sukar difahami apabila anda kembali kepadanya?
- Bagaimana anda boleh mengatur kod anda supaya lebih mudah untuk orang lain menyumbang?
- Apa yang akan berlaku jika anda ingin menambah ciri baru seperti power-up atau jenis musuh yang berbeza?
Kuiz Selepas Kuliah
Ulasan & Kajian Kendiri
Kami telah membina semuanya dari awal, yang sangat bagus untuk pembelajaran, tetapi berikut adalah rahsia kecil – terdapat beberapa kerangka kerja JavaScript yang hebat di luar sana yang boleh menangani banyak kerja berat untuk anda. Setelah anda merasa selesa dengan asas yang telah kami bahas, ia berbaloi untuk meneroka apa yang tersedia.
Fikirkan kerangka kerja seperti mempunyai kotak alat yang lengkap dan bukannya membuat setiap alat secara manual. Mereka boleh menyelesaikan banyak cabaran pengorganisasian kod yang telah kita bincangkan, serta menawarkan ciri-ciri yang akan mengambil masa berminggu-minggu untuk dibina sendiri.
Perkara yang berbaloi untuk diteroka:
- Bagaimana enjin permainan mengatur kod – anda akan kagum dengan corak pintar yang mereka gunakan
- Trik prestasi untuk membuat permainan kanvas berjalan dengan lancar
- Ciri-ciri JavaScript moden yang boleh menjadikan kod anda lebih bersih dan mudah diselenggara
- Pendekatan yang berbeza untuk menguruskan objek permainan dan hubungan mereka
🎯 Garis Masa Penguasaan Animasi Permainan Anda
timeline
title Game Animation & Interaction Learning Progression
section Movement Fundamentals (20 minutes)
Animation Principles: Frame-based animation
: Position updates
: Coordinate systems
: Smooth movement
section Event Systems (25 minutes)
User Input: Keyboard event handling
: Default behavior prevention
: Event object properties
: Window-level listening
section Game Architecture (30 minutes)
Object Design: Inheritance patterns
: Base class creation
: Specialized behaviors
: Polymorphic interfaces
section Communication Patterns (35 minutes)
Pub/Sub Implementation: Event emitters
: Message constants
: Loose coupling
: System integration
section Game Loop Mastery (40 minutes)
Real-time Systems: Frame rate control
: Update/render cycle
: State management
: Performance optimization
section Advanced Techniques (45 minutes)
Professional Features: Collision detection
: Physics simulation
: State machines
: Component systems
section Game Engine Concepts (1 week)
Framework Understanding: Entity-component systems
: Scene graphs
: Asset pipelines
: Performance profiling
section Production Skills (1 month)
Professional Development: Code organization
: Team collaboration
: Testing strategies
: Deployment optimization
🛠️ Ringkasan Alat Pembangunan Permainan Anda
Selepas menyelesaikan pelajaran ini, anda kini telah menguasai:
- Prinsip Animasi: Pergerakan berasaskan bingkai dan peralihan yang lancar
- Pengaturcaraan Berasaskan Acara: Pengendalian input papan kekunci dengan pengurusan acara yang betul
- Reka Bentuk Berorientasikan Objek: Hierarki pewarisan dan antara muka polimorfik
- Corak Komunikasi: Seni bina pub/sub untuk kod yang boleh diselenggara
- Seni Bina Gelung Permainan: Kemas kini masa nyata dan kitaran rendering
- Sistem Input: Pemetaan kawalan pengguna dengan pencegahan tingkah laku lalai
- Pengurusan Aset: Pemuatan sprite dan teknik rendering yang cekap
⚡ Apa yang Boleh Anda Lakukan dalam 5 Minit Seterusnya
- Buka konsol pelayar dan cuba
addEventListener('keydown', console.log)untuk melihat acara papan kekunci - Cipta elemen div ringkas dan gerakkannya menggunakan kekunci anak panah
- Bereksperimen dengan
setIntervaluntuk mencipta pergerakan berterusan - Cuba mencegah tingkah laku lalai dengan
event.preventDefault()
🎯 Apa yang Boleh Anda Capai Dalam Jam Ini
- Lengkapkan kuiz selepas pelajaran dan fahami pengaturcaraan berasaskan acara
- Bina kapal angkasa hero yang bergerak dengan kawalan papan kekunci penuh
- Laksanakan corak pergerakan musuh yang lancar
- Tambah sempadan untuk menghalang objek permainan daripada meninggalkan skrin
- Cipta pengesanan perlanggaran asas antara objek permainan
📅 Perjalanan Animasi Anda Sepanjang Minggu
- Lengkapkan permainan angkasa penuh dengan pergerakan dan interaksi yang kemas
- Tambah corak pergerakan lanjutan seperti lengkung, pecutan, dan fizik
- Laksanakan peralihan yang lancar dan fungsi easing
- Cipta kesan partikel dan sistem maklum balas visual
- Optimumkan prestasi permainan untuk permainan 60fps yang lancar
- Tambah kawalan sentuhan mudah alih dan reka bentuk responsif
🌟 Pembangunan Interaktif Anda Sepanjang Bulan
- Bina aplikasi interaktif yang kompleks dengan sistem animasi lanjutan
- Pelajari perpustakaan animasi seperti GSAP atau cipta enjin animasi anda sendiri
- Menyumbang kepada projek pembangunan permainan dan animasi sumber terbuka
- Kuasai pengoptimuman prestasi untuk aplikasi intensif grafik
- Cipta kandungan pendidikan tentang pembangunan permainan dan animasi
- Bina portfolio yang mempamerkan kemahiran pengaturcaraan interaktif yang maju
Aplikasi Dunia Sebenar: Kemahiran animasi permainan anda digunakan secara langsung untuk:
- Aplikasi Web Interaktif: Papan pemuka dinamik dan antara muka masa nyata
- Visualisasi Data: Carta animasi dan grafik interaktif
- Perisian Pendidikan: Simulasi interaktif dan alat pembelajaran
- Pembangunan Mudah Alih: Permainan berasaskan sentuhan dan pengendalian isyarat
- Aplikasi Desktop: Aplikasi Electron dengan animasi yang lancar
- Animasi Web: Perpustakaan animasi CSS dan JavaScript
Kemahiran Profesional Diperoleh: Anda kini boleh:
- Mereka Bentuk sistem berasaskan acara yang berskala dengan kerumitan
- Melaksanakan animasi yang lancar menggunakan prinsip matematik
- Menyahpepijat sistem interaksi kompleks menggunakan alat pembangun pelayar
- Mengoptimumkan prestasi permainan untuk pelbagai peranti dan pelayar
- Mereka Bentuk struktur kod yang boleh diselenggara menggunakan corak yang terbukti
Konsep Pembangunan Permainan Dikuasai:
- Pengurusan Kadar Bingkai: Memahami FPS dan kawalan masa
- Pengendalian Input: Sistem papan kekunci dan acara merentas platform
- Kitaran Hayat Objek: Corak penciptaan, kemas kini, dan pemusnahan
- Penyelarasan Keadaan: Menjaga keadaan permainan konsisten merentas bingkai
- Seni Bina Acara: Komunikasi yang tidak bergantung antara sistem permainan
Tahap Seterusnya: Anda bersedia untuk menambah pengesanan perlanggaran, sistem pemarkahan, kesan bunyi, atau meneroka kerangka kerja permainan moden seperti Phaser atau Three.js!
🌟 Pencapaian Terkunci: Anda telah membina sistem permainan interaktif lengkap dengan corak seni bina profesional!
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.