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/translations/id/6-space-game/3-moving-elements-around/README.md

37 KiB

Membangun Game Luar Angkasa Bagian 3: Menambahkan Gerakan

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

Pikirkan tentang game favoritmu yang membuatnya menarik bukan hanya grafis yang indah, tetapi juga cara semuanya bergerak dan merespons tindakanmu. Saat ini, game luar angkasamu seperti lukisan yang indah, tetapi kita akan menambahkan gerakan yang membuatnya hidup.

Ketika insinyur NASA memprogram komputer panduan untuk misi Apollo, mereka menghadapi tantangan serupa: bagaimana membuat pesawat luar angkasa merespons input pilot sambil secara otomatis menjaga koreksi jalur? Prinsip yang akan kita pelajari hari ini mencerminkan konsep yang sama mengelola gerakan yang dikendalikan pemain bersama perilaku sistem otomatis.

Dalam pelajaran ini, kamu akan belajar cara membuat pesawat luar angkasa meluncur di layar, merespons perintah pemain, dan menciptakan pola gerakan yang halus. Kita akan memecah semuanya menjadi konsep yang mudah dipahami yang saling membangun secara alami.

Pada akhirnya, pemain akan dapat menerbangkan kapal pahlawan mereka di layar sementara kapal musuh berpatroli di atas. Lebih penting lagi, kamu akan memahami prinsip inti yang mendukung sistem gerakan dalam game.

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

Kuis Pra-Pelajaran

Kuis pra-pelajaran

Memahami Gerakan dalam Game

Game menjadi hidup ketika objek mulai bergerak, dan secara fundamental ada dua cara hal ini terjadi:

  • Gerakan yang dikendalikan pemain: Ketika kamu menekan tombol atau mengklik mouse, sesuatu bergerak. Ini adalah hubungan langsung antara kamu dan dunia game.
  • Gerakan otomatis: Ketika game itu sendiri memutuskan untuk menggerakkan objek seperti kapal musuh yang harus berpatroli di layar meskipun kamu tidak melakukan apa-apa.

Membuat objek bergerak di layar komputer lebih sederhana dari yang kamu pikirkan. Ingat koordinat x dan y dari kelas matematika? Itulah yang kita gunakan di sini. Ketika Galileo melacak bulan Jupiter pada tahun 1610, dia pada dasarnya melakukan hal yang sama memplot posisi dari waktu ke waktu untuk memahami pola gerakan.

Menggerakkan objek di layar seperti membuat animasi buku flip kamu perlu mengikuti tiga langkah sederhana 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
  1. Perbarui posisi Ubah di mana objekmu seharusnya berada (misalnya pindahkan 5 piksel ke kanan)
  2. Hapus frame lama Bersihkan layar agar tidak terlihat jejak bayangan di mana-mana
  3. Gambar frame baru Tempatkan objekmu di posisi barunya

Lakukan ini dengan cukup cepat, dan boom! Kamu mendapatkan gerakan halus yang terasa alami bagi pemain.

Berikut adalah contoh kode:

// 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 kode ini:

  • Memperbarui koordinat x hero sebanyak 5 piksel untuk menggerakkannya secara horizontal
  • Membersihkan seluruh area kanvas untuk menghapus frame sebelumnya
  • Mengisi kanvas dengan warna latar belakang hitam
  • Menggambar ulang gambar hero di posisi barunya

Bisakah kamu memikirkan alasan mengapa menggambar ulang hero beberapa frame per detik dapat menyebabkan biaya kinerja? Baca tentang alternatif untuk pola ini.

Menangani Event Keyboard

Di sinilah kita menghubungkan input pemain dengan aksi dalam game. Ketika seseorang menekan tombol spasi untuk menembakkan laser atau mengetuk tombol panah untuk menghindari asteroid, game kamu perlu mendeteksi dan merespons input tersebut.

