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/mo/6-space-game/1-introduction/README.md

25 KiB

建立太空遊戲第一部分:介紹

journey
    title Your Game Development Journey
    section Foundation
      Learn game architecture: 3: Student
      Understand inheritance: 4: Student
      Explore composition: 4: Student
    section Communication
      Build pub/sub system: 4: Student
      Design event flow: 5: Student
      Connect components: 5: Student
    section Application
      Create game objects: 5: Student
      Implement patterns: 5: Student
      Plan game structure: 5: Student

太空遊戲動畫展示遊戲玩法

就像 NASA 的任務控制在太空發射期間協調多個系統一樣,我們將建立一個太空遊戲,展示程式的不同部分如何無縫協作。在創建一個實際可以玩的遊戲的同時,您將學習適用於任何軟體專案的基本程式設計概念。

我們將探討組織程式碼的兩種基本方法:繼承和組合。這些不僅僅是學術概念——它們是從電子遊戲到銀行系統的所有事物的運作模式。我們還將實現一個名為 pub/sub 的通信系統,該系統類似於航天器使用的通信網路,允許不同的組件共享資訊而不產生依賴性。

在本系列結束時,您將了解如何構建可擴展和演化的應用程式——無論您是開發遊戲、網頁應用程式還是其他任何軟體系統。

mindmap
  root((Game Architecture))
    Object Organization
      Inheritance
      Composition
      Class Hierarchies
      Behavior Mixing
    Communication Patterns
      Pub/Sub System
      Event Emitters
      Message Passing
      Loose Coupling
    Game Objects
      Properties (x, y)
      Behaviors (move, collide)
      Lifecycle Management
      State Management
    Design Patterns
      Factory Functions
      Observer Pattern
      Component System
      Event-Driven Architecture
    Scalability
      Modular Design
      Maintainable Code
      Testing Strategies
      Performance Optimization

課前測驗

課前測驗

繼承與組合在遊戲開發中的應用

隨著專案的複雜性增加,程式碼的組織變得至關重要。最初的簡單腳本如果沒有適當的結構,可能會變得難以維護——就像阿波羅任務需要仔細協調數千個組件一樣。

我們將探討組織程式碼的兩種基本方法:繼承和組合。每種方法都有其獨特的優勢,了解這兩者有助於您在不同情況下選擇合適的方法。我們將通過我們的太空遊戲演示這些概念,其中英雄、敵人、增強道具和其他物件必須高效地互動。

最著名的程式設計書籍之一與設計模式有關。

在任何遊戲中,您都會有「遊戲物件」——填充遊戲世界的互動元素。英雄、敵人、增強道具和視覺效果都是遊戲物件。每個物件都使用 xy 值存在於特定的螢幕座標上,類似於在坐標平面上繪製點。

儘管它們在視覺上有所不同,但這些物件通常共享基本行為:

  • 它們存在於某處——每個物件都有 x 和 y 座標,因此遊戲知道在哪裡繪製它
  • 許多物件可以移動——英雄奔跑,敵人追逐,子彈在螢幕上飛行
  • 它們有壽命——有些物件會永遠存在,其他物件(如爆炸)會短暫出現然後消失
  • 它們會對事物做出反應——當物件碰撞時,增強道具被收集,生命條更新

想想像吃豆人這樣的遊戲。您能否在這個遊戲中識別出上述四種物件類型?

classDiagram
    class GameObject {
        +x: number
        +y: number
        +type: string
        +exists_somewhere()
    }
    
    class MovableObject {
        +moveTo(x, y)
        +can_move_around()
    }
    
    class TemporaryObject {
        +lifespan: number
        +has_lifespan()
    }
    
    class InteractiveObject {
        +onCollision()
        +reacts_to_stuff()
    }
    
    GameObject <|-- MovableObject
    GameObject <|-- TemporaryObject
    GameObject <|-- InteractiveObject
    
    MovableObject <|-- Hero
    MovableObject <|-- Enemy
    MovableObject <|-- Bullet
    
    TemporaryObject <|-- PowerUp
    TemporaryObject <|-- Explosion
    
    InteractiveObject <|-- Collectible
    InteractiveObject <|-- Obstacle