Event keyboard terjadi di tingkat window, artinya seluruh jendela browsermu mendengarkan penekanan tombol tersebut. Klik mouse, di sisi lain, dapat diikat ke elemen tertentu (seperti mengklik tombol). Untuk game luar angkasa kita, kita akan fokus pada kontrol keyboard karena itulah yang memberikan pemain nuansa arcade klasik.

Ini mengingatkan saya pada bagaimana operator telegraf di tahun 1800-an harus menerjemahkan input kode morse menjadi pesan yang bermakna kita melakukan sesuatu yang serupa, menerjemahkan penekanan tombol menjadi perintah game.

Untuk menangani sebuah event, kamu perlu menggunakan metode addEventListener() pada window dan memberikannya dua parameter input. Parameter pertama adalah nama event, misalnya keyup. Parameter kedua adalah fungsi yang harus dipanggil sebagai hasil dari event yang terjadi.

Berikut adalah contohnya:

window.addEventListener('keyup', (evt) => {
  // evt.key = string representation of the key
  if (evt.key === 'ArrowUp') {
    // do something
  }
});

Penjelasan apa yang terjadi di sini:

  • Mendengarkan event keyboard di seluruh window
  • Menangkap objek event yang berisi informasi tentang tombol mana yang ditekan
  • Memeriksa apakah tombol yang ditekan cocok dengan tombol tertentu (dalam hal ini, tombol panah atas)
  • Menjalankan kode ketika kondisi terpenuhi

Untuk event tombol, ada dua properti pada event yang dapat kamu gunakan untuk melihat tombol mana yang ditekan:

  • key - ini adalah representasi string dari tombol yang ditekan, misalnya 'ArrowUp'
  • keyCode - ini adalah representasi angka, misalnya 37, yang sesuai dengan ArrowLeft

Manipulasi event tombol berguna di luar pengembangan game. Apa kegunaan lain yang bisa kamu pikirkan 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

Tombol Khusus: Perhatian!

Beberapa tombol memiliki perilaku bawaan browser yang dapat mengganggu game kamu. Tombol panah menggulir halaman dan tombol spasi melompat ke bawah perilaku yang tidak kamu inginkan saat seseorang mencoba mengendalikan pesawat luar angkasa mereka.

Kita dapat mencegah perilaku bawaan ini dan membiarkan game kita menangani input tersebut. Ini mirip dengan bagaimana programmer komputer awal harus menimpa interupsi sistem untuk menciptakan perilaku khusus kita hanya melakukannya di tingkat browser. Berikut 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 kode pencegahan ini:

  • Memeriksa kode tombol tertentu yang mungkin menyebabkan perilaku browser yang tidak diinginkan
  • Mencegah aksi bawaan browser untuk tombol panah dan tombol spasi
  • Mengizinkan tombol lain berfungsi normal
  • Menggunakan e.preventDefault() untuk menghentikan perilaku bawaan browser

🔄 Pengecekan Pedagogis

Pemahaman Penanganan Event: Sebelum beralih ke gerakan otomatis, pastikan kamu dapat:

  • Menjelaskan perbedaan antara event keydown dan keyup
  • Memahami mengapa kita mencegah perilaku bawaan browser
  • Menggambarkan bagaimana event listener menghubungkan input pengguna dengan logika game
  • Mengidentifikasi tombol mana yang mungkin mengganggu kontrol game

Tes Cepat Diri Sendiri: Apa yang akan terjadi jika kamu tidak mencegah perilaku bawaan untuk tombol panah? Jawaban: Browser akan menggulir halaman, mengganggu gerakan dalam game

Arsitektur Sistem Event: Kamu sekarang memahami:

  • Pendengaran tingkat window: Menangkap event di tingkat browser
  • Properti objek event: String key vs angka keyCode
  • Pencegahan bawaan: Menghentikan perilaku browser yang tidak diinginkan
  • Logika kondisional: Merespons kombinasi tombol tertentu

Gerakan yang Diinduksi Game

Sekarang mari kita bicara tentang objek yang bergerak tanpa input pemain. Pikirkan tentang kapal musuh yang meluncur di layar, peluru yang terbang dalam garis lurus, atau awan yang melayang di latar belakang. Gerakan otomatis ini membuat dunia game kamu terasa hidup bahkan ketika tidak ada yang menyentuh kontrol.

Kita menggunakan timer bawaan JavaScript untuk memperbarui posisi pada interval yang teratur. Konsep ini mirip dengan cara kerja jam pendulum mekanisme reguler yang memicu aksi yang konsisten dan teratur. Berikut betapa sederhananya ini:

const id = setInterval(() => {
  // Move the enemy on the y axis
  enemy.y += 10;
}, 100);

Apa yang dilakukan kode gerakan ini:

  • Membuat timer yang berjalan setiap 100 milidetik
  • Memperbarui koordinat y musuh sebanyak 10 piksel setiap kali
  • Menyimpan ID interval sehingga kita dapat menghentikannya nanti jika diperlukan
  • Menggerakkan musuh ke bawah layar secara otomatis

Loop Game

Berikut adalah konsep yang mengikat semuanya loop game. Jika game kamu adalah sebuah film, loop game akan menjadi proyektor film, menampilkan frame demi frame dengan sangat cepat sehingga semuanya tampak bergerak dengan mulus.

Setiap game memiliki salah satu loop ini yang berjalan di belakang layar. Ini adalah fungsi yang memperbarui semua objek game, menggambar ulang layar, dan mengulangi proses ini secara terus-menerus. Ini melacak hero kamu, semua musuh, peluru yang terbang seluruh keadaan game.

Konsep ini mengingatkan saya pada bagaimana animator film awal seperti Walt Disney harus menggambar ulang karakter frame demi frame untuk menciptakan ilusi gerakan. Kita melakukan hal yang sama, hanya saja dengan kode, bukan pensil.

Berikut adalah seperti apa loop game biasanya, diekspresikan dalam kode:

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 loop game:

  • Membersihkan seluruh kanvas untuk menghapus frame sebelumnya
  • Mengisi latar belakang dengan warna solid
  • Menggambar semua objek game di posisi mereka saat ini
  • Mengulangi proses ini setiap 200 milidetik untuk menciptakan animasi yang halus
  • Mengelola frame rate dengan mengontrol waktu interval

Melanjutkan Game Luar Angkasa

Sekarang kita akan menambahkan gerakan ke adegan statis yang telah kamu buat sebelumnya. Kita akan mengubahnya dari tangkapan layar menjadi pengalaman interaktif. Kita akan bekerja melalui ini langkah demi langkah untuk memastikan setiap bagian saling membangun.

Ambil kode dari tempat kita berhenti di pelajaran sebelumnya (atau mulai dengan kode di folder Part II- starter jika kamu membutuhkan awal yang baru).

Inilah yang akan kita bangun hari ini:

  • Kontrol hero: Tombol panah akan mengendalikan pesawat luar angkasamu di layar
  • Gerakan musuh: Kapal alien itu akan mulai bergerak maju

Mari kita mulai mengimplementasikan fitur-fitur ini.

Langkah yang Direkomendasikan

Temukan file yang telah dibuat untukmu di sub folder your-work. Folder tersebut harus berisi:

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

Mulailah proyekmu di folder your-work dengan mengetik:

cd your-work
npm start

Apa yang dilakukan perintah ini:

  • Menavigasi ke direktori proyekmu
  • Memulai HTTP Server di alamat http://localhost:5000
  • Melayani file game-mu sehingga kamu dapat mengujinya di browser

Perintah di atas akan memulai HTTP Server di alamat http://localhost:5000. Buka browser dan masukkan alamat tersebut, saat ini seharusnya menampilkan hero dan semua musuh; tidak ada yang bergerak - belum!