通過程式碼表達行為

現在您已了解遊戲物件共享的常見行為,讓我們來探討如何在 JavaScript 中實現這些行為。您可以通過附加到類或單個物件的方法來表達物件行為,並且有多種方法可供選擇。

基於類的方式

類和繼承提供了一種結構化的方法來組織遊戲物件。就像卡爾·林奈斯開發的分類系統一樣,您從包含常見屬性的基類開始,然後創建繼承這些基礎並添加特定功能的專門類。

繼承是一個重要的概念。了解更多請參考 MDN 的關於繼承的文章

以下是如何使用類和繼承來實現遊戲物件:

// Step 1: Create the base GameObject class
class GameObject {
  constructor(x, y, type) {
    this.x = x;
    this.y = y;
    this.type = type;
  }
}

讓我們一步步分解:

  • 我們正在創建每個遊戲物件都可以使用的基本模板
  • 建構函數保存物件的位置(xy)以及物件的類型
  • 這成為所有遊戲物件構建的基礎
// Step 2: Add movement capability through inheritance
class Movable extends GameObject {
  constructor(x, y, type) {
    super(x, y, type); // Call parent constructor
  }

  // Add the ability to move to a new position
  moveTo(x, y) {
    this.x = x;
    this.y = y;
  }
}

在上面,我們已經:

  • 擴展了 GameObject 類以添加移動功能
  • 使用 super() 調用父建構函數以初始化繼承的屬性
  • 添加了一個 moveTo() 方法來更新物件的位置
// Step 3: Create specific game object types
class Hero extends Movable {
  constructor(x, y) {
    super(x, y, 'Hero'); // Set type automatically
  }
}

class Tree extends GameObject {
  constructor(x, y) {
    super(x, y, 'Tree'); // Trees don't need movement
  }
}

// Step 4: Use your game objects
const hero = new Hero(0, 0);
hero.moveTo(5, 5); // Hero can move!

const tree = new Tree(10, 15);
// tree.moveTo() would cause an error - trees can't move

理解這些概念:

  • 創建繼承適當行為的專門物件類型
  • 展示了繼承如何允許選擇性地包含功能
  • 顯示英雄可以移動,而樹木保持靜止
  • 說明類層次結構如何防止不適當的操作