Tambahkan kode

  1. Tambahkan objek khusus untuk hero, enemy, dan game object, mereka harus memiliki properti x dan y. (Ingat bagian tentang Inheritance atau composition).

    PETUNJUK game object harus menjadi objek yang memiliki x dan y serta kemampuan untuk menggambar dirinya sendiri ke kanvas.

    Tip: Mulailah dengan menambahkan kelas baru GameObject dengan konstruktor yang ditentukan seperti di bawah ini, lalu gambarlah 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 dasar ini:

    • Mendefinisikan properti umum yang dimiliki semua objek game (posisi, ukuran, gambar)
    • Menyertakan flag dead untuk melacak apakah objek harus dihapus
    • Menyediakan metode draw() yang merender objek di kanvas
    • Mengatur nilai default untuk semua properti yang dapat ditimpa oleh kelas turunan
    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, perpanjang GameObject ini untuk membuat Hero dan Enemy:

    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-kelas ini:

    • Mewarisi dari GameObject menggunakan kata kunci extends
    • Memanggil konstruktor induk dengan super(x, y)
    • Mengatur dimensi dan properti spesifik untuk setiap tipe objek
    • Mengimplementasikan gerakan otomatis untuk musuh menggunakan setInterval()
  2. Tambahkan penangan event tombol untuk menangani navigasi tombol (gerakkan hero ke atas/bawah kiri/kanan)

    INGAT ini adalah sistem kartesian, kiri atas adalah 0,0. Juga ingat untuk menambahkan kode untuk menghentikan perilaku bawaan

    Tip: Buat fungsi onKeyDown dan lampirkan ke window:

    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 penangan event ini:

    • Mendengarkan event keydown di seluruh window
    • Mencatat kode tombol untuk membantumu memeriksa tombol mana yang ditekan
    • Mencegah perilaku bawaan browser untuk tombol panah dan tombol spasi
    • Mengizinkan tombol lain berfungsi normal

    Periksa konsol browsermu pada titik ini, dan lihat penekanan tombol yang dicatat.

  3. Implementasikan Pola Pub-Sub, ini akan menjaga kode kamu tetap bersih saat kamu mengikuti bagian-bagian berikutnya.

    Pola Publish-Subscribe membantu mengorganisasi kode kamu dengan memisahkan deteksi event dari penanganan event. Ini membuat kode kamu lebih modular dan mudah dipelihara.

    Untuk melakukan bagian terakhir ini, kamu dapat:

    1. Tambahkan pendengar event pada window:

      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 sistem event ini:

    • Mendeteksi input keyboard dan mengonversinya menjadi event game khusus
    • Memisahkan deteksi input dari logika game
    • Mempermudah perubahan kontrol nanti tanpa memengaruhi kode game
    • Mengizinkan beberapa sistem merespons 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
    
    1. Buat kelas EventEmitter untuk mempublikasikan dan berlangganan pesan:

      class EventEmitter {
        constructor() {
          this.listeners = {};
        }
      
        on(message, listener) {
          if (!this.listeners[message]) {
            this.listeners[message] = [];
          }
          this.listeners[message].push(listener);
        }
      
      
    2. Tambahkan konstanta dan atur 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 pengaturan:

    • Mendefinisikan konstanta pesan untuk menghindari kesalahan ketik dan mempermudah refactoring
    • Mendeklarasikan variabel untuk gambar, konteks kanvas, dan status game
    • Membuat event emitter global untuk sistem pub-sub
    • Menginisialisasi array untuk menyimpan semua objek permainan
    1. Inisialisasi 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;
        });
      
      
  4. Siapkan game loop

    Refactor fungsi window.onload untuk menginisialisasi permainan dan mengatur game loop dengan interval yang baik. Anda juga akan menambahkan sinar 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 pengaturan permainan:

    • Menunggu halaman selesai dimuat sebelum memulai
    • Mendapatkan elemen canvas dan konteks rendering 2D-nya
    • Memuat semua aset gambar secara asinkron menggunakan await
    • Memulai game loop dengan interval 100ms (10 FPS)
    • Membersihkan dan menggambar ulang seluruh layar setiap frame
  5. Tambahkan kode untuk menggerakkan musuh pada interval tertentu

    Refactor fungsi createEnemies() untuk membuat musuh dan menambahkannya ke kelas gameObjects 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 pembuatan musuh:

    • Menghitung posisi untuk memusatkan musuh di layar
    • Membuat grid musuh menggunakan loop bersarang
    • Menetapkan gambar musuh ke setiap objek musuh
    • Menambahkan setiap musuh ke array objek permainan global

    dan tambahkan fungsi createHero() untuk melakukan proses serupa untuk hero.

    function createHero() {
      hero = new Hero(
        canvas.width / 2 - 45,
        canvas.height - canvas.height / 4
      );
      hero.img = heroImg;
      gameObjects.push(hero);
    }
    

    Apa yang dilakukan pembuatan hero:

    • Memposisikan hero di bagian bawah tengah layar
    • Menetapkan gambar hero ke objek hero
    • Menambahkan hero ke array objek permainan untuk dirender

    dan terakhir, tambahkan fungsi drawGameObjects() untuk memulai proses menggambar:

    function drawGameObjects(ctx) {
      gameObjects.forEach(go => go.draw(ctx));
    }
    

    Memahami fungsi menggambar:

    • Mengiterasi semua objek permainan dalam array
    • Memanggil metode draw() pada setiap objek
    • Melewatkan konteks canvas sehingga objek dapat merender dirinya sendiri

    🔄 Pengecekan Pedagogis

    Pemahaman Sistem Permainan Lengkap: Verifikasi penguasaan Anda terhadap seluruh arsitektur:

    • Bagaimana pewarisan memungkinkan Hero dan Enemy berbagi properti GameObject yang sama?
    • Mengapa pola pub/sub membuat kode Anda lebih mudah dipelihara?
    • Apa peran game loop dalam menciptakan animasi yang mulus?
    • Bagaimana event listener menghubungkan input pengguna dengan perilaku objek permainan?

    Integrasi Sistem: Permainan Anda sekarang menunjukkan:

    • Desain Berorientasi Objek: Kelas dasar dengan pewarisan khusus
    • Arsitektur Berbasis Event: Pola pub/sub untuk coupling yang longgar
    • Kerangka Animasi: Game loop dengan pembaruan frame yang konsisten
    • Penanganan Input: Event keyboard dengan pencegahan default
    • Manajemen Aset: Pemuatan gambar dan rendering sprite

    Pola Profesional: Anda telah menerapkan:

    • Pemisahan Tugas: Input, logika, dan rendering terpisah
    • Polimorfisme: Semua objek permainan berbagi antarmuka menggambar yang sama
    • Pengiriman Pesan: Komunikasi bersih antara komponen
    • Manajemen Sumber Daya: Penanganan sprite dan animasi yang efisien

    Musuh Anda harus mulai maju menuju pesawat luar 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 terakhir, tambahkan fungsi drawGameObjects() untuk memulai proses menggambar:

    function drawGameObjects(ctx) {
      gameObjects.forEach(go => go.draw(ctx));
    }
    

    Musuh Anda harus mulai maju menuju pesawat luar angkasa hero Anda!


Tantangan GitHub Copilot Agent 🚀

Berikut tantangan yang akan meningkatkan kualitas permainan Anda: menambahkan batas layar dan kontrol yang halus. Saat ini, hero Anda bisa terbang keluar layar, dan gerakannya mungkin terasa patah-patah.

Misi Anda: Buat pesawat luar angkasa Anda terasa lebih realistis dengan menerapkan batas layar dan gerakan yang mulus. Ini mirip dengan bagaimana sistem kontrol penerbangan NASA mencegah pesawat luar angkasa melebihi parameter operasional yang aman.

Apa yang harus dibuat: Buat sistem yang menjaga pesawat luar angkasa hero tetap di layar, dan buat kontrol terasa halus. Ketika pemain menahan tombol panah, pesawat harus meluncur terus-menerus daripada bergerak dalam langkah-langkah diskrit. Pertimbangkan untuk menambahkan umpan balik visual saat pesawat mencapai batas layar mungkin efek halus untuk menunjukkan tepi area permainan.

Pelajari lebih lanjut tentang mode agen di sini.

🚀 Tantangan

Organisasi kode menjadi semakin penting seiring pertumbuhan proyek. Anda mungkin telah memperhatikan file Anda menjadi penuh dengan fungsi, variabel, dan kelas yang bercampur aduk. Ini mengingatkan saya pada bagaimana para insinyur yang mengorganisasi kode misi Apollo harus menciptakan sistem yang jelas dan dapat dipelihara sehingga banyak tim dapat bekerja secara bersamaan.