花幾分鐘重新構想吃豆人中的英雄(例如 Inky、Pinky 或 Blinky並思考如何用 JavaScript 編寫它。

組合方式

組合遵循模組化設計哲學,類似於工程師如何設計具有可互換組件的航天器。與其從父類繼承,不如通過組合特定行為來創建具有所需功能的物件。這種方法提供了靈活性,而不受嚴格的層次結構限制。

// Step 1: Create base behavior objects
const gameObject = {
  x: 0,
  y: 0,
  type: ''
};

const movable = {
  moveTo(x, y) {
    this.x = x;
    this.y = y;
  }
};

這段程式碼的作用:

  • 定義了一個基礎 gameObject,具有位置和類型屬性
  • 創建了一個單獨的 movable 行為物件,具有移動功能
  • 分離關注點,將位置資料和移動邏輯獨立開來
// Step 2: Compose objects by combining behaviors
const movableObject = { ...gameObject, ...movable };

// Step 3: Create factory functions for different object types
function createHero(x, y) {
  return {
    ...movableObject,
    x,
    y,
    type: 'Hero'
  };
}

function createStatic(x, y, type) {
  return {
    ...gameObject,
    x,
    y,
    type
  };
}

在上面,我們已經:

  • 使用展開語法 組合了基礎物件屬性和移動行為
  • 創建了返回自定義物件的工廠函數
  • 啟用了靈活的物件創建,而不受嚴格的類層次結構限制
  • 允許物件擁有其所需的行為
// Step 4: Create and use your composed objects
const hero = createHero(10, 10);
hero.moveTo(5, 5); // Works perfectly!

const tree = createStatic(0, 0, 'Tree');
// tree.moveTo() is undefined - no movement behavior was composed

需要記住的關鍵點:

  • 通過混合行為來組合物件,而不是繼承它們
  • 提供比嚴格的繼承層次結構更大的靈活性
  • 允許物件擁有其所需的功能
  • 使用現代 JavaScript 展開語法進行乾淨的物件組合

**Which Pattern Should You Choose?**

**Which Pattern Should You Choose?**

```mermaid
quadrantChart
    title Code Organization Patterns
    x-axis Simple --> Complex
    y-axis Rigid --> Flexible
    quadrant-1 Advanced Composition
    quadrant-2 Hybrid Approaches
    quadrant-3 Basic Inheritance
    quadrant-4 Modern Composition
    
    Class Inheritance: [0.3, 0.2]
    Interface Implementation: [0.6, 0.4]
    Mixin Patterns: [0.7, 0.7]
    Pure Composition: [0.8, 0.9]
    Factory Functions: [0.5, 0.8]
    Prototype Chain: [0.4, 0.3]

💡 專業提示:這兩種模式在現代 JavaScript 開發中都有其位置。類適用於明確定義的層次結構,而組合在需要最大靈活性時表現出色。

以下是使用每種方法的情況:

  • 選擇繼承,當您有明確的「是某物」關係時(例如,英雄 可移動物件)
  • 選擇組合,當您需要「擁有某物」關係時(例如,英雄 擁有 移動能力)
  • 考慮您的團隊偏好和專案需求
  • 記住您可以在同一應用程式中混合使用這兩種方法

🔄 教學檢查

物件組織理解:在進入通信模式之前,確保您能夠:

  • 解釋繼承和組合的區別
  • 確定何時使用類與工廠函數
  • 理解 super() 關鍵字在繼承中的作用
  • 認識每種方法在遊戲開發中的優勢

快速自測:如何創建一個既能移動又能飛行的飛行敵人?

  • 繼承方式class FlyingEnemy extends Movable
  • 組合方式{ ...movable, ...flyable, ...gameObject }

現實世界的聯繫:這些模式無處不在:

  • React 元件:屬性(組合)與類繼承
  • 遊戲引擎:實體-組件系統使用組合
  • 移動應用UI 框架通常使用繼承層次結構

通信模式Pub/Sub 系統

隨著應用程式變得複雜,管理組件之間的通信變得具有挑戰性。發布-訂閱模式pub/sub使用類似於廣播的原則解決了這個問題——一個發射器可以在不知道誰在聽的情況下到達多個接收器。

想像一下當英雄受到傷害時會發生什麼生命條更新、音效播放、視覺反饋出現。與其將英雄物件直接與這些系統耦合pub/sub 允許英雄廣播「受到傷害」的消息。任何需要響應的系統都可以訂閱此消息類型並做出相應的反應。

Pub/Sub 代表「發布-訂閱」

flowchart TD
    A[Hero Takes Damage] --> B[Publish: HERO_DAMAGED]
    B --> C[Event System]
    
    C --> D[Health Bar Subscriber]
    C --> E[Sound System Subscriber]
    C --> F[Visual Effects Subscriber]
    C --> G[Achievement System Subscriber]
    
    D --> H[Update Health Display]
    E --> I[Play Damage Sound]
    F --> J[Show Red Flash]
    G --> K[Check Survival Achievements]
    
    style A fill:#ffebee
    style B fill:#e1f5fe
    style C fill:#e8f5e8
    style H fill:#fff3e0
    style I fill:#fff3e0
    style J fill:#fff3e0
    style K fill:#fff3e0

理解 Pub/Sub 架構

Pub/Sub 模式使應用程式的不同部分保持鬆散耦合,這意味著它們可以協同工作而不直接依賴彼此。這種分離使您的程式碼更易於維護、測試和適應變化。

Pub/Sub 的關鍵角色:

  • 消息——簡單的文本標籤,例如 'PLAYER_SCORED',描述發生了什麼(加上任何額外資訊)
  • 發布者——喊出「發生了某事!」的物件,通知所有正在聽的人
  • 訂閱者——表示「我關心這個事件」並在事件發生時做出反應的物件
  • 事件系統——確保消息到達正確聽眾的中間人

建立事件系統

讓我們創建一個簡單但功能強大的事件系統來演示這些概念:

// Step 1: Create the EventEmitter class
class EventEmitter {
  constructor() {
    this.listeners = {}; // Store all event listeners
  }
  
  // Register a listener for a specific message type
  on(message, listener) {
    if (!this.listeners[message]) {
      this.listeners[message] = [];
    }
    this.listeners[message].push(listener);
  }
  
  // Send a message to all registered listeners
  emit(message, payload = null) {
    if (this.listeners[message]) {
      this.listeners[message].forEach(listener => {
        listener(message, payload);
      });
    }
  }
}

分解這裡發生的事情:

  • 創建一個使用簡單類的中央事件管理系統
  • 存儲按消息類型組織的監聽器
  • 使用 on() 方法 註冊新監聽器
  • 使用 emit() 廣播消息給所有感興趣的監聽器
  • 支持可選的數據負載以傳遞相關資訊

結合起來:實際示例

好吧,讓我們看看它的實際應用!我們將建立一個簡單的移動系統,展示 pub/sub 的清晰性和靈活性:

// Step 1: Define your message types
const Messages = {
  HERO_MOVE_LEFT: 'HERO_MOVE_LEFT',
  HERO_MOVE_RIGHT: 'HERO_MOVE_RIGHT',
  ENEMY_SPOTTED: 'ENEMY_SPOTTED'
};

// Step 2: Create your event system and game objects
const eventEmitter = new EventEmitter();
const hero = createHero(0, 0);

這段程式碼的作用:

  • 定義了一個常量物件以防止消息名稱中的拼寫錯誤
  • 創建了一個事件發射器實例來處理所有通信
  • 初始化了一個英雄物件在起始位置
// Step 3: Set up event listeners (subscribers)
eventEmitter.on(Messages.HERO_MOVE_LEFT, () => {
  hero.moveTo(hero.x - 5, hero.y);
  console.log(`Hero moved to position: ${hero.x}, ${hero.y}`);
});

eventEmitter.on(Messages.HERO_MOVE_RIGHT, () => {
  hero.moveTo(hero.x + 5, hero.y);
  console.log(`Hero moved to position: ${hero.x}, ${hero.y}`);
});

在上面,我們已經:

  • 註冊了響應移動消息的事件監聽器
  • 更新了英雄的位置,根據移動方向
  • 添加了控制台日誌以跟踪英雄位置的變化
  • 分離了移動邏輯與輸入處理
// Step 4: Connect keyboard input to events (publishers)
window.addEventListener('keydown', (event) => {
  switch(event.key) {
    case 'ArrowLeft':
      eventEmitter.emit(Messages.HERO_MOVE_LEFT);
      break;
    case 'ArrowRight':
      eventEmitter.emit(Messages.HERO_MOVE_RIGHT);
      break;
  }
});

理解這些概念:

  • 連接鍵盤輸入到遊戲事件,而不緊密耦合
  • 使輸入系統能夠間接與遊戲物件通信
  • 允許多個系統響應相同的鍵盤事件
  • 使更改按鍵綁定或添加新輸入方法變得容易
sequenceDiagram
    participant User
    participant Keyboard
    participant EventEmitter
    participant Hero
    participant SoundSystem
    participant Camera
    
    User->>Keyboard: Presses ArrowLeft
    Keyboard->>EventEmitter: emit('HERO_MOVE_LEFT')
    EventEmitter->>Hero: Move left 5 pixels
    EventEmitter->>SoundSystem: Play footstep sound
    EventEmitter->>Camera: Follow hero
    
    Hero->>Hero: Update position
    SoundSystem->>SoundSystem: Play audio
    Camera->>Camera: Adjust viewport

💡 專業提示:這種模式的美妙之處在於它的靈活性!您可以通過簡單地添加更多事件監聽器來輕鬆添加音效、螢幕震動或粒子效果——無需修改現有的鍵盤或移動程式碼。

以下是您會喜歡這種方法的原因:

  • 添加新功能變得非常容易——只需監聽您關心的事件
  • 多個事物可以對同一事件做出反應,而不會相互干擾
  • 測試變得非常簡單,因為每個部分都可以獨立工作
  • 當某些東西出現問題時,您可以確切地知道問題出在哪裡

為什麼 Pub/Sub 能有效擴展

隨著應用程式的複雜性增加Pub/Sub 模式保持簡單性。無論是管理數十個敵人、動態 UI 更新還是音效系統,該模式都能在不進行架構更改的情況下處理增加的規模。新功能可以集成到現有事件系統中,而不影響既有功能。

⚠️ 常見錯誤:不要在早期創建太多特定的消息類型。從廣泛的類別開始,隨著遊戲需求的明確化進行細化。

最佳實踐:

  • 相關消息分組到邏輯類別中
  • 使用描述性名稱,清楚地表明發生了什麼
  • 保持消息負載簡單且專注
  • 記錄您的消息類型以便團隊協作

🔄 教學檢查

事件驅動架構理解:驗證您對完整系統的掌握:

  • Pub/Sub 模式如何防止組件之間的緊密耦合?
  • 為什麼使用事件驅動架構更容易添加新功能?
  • EventEmitter 在通信流程中扮演什麼角色?
  • 消息常量如何防止錯誤並提高可維護性?

設計挑戰:如何使用 Pub/Sub 處理以下遊戲場景?

  1. 敵人死亡:更新分數、播放音效、生成增強道具、從螢幕移除
  2. 關卡完成:停止音樂、顯示 UI、保存進度、加載下一關
  3. 收集增強道具:增強能力、更新 UI、播放效果、啟動計時器

專業聯繫:此模式出現在:

  • 前端框架React/Vue 的事件系統
  • 後端服務:微服務通信
  • 遊戲引擎Unity 的事件系統
  • 移動開發iOS/Android 的通知系統

GitHub Copilot Agent 挑戰 🚀

使用 Agent 模式完成以下挑戰:

描述: 使用繼承和 Pub/Sub 模式創建一個簡單的遊戲物件系統。您將實現一個基本遊戲,其中不同的物件可以通過事件進行通信,而不直接了解彼此。

提示: 使用以下要求創建一個 JavaScript 遊戲系統1創建一個具有 x、y 座標和類型屬性的基礎 GameObject 類。2創建一個 Hero 類,擴展 GameObject 並可以移動。3創建一個 Enemy 類,擴展 GameObject 並可以追逐英雄。4實現一個 EventEmitter 類,用於 Pub/Sub 模式。5設置事件監聽器當英雄移動時附近的敵人接收到 'HERO_MOVED' 事件並更新其位置以追逐英雄。包括 console.log 語句以顯示物件之間的通信。

了解更多關於 agent 模式 的資訊。

🚀 挑戰

考慮如何使用發布-訂閱模式來提升遊戲架構。識別哪些元件應該發出事件,以及系統應如何響應。設計一個遊戲概念並繪製其元件之間的通信模式。

課後測驗

課後測驗

回顧與自學

了解更多有關發布/訂閱模式的資訊,請閱讀相關內容

接下來的5分鐘內可以做的事情

  • 打開任何線上HTML5遊戲使用開發者工具檢查其代碼
  • 創建一個簡單的HTML5 Canvas元素並繪製基本形狀
  • 嘗試使用setInterval創建一個簡單的動畫循環
  • 探索Canvas API文檔並嘗試一個繪圖方法

🎯 一小時內可以完成的目標

  • 完成課後測驗並理解遊戲開發概念
  • 使用HTML、CSS和JavaScript文件設置遊戲項目結構
  • 創建一個基本的遊戲循環,持續更新和渲染
  • 在Canvas上繪製你的第一個遊戲精靈
  • 實現基本的資產加載功能,包括圖片和聲音

📅 一週內的遊戲創作計劃

  • 完成具有所有計劃功能的完整太空遊戲
  • 添加精美的圖形、音效和流暢的動畫
  • 實現遊戲狀態(開始畫面、遊戲過程、遊戲結束)
  • 創建計分系統和玩家進度追蹤功能
  • 使遊戲在各種設備上都能響應並易於訪問
  • 將你的遊戲分享至線上並收集玩家的反饋

🌟 一個月的遊戲開發計劃

  • 創建多款遊戲,探索不同的類型和機制
  • 學習一個遊戲開發框架例如Phaser或Three.js
  • 參與開源遊戲開發項目
  • 掌握高級遊戲編程模式和優化技術
  • 創建一個展示遊戲開發技能的作品集
  • 指導其他對遊戲開發和互動媒體感興趣的人

🎯 遊戲開發精通時間表

timeline
    title Game Architecture Learning Progression
    
    section Object Patterns (20 minutes)
        Code Organization: Class inheritance
                         : Composition patterns
                         : Factory functions
                         : Behavior mixing
        
    section Communication Systems (25 minutes)
        Event Architecture: Pub/Sub implementation
                          : Message design
                          : Event emitters
                          : Loose coupling
        
    section Game Object Design (30 minutes)
        Entity Systems: Property management
                      : Behavior composition
                      : State handling
                      : Lifecycle management
        
    section Architecture Patterns (35 minutes)
        System Design: Component systems
                     : Observer pattern
                     : Command pattern
                     : State machines
        
    section Advanced Concepts (45 minutes)
        Scalable Architecture: Performance optimization
                             : Memory management
                             : Modular design
                             : Testing strategies
        
    section Game Engine Concepts (1 week)
        Professional Development: Scene graphs
                                 : Asset management
                                 : Rendering pipelines
                                 : Physics integration
        
    section Framework Mastery (2 weeks)
        Modern Game Development: React game patterns
                               : Canvas optimization
                               : WebGL basics
                               : PWA games
        
    section Industry Practices (1 month)
        Professional Skills: Team collaboration
                           : Code reviews
                           : Game design patterns
                           : Performance profiling

🛠️ 遊戲架構工具包摘要

完成本課程後,你現在擁有:

  • 設計模式精通:理解繼承與組合的權衡
  • 事件驅動架構:發布/訂閱實現可擴展的通信
  • 面向對象設計:類層次結構和行為組合
  • 現代JavaScript工廠函數、展開語法和ES6+模式
  • 可擴展架構:鬆耦合和模塊化設計原則
  • 遊戲開發基礎:實體系統和組件模式
  • 專業模式:符合行業標準的代碼組織方法

實際應用:這些模式直接適用於:

  • 前端框架React/Vue的組件架構和狀態管理
  • 後端服務:微服務通信和事件驅動系統
  • 移動開發iOS/Android應用架構和通知系統
  • 遊戲引擎Unity、Unreal和基於網頁的遊戲開發
  • 企業軟件:事件溯源和分佈式系統設計
  • API設計RESTful服務和實時通信

專業技能獲得:你現在可以:

  • 設計使用經驗證模式的可擴展軟件架構
  • 實現處理複雜交互的事件驅動系統
  • 選擇適合不同場景的代碼組織策略
  • 調試並有效維護鬆耦合系統
  • 溝通使用行業標準術語進行技術決策

下一步:你已準備好在真實遊戲中實施這些模式,探索高級遊戲開發主題,或將這些架構概念應用於網頁應用程序!

🌟 成就解鎖:你已掌握從簡單遊戲到複雜企業系統的基礎軟件架構模式!

作業

設計一款遊戲


免責聲明
本文件已使用 AI 翻譯服務 Co-op Translator 進行翻譯。儘管我們努力確保翻譯的準確性,但請注意,自動翻譯可能包含錯誤或不準確之處。原始文件的母語版本應被視為權威來源。對於關鍵信息,建議使用專業人工翻譯。我們對因使用此翻譯而引起的任何誤解或誤釋不承擔責任。