Misi Anda: Berpikir seperti seorang arsitek perangkat lunak. Bagaimana Anda akan mengorganisasi kode Anda sehingga enam bulan dari sekarang, Anda (atau rekan tim) dapat memahami apa yang sedang terjadi? Bahkan jika semuanya tetap dalam satu file untuk saat ini, Anda dapat menciptakan organisasi yang lebih baik:

  • Mengelompokkan fungsi terkait dengan header komentar yang jelas
  • Memisahkan tugas - menjaga logika permainan terpisah dari rendering
  • Menggunakan konvensi penamaan yang konsisten untuk variabel dan fungsi
  • Membuat modul atau namespace untuk mengorganisasi aspek-aspek berbeda dari permainan Anda
  • Menambahkan dokumentasi yang menjelaskan tujuan setiap bagian utama

Pertanyaan refleksi:

  • Bagian mana dari kode Anda yang paling sulit dipahami saat Anda kembali ke sana?
  • Bagaimana Anda dapat mengorganisasi kode Anda agar lebih mudah bagi orang lain untuk berkontribusi?
  • Apa yang akan terjadi jika Anda ingin menambahkan fitur baru seperti power-up atau jenis musuh yang berbeda?

Kuis Pasca-Pelajaran

Kuis pasca-pelajaran

Tinjauan & Studi Mandiri

Kami telah membangun semuanya dari awal, yang sangat bagus untuk pembelajaran, tetapi ada sedikit rahasia ada beberapa kerangka kerja JavaScript yang luar biasa di luar sana yang dapat menangani banyak pekerjaan berat untuk Anda. Setelah Anda merasa nyaman dengan dasar-dasar yang telah kita bahas, ada baiknya mengeksplorasi apa yang tersedia.

Pikirkan kerangka kerja seperti memiliki kotak alat yang lengkap daripada membuat setiap alat secara manual. Mereka dapat menyelesaikan banyak tantangan organisasi kode yang kita bicarakan, plus menawarkan fitur yang akan memakan waktu berminggu-minggu untuk dibangun sendiri.

Hal-hal yang layak dieksplorasi:

  • Bagaimana mesin permainan mengorganisasi kode Anda akan kagum dengan pola cerdas yang mereka gunakan
  • Trik performa untuk membuat permainan canvas berjalan sangat mulus
  • Fitur JavaScript modern yang dapat membuat kode Anda lebih bersih dan mudah dipelihara
  • Pendekatan berbeda untuk mengelola objek permainan dan hubungannya

🎯 Garis Waktu 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 Toolkit Pengembangan Permainan Anda

Setelah menyelesaikan pelajaran ini, Anda sekarang telah menguasai:

  • Prinsip Animasi: Gerakan berbasis frame dan transisi yang mulus
  • Pemrograman Berbasis Event: Penanganan input keyboard dengan manajemen event yang tepat
  • Desain Berorientasi Objek: Hierarki pewarisan dan antarmuka polimorfik
  • Pola Komunikasi: Arsitektur pub/sub untuk kode yang dapat dipelihara
  • Arsitektur Game Loop: Pembaruan real-time dan siklus rendering
  • Sistem Input: Pemetaan kontrol pengguna dengan pencegahan perilaku default
  • Manajemen Aset: Pemuatan sprite dan teknik rendering yang efisien

Apa yang Bisa Anda Lakukan dalam 5 Menit Berikutnya

  • Buka konsol browser dan coba addEventListener('keydown', console.log) untuk melihat event keyboard
  • Buat elemen div sederhana dan gerakkan menggunakan tombol panah
  • Bereksperimen dengan setInterval untuk menciptakan gerakan terus-menerus
  • Coba mencegah perilaku default dengan event.preventDefault()

🎯 Apa yang Bisa Anda Capai dalam Satu Jam

  • Selesaikan kuis pasca-pelajaran dan pahami pemrograman berbasis event
  • Bangun pesawat luar angkasa hero yang bergerak dengan kontrol keyboard penuh
  • Terapkan pola gerakan musuh yang mulus
  • Tambahkan batas untuk mencegah objek permainan keluar dari layar
  • Buat deteksi tabrakan dasar antara objek permainan

📅 Perjalanan Animasi Anda Selama Seminggu

  • Selesaikan permainan luar angkasa lengkap dengan gerakan dan interaksi yang halus
  • Tambahkan pola gerakan canggih seperti kurva, akselerasi, dan fisika
  • Terapkan transisi yang mulus dan fungsi easing
  • Buat efek partikel dan sistem umpan balik visual
  • Optimalkan performa permainan untuk gameplay 60fps yang mulus
  • Tambahkan kontrol sentuh untuk perangkat mobile dan desain responsif

🌟 Pengembangan Interaktif Anda Selama Sebulan

  • Bangun aplikasi interaktif kompleks dengan sistem animasi canggih
  • Pelajari pustaka animasi seperti GSAP atau buat mesin animasi Anda sendiri
  • Berkontribusi pada proyek pengembangan permainan dan animasi open source
  • Kuasai optimasi performa untuk aplikasi grafis intensif
  • Buat konten edukasi tentang pengembangan permainan dan animasi
  • Bangun portofolio yang menampilkan keterampilan pemrograman interaktif tingkat lanjut

Aplikasi Dunia Nyata: Keterampilan animasi permainan Anda langsung berlaku untuk:

  • Aplikasi Web Interaktif: Dasbor dinamis dan antarmuka real-time
  • Visualisasi Data: Grafik animasi dan grafik interaktif
  • Perangkat Lunak Pendidikan: Simulasi interaktif dan alat pembelajaran
  • Pengembangan Mobile: Permainan berbasis sentuhan dan penanganan gestur
  • Aplikasi Desktop: Aplikasi Electron dengan animasi yang mulus
  • Animasi Web: Pustaka animasi CSS dan JavaScript

Keterampilan Profesional yang Diperoleh: Anda sekarang dapat:

  • Merancang sistem berbasis event yang skalabel dengan kompleksitas
  • Menerapkan animasi yang mulus menggunakan prinsip matematika
  • Mendiagnosis sistem interaksi kompleks menggunakan alat pengembang browser
  • Mengoptimalkan performa permainan untuk berbagai perangkat dan browser
  • Merancang struktur kode yang dapat dipelihara menggunakan pola yang terbukti

Konsep Pengembangan Permainan yang Dikuasai:

  • Manajemen Frame Rate: Memahami FPS dan kontrol waktu
  • Penanganan Input: Sistem keyboard dan event lintas platform
  • Siklus Objek: Pola pembuatan, pembaruan, dan penghancuran
  • Sinkronisasi Status: Menjaga konsistensi status permainan di setiap frame
  • Arsitektur Event: Komunikasi yang terpisah antara sistem permainan

Tingkat Selanjutnya: Anda siap menambahkan deteksi tabrakan, sistem skor, efek suara, atau mengeksplorasi kerangka kerja permainan modern seperti Phaser atau Three.js!

🌟 Pencapaian Terkunci: Anda telah membangun sistem permainan interaktif lengkap dengan pola arsitektur profesional!

Tugas

Komentari kode Anda


Penafian:
Dokumen ini telah diterjemahkan menggunakan layanan penerjemahan AI Co-op Translator. Meskipun kami berupaya 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 penting, disarankan menggunakan jasa penerjemahan manusia profesional. Kami tidak bertanggung jawab atas kesalahpahaman atau interpretasi yang keliru yang timbul dari penggunaan terjemahan ini.