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/th/6-space-game/1-introduction
localizeflow[bot] 3b6a4ec479
chore(i18n): sync translations with latest source changes (chunk 11/20, 100 files)
4 months ago
..
README.md chore(i18n): sync translations with latest source changes (chunk 11/20, 100 files) 4 months ago
assignment.md 🌐 Update translations via Co-op Translator 6 months ago

README.md

สร้างเกมอวกาศ ตอนที่ 1: บทนำ

journey
    title การเดินทางพัฒนาเกมของคุณ
    section Foundation
      เรียนรู้สถาปัตยกรรมเกม: 3: Student
      เข้าใจการสืบทอด: 4: Student
      สำรวจการประกอบ: 4: Student
    section Communication
      สร้างระบบ pub/sub: 4: Student
      ออกแบบการไหลของเหตุการณ์: 5: Student
      เชื่อมต่อส่วนประกอบ: 5: Student
    section Application
      สร้างวัตถุในเกม: 5: Student
      นำแบบแผนไปใช้: 5: Student
      วางแผนโครงสร้างเกม: 5: Student

ภาพเคลื่อนไหวเกมอวกาศแสดงการเล่นเกม

เหมือนกับศูนย์ควบคุมภารกิจของ NASA ที่ประสานงานระบบหลายอย่างในระหว่างการปล่อยยานอวกาศ เราจะสร้างเกมอวกาศที่แสดงให้เห็นว่าส่วนต่าง ๆ ของโปรแกรมสามารถทำงานร่วมกันได้อย่างราบรื่น ในขณะที่สร้างสิ่งที่คุณสามารถเล่นได้จริง คุณจะได้เรียนรู้แนวคิดโปรแกรมมิ่งพื้นฐานที่ใช้ได้กับโครงการซอฟต์แวร์ใด ๆ

เราจะสำรวจสองวิธีพื้นฐานในการจัดระเบียบโค้ด: การสืบทอด (inheritance) และการประกอบ (composition) ซึ่งไม่ใช่แค่แนวคิดทางวิชาการ แต่เป็นรูปแบบที่ใช้ในทุกอย่างตั้งแต่เกมวิดีโอจนถึงระบบธนาคาร เรายังจะใช้ระบบสื่อสารที่เรียกว่า pub/sub ซึ่งทำงานเหมือนเครือข่ายการสื่อสารที่ใช้บนยานอวกาศ ช่วยให้ส่วนประกอบต่าง ๆ แบ่งปันข้อมูลกันโดยไม่สร้างการพึ่งพาซึ่งกันและกัน

เมื่อจบซีรีส์นี้ คุณจะเข้าใจวิธีสร้างแอปพลิเคชันที่สามารถขยายและพัฒนาได้ ไม่ว่าคุณจะพัฒนาเกม เว็บแอปพลิเคชัน หรือระบบซอฟต์แวร์อื่น ๆ ก็ตาม

mindmap
  root((สถาปัตยกรรมเกม))
    Object Organization
      การสืบทอด
      การประกอบ
      ลำดับชั้นคลาส
      การผสมพฤติกรรม
    Communication Patterns
      ระบบ Pub/Sub
      ตัวส่งเหตุการณ์
      การส่งข้อความ
      การเชื่อมโยงแบบหลวม
    Game Objects
      คุณสมบัติ (x, y)
      พฤติกรรม (เคลื่อนที่, ชน)
      การจัดการวงจรชีวิต
      การจัดการสถานะ
    Design Patterns
      ฟังก์ชันโรงงาน
      รูปแบบผู้สังเกตการณ์
      ระบบส่วนประกอบ
      สถาปัตยกรรมขับเคลื่อนด้วยเหตุการณ์
    Scalability
      การออกแบบแบบโมดูลาร์
      โค้ดที่ดูแลรักษาง่าย
      ยุทธศาสตร์การทดสอบ
      การเพิ่มประสิทธิภาพ

แบบทดสอบก่อนบรรยาย

แบบทดสอบก่อนบรรยาย

การสืบทอดและการประกอบในการพัฒนาเกม

เมื่อโปรเจกต์เติบโตความซับซ้อน การจัดระเบียบโค้ดก็สำคัญ สิ่งที่เริ่มต้นจากสคริปต์ง่าย ๆ อาจกลายเป็นยากต่อการดูแลหากไม่มีโครงสร้างที่เหมาะสม เหมือนกับภารกิจอพอลโลที่ต้องมีการประสานงานอย่างละเอียดระหว่างส่วนประกอบหลายพันชิ้น

เราจะสำรวจสองวิธีพื้นฐานในการจัดระเบียบโค้ด: การสืบทอดและการประกอบ ซึ่งแต่ละวิธีมีข้อดีที่แตกต่าง และการเข้าใจทั้งสองช่วยให้คุณเลือกวิธีที่เหมาะสมในแต่ละสถานการณ์ เราจะสาธิตแนวคิดเหล่านี้ผ่านเกมอวกาศของเรา ซึ่งฮีโร่ ศัตรู ไอเท็มเสริมพลัง และวัตถุอื่น ๆ ต้องทำงานร่วมกันอย่างมีประสิทธิภาพ

หนึ่งในหนังสือเขียนโปรแกรมที่มีชื่อเสียงที่สุดเกี่ยวข้องกับ รูปแบบการออกแบบ

ในเกมใด ๆ คุณจะมี วัตถุเกม (game objects) — ส่วนประกอบที่โต้ตอบได้ซึ่งเติมเต็มโลกในเกมของคุณ ฮีโร่ ศัตรู ไอเท็มเสริมพลัง และเอฟเฟกต์ภาพ ทั้งหมดนี้เป็นวัตถุเกม แต่ละตัวมีพิกัดบนหน้าจอเป็นค่าของ x และ y เหมือนกับการวางจุดบนระนาบพิกัด

แม้ว่าจะมีลักษณะต่างกัน แต่พวกมันมักจะแบ่งปันพฤติกรรมพื้นฐานบางอย่าง:

  • มันอยู่ที่ใดที่หนึ่ง — วัตถุทุกตัวมีพิกัด x และ y เพื่อให้เกมรู้ว่าจะวาดตรงไหน
  • หลายตัวสามารถเคลื่อนย้ายได้ — ฮีโร่วิ่ง ศัตรูไล่ตาม กระสุนบินข้ามหน้าจอ
  • มีอายุการใช้งาน — บางตัวอยู่ได้ตลอดไป บางตัว (เช่น การระเบิด) ปรากฏชั่วคราวแล้วหายไป
  • ตอบสนองต่อสิ่งต่าง ๆ — เมื่อตัวละครชนกัน ไอเท็มเสริมพลังถูกเก็บ แถบสุขภาพอัปเดต

ลองคิดถึงเกมอย่าง Pac-Man คุณสามารถระบุวัตถุทั้งสี่ประเภทตามที่กล่าวมาข้างต้นในเกมนี้ได้ไหม?

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 คุณสามารถแสดงพฤติกรรมวัตถุผ่านเมธอดที่แนบมากับคลาสหรือวัตถุแต่ละตัว และมีหลายวิธีให้เลือกใช้

แนวทางแบบคลาส

คลาสและการสืบทอดมอบวิธีการจัดระเบียบวัตถุเกมอย่างเป็นโครงสร้าง เหมือนกับระบบจำแนกชนิดสิ่งมีชีวิตที่ Carl Linnaeus พัฒนาขึ้น คุณเริ่มจากคลาสฐานซึ่งมีคุณสมบัติทั่วไปก่อน จากนั้นสร้างคลาสเฉพาะที่สืบทอดคุณสมบัติเหล่านี้และเพิ่มเติมความสามารถเฉพาะตัว

การสืบทอดเป็นแนวคิดที่สำคัญ เรียนรู้เพิ่มเติมได้ที่ บทความของ MDN เกี่ยวกับการสืบทอด

นี่คือวิธีที่คุณสามารถใช้งานวัตถุเกมโดยใช้คลาสและการสืบทอด:

// ขั้นตอนที่ 1: สร้างคลาส GameObject พื้นฐาน
class GameObject {
  constructor(x, y, type) {
    this.x = x;
    this.y = y;
    this.type = type;
  }
}

มาทำความเข้าใจกันทีละขั้นตอน:

  • เรากำลังสร้างแม่แบบพื้นฐานที่วัตถุเกมทุกตัวสามารถใช้ได้
  • คอนสตรัคเตอร์จะบันทึกตำแหน่งของวัตถุ (x, y) และประเภทของมัน
  • นี่จะเป็นฐานที่วัตถุเกมทั้งหมดของคุณจะพัฒนาขึ้นต่อไป
// ขั้นตอนที่ 2: เพิ่มความสามารถในการเคลื่อนที่ผ่านการสืบทอด
class Movable extends GameObject {
  constructor(x, y, type) {
    super(x, y, type); // เรียกตัวสร้างของคลาสแม่
  }

  // เพิ่มความสามารถในการย้ายไปยังตำแหน่งใหม่
  moveTo(x, y) {
    this.x = x;
    this.y = y;
  }
}

จากโค้ดด้านบน เราได้:

  • สืบทอด คลาส GameObject เพื่อเพิ่มฟังก์ชันการเคลื่อนที่
  • เรียก คอนสตรัคเตอร์พ่อแม่ด้วย super() เพื่อเริ่มต้นคุณสมบัติที่สืบทอดมา
  • เพิ่ม เมธอด moveTo() ที่อัปเดตตำแหน่งของวัตถุ
// ขั้นตอนที่ 3: สร้างประเภทวัตถุเกมเฉพาะ
class Hero extends Movable {
  constructor(x, y) {
    super(x, y, 'Hero'); // กำหนดประเภทโดยอัตโนมัติ
  }
}

class Tree extends GameObject {
  constructor(x, y) {
    super(x, y, 'Tree'); // ต้นไม้ไม่จำเป็นต้องเคลื่อนที่
  }
}

// ขั้นตอนที่ 4: ใช้วัตถุเกมของคุณ
const hero = new Hero(0, 0);
hero.moveTo(5, 5); // ฮีโร่สามารถเคลื่อนที่ได้!

const tree = new Tree(10, 15);
// tree.moveTo() จะทำให้เกิดข้อผิดพลาด - ต้นไม้ไม่สามารถเคลื่อนที่ได้

เข้าใจแนวคิดเหล่านี้:

  • สร้าง ประเภทวัตถุเฉพาะที่สืบทอดพฤติกรรมที่เหมาะสม
  • แสดง ว่าการสืบทอดช่วยให้เลือกเพิ่มฟีเจอร์ได้ตามต้องการ
  • ชี้ให้เห็น ว่าฮีโร่สามารถเคลื่อนที่ได้ในขณะที่ต้นไม้คงที่
  • ยกตัวอย่าง การป้องกันการทำงานไม่เหมาะสมด้วยลำดับชั้นของคลาส

ใช้เวลาสักครู่เพื่อจินตนาการฮีโร่ Pac-Man (เช่น Inky, Pinky หรือ Blinky) ว่าจะถูกเขียนใน JavaScript อย่างไร

แนวทางแบบ Composition

การประกอบตามแนวคิดการออกแบบแบบโมดูลาร์ คล้ายกับการที่วิศวกรออกแบบยานอวกาศด้วยส่วนประกอบที่เปลี่ยนได้ แทนที่จะสืบทอดจากคลาสแม่ คุณรวมพฤติกรรมเฉพาะเพื่อสร้างวัตถุที่มีฟังก์ชันตามต้องการ วิธีนี้ให้ความยืดหยุ่นโดยไม่มีข้อจำกัดเรื่องลำดับชั้นที่ตายตัว

// ขั้นตอนที่ 1: สร้างวัตถุพฤติกรรมพื้นฐาน
const gameObject = {
  x: 0,
  y: 0,
  type: ''
};

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

โค้ดนี้ทำอะไร:

  • กำหนด วัตถุ gameObject พื้นฐานที่มีตำแหน่งและชนิด
  • สร้าง วัตถุพฤติกรรม movable ที่มีฟังก์ชันการเคลื่อนที่แยกต่างหาก
  • แยก ความรับผิดชอบโดยเก็บข้อมูลตำแหน่งและตรรกะการเคลื่อนที่แยกกัน
// ขั้นตอนที่ 2: ประกอบวัตถุโดยการรวมพฤติกรรม
const movableObject = { ...gameObject, ...movable };

// ขั้นตอนที่ 3: สร้างฟังก์ชันโรงงานสำหรับวัตถุประเภทต่าง ๆ
function createHero(x, y) {
  return {
    ...movableObject,
    x,
    y,
    type: 'Hero'
  };
}

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

จากโค้ดนี้ เราได้:

  • ผสมผสาน คุณสมบัติของวัตถุพื้นฐานกับพฤติกรรมการเคลื่อนที่โดยใช้ spread syntax
  • สร้าง ฟังก์ชันโรงงานที่คืนค่าวัตถุปรับแต่งได้
  • เปิดใช้งาน การสร้างวัตถุที่ยืดหยุ่นโดยไม่มีลำดับชั้นคลาสตายตัว
  • อนุญาต ให้วัตถุมีพฤติกรรมที่ต้องการอย่างแม่นยำ
// ขั้นตอนที่ 4: สร้างและใช้วัตถุที่คุณประกอบขึ้น
const hero = createHero(10, 10);
hero.moveTo(5, 5); // ทำงานได้อย่างสมบูรณ์แบบ!

const tree = createStatic(0, 0, 'Tree');
// tree.moveTo() ไม่ได้กำหนด - ไม่มีพฤติกรรมการเคลื่อนไหวถูกประกอบขึ้นมา

ประเด็นหลักที่ต้องจำ:

  • ประกอบ วัตถุโดยผสมพฤติกรรมแทนการสืบทอด
  • มอบความยืดหยุ่น มากกว่าลำดับชั้นการสืบทอดที่ตายตัว
  • ให้วัตถุ มีฟีเจอร์ตามที่จำเป็นพอดี
  • ใช้ spread syntax ของ 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 สมัยใหม่ คลาสเหมาะกับลำดับชั้นที่ชัดเจน ในขณะที่ composition เหมาะกับความยืดหยุ่นสูงสุด

นี่คือเมื่อใช้แต่ละวิธี:

  • เลือก การสืบทอดเมื่อมีความสัมพันธ์ "เป็น-a" ชัดเจน (ฮีโร่ เป็น วัตถุที่เคลื่อนที่ได้)
  • เลือก การประกอบเมื่อมีความสัมพันธ์ "มี-a" (ฮีโร่ มี ความสามารถในการเคลื่อนที่)
  • พิจารณา ความชอบและความต้องการของทีม
  • จำไว้ ว่าสามารถผสมผสานสองวิธีนี้ในแอปเดียวกันได้

🔄 ตรวจเช็คความเข้าใจเชิงการสอน

ความเข้าใจการจัดระเบียบวัตถุ: ก่อนย้ายไปแพทเทิร์นสื่อสาร ให้แน่ใจว่าคุณ:

  • อธิบายความแตกต่างระหว่าง inheritance และ composition ได้
  • ระบุเมื่อใช้คลาสกับฟังก์ชันโรงงานได้
  • เข้าใจคำสำคัญ super() ในการสืบทอด
  • รู้ประโยชน์ของแต่ละวิธีในพัฒนาเกม

ทดสอบตนเองอย่างรวดเร็ว: คุณจะสร้าง Flying Enemy ที่ทั้งเคลื่อนที่และบินได้อย่างไร?

  • วิธี inheritance: class FlyingEnemy extends Movable
  • วิธี composition: { ...movable, ...flyable, ...gameObject }

ตัวอย่างจากโลกจริง: รูปแบบนี้พบได้ทั่วไปใน:

  • React Components: Props (composition) กับ inheritance ของคลาส
  • เกมเอนจิน: ระบบเอนทิตี้-คอมโพเนนต์ใช้ composition
  • แอปมือถือ: เฟรมเวิร์ค UI ส่วนใหญ่ใช้ลำดับชั้น inheritance

แพทเทิร์นการสื่อสาร: ระบบ Pub/Sub

เมื่อแอปพลิเคชันซับซ้อนขึ้น การจัดการการสื่อสารระหว่างส่วนประกอบก็กลายเป็นเรื่องท้าทาย รูปแบบการเผยแพร่-สมัครรับ (pub/sub) แก้ปัญหานี้โดยใช้หลักการคล้ายการกระจายเสียงวิทยุ — ผู้ส่งเพียงหนึ่งรายสามารถสื่อสารถึงผู้รับหลายรายโดยไม่ต้องรู้ว่าผู้ฟังคือใคร

ลองนึกดูว่ามีอะไรเกิดขึ้นเมื่อฮีโร่ได้รับความเสียหาย: แถบสุขภาพอัปเดต เสียงประกอบดังขึ้น และมีภาพแสดงผล โดยแทนที่จะผูกวัตถุฮีโร่เข้ากับระบบเหล่านี้โดยตรง pub/sub อนุญาตให้ฮีโร่ส่งข้อความ "ได้รับความเสียหาย" ให้ระบบใดก็ได้ที่ต้องตอบสนองสมัครรับและทำงานตอบสนองตามนั้น

Pub/Sub ย่อมาจาก 'publish-subscribe'

flowchart TD
    A[ฮีโร่ได้รับความเสียหาย] --> B[เผยแพร่: HERO_DAMAGED]
    B --> C[ระบบอีเวนต์]
    
    C --> D[ผู้ติดตามแถบสุขภาพ]
    C --> E[ผู้ติดตามระบบเสียง]
    C --> F[ผู้ติดตามเอฟเฟกต์ภาพ]
    C --> G[ผู้ติดตามระบบความสำเร็จ]
    
    D --> H[อัปเดตการแสดงผลสุขภาพ]
    E --> I[เล่นเสียงความเสียหาย]
    F --> J[แสดงแสงสีแดง]
    G --> K[ตรวจสอบความสำเร็จการเอาชีวิตรอด]
    
    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:

  • ข้อความ (Messages) ป้ายข้อความง่าย ๆ เช่น 'PLAYER_SCORED' เพื่อบอกว่าเกิดอะไรขึ้น (รวมถึงข้อมูลเพิ่มเติมใด ๆ)
  • ผู้เผยแพร่ (Publishers) วัตถุที่ส่งเสียงว่า "เกิดเหตุการณ์!" ให้กับผู้ฟังทุกคน
  • ผู้สมัครรับ (Subscribers) วัตถุที่บอกว่า "ฉันสนใจเหตุการณ์นี้" และทำงานตอบสนองเมื่อเหตุการณ์เกิดขึ้น
  • ระบบเหตุการณ์ (Event System) ตัวกลางที่ช่วยให้ข้อความส่งไปถึงผู้ฟังที่ถูกต้อง

สร้างระบบเหตุการณ์

เราจะสร้างระบบเหตุการณ์ง่าย ๆ แต่ทรงพลังเพื่อแสดงแนวคิดเหล่านี้:

// ขั้นตอนที่ 1: สร้างคลาส EventEmitter
class EventEmitter {
  constructor() {
    this.listeners = {}; // เก็บตัวฟังเหตุการณ์ทั้งหมด
  }
  
  // ลงทะเบียนตัวฟังสำหรับประเภทข้อความเฉพาะ
  on(message, listener) {
    if (!this.listeners[message]) {
      this.listeners[message] = [];
    }
    this.listeners[message].push(listener);
  }
  
  // ส่งข้อความไปยังตัวฟังที่ลงทะเบียนทั้งหมด
  emit(message, payload = null) {
    if (this.listeners[message]) {
      this.listeners[message].forEach(listener => {
        listener(message, payload);
      });
    }
  }
}

อธิบายโค้ดนี้:

  • สร้าง ระบบจัดการเหตุการณ์กลางโดยใช้คลาสง่าย ๆ
  • เก็บ รายชื่อผู้ฟังในอ็อบเจ็กต์จัดกลุ่มตามประเภทข้อความ
  • ลงทะเบียน ผู้ฟังใหม่ผ่านเมธอด on()
  • เผยแพร่ ข้อความไปยังผู้ฟังที่สนใจผ่าน emit()
  • รองรับ การส่งข้อมูลเสริมผ่าน payload

ตัวอย่างใช้งานจริง

ตอนนี้ลองดูการทำงานจริง! เราจะสร้างระบบเคลื่อนที่ง่าย ๆ ที่แสดงให้เห็นความสะอาดและความยืดหยุ่นของ pub/sub:

// ขั้นตอนที่ 1: กำหนดประเภทข้อความของคุณ
const Messages = {
  HERO_MOVE_LEFT: 'HERO_MOVE_LEFT',
  HERO_MOVE_RIGHT: 'HERO_MOVE_RIGHT',
  ENEMY_SPOTTED: 'ENEMY_SPOTTED'
};

// ขั้นตอนที่ 2: สร้างระบบเหตุการณ์และวัตถุในเกมของคุณ
const eventEmitter = new EventEmitter();
const hero = createHero(0, 0);

โค้ดนี้ทำอะไร:

  • กำหนด ออบเจ็กต์ค่าคงที่เพื่อป้องกันการพิมพ์ผิดชื่อข้อความ
  • สร้าง อินสแตนซ์อีเวนท์อีมิทเตอร์เพื่อจัดการการสื่อสารทั้งหมด
  • เริ่มต้น วัตถุฮีโรที่ตำแหน่งเริ่มต้น
// ขั้นตอนที่ 3: ตั้งค่าผู้ฟังเหตุการณ์ (ผู้สมัครสมาชิก)
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}`);
});

ในโค้ดด้านบน เราได้:

  • ลงทะเบียน ผู้ฟังเหตุการณ์ที่ตอบสนองข้อความเกี่ยวกับการเคลื่อนที่
  • อัปเดต ตำแหน่งฮีโรรองรับทิศทางการเคลื่อนที่
  • เพิ่ม การบันทึกข้อมูลในคอนโซลเพื่อติดตามการเปลี่ยนแปลงตำแหน่งฮีโร่
  • แยก ลอจิกการเคลื่อนที่ออกจากการจัดการอินพุต
// ขั้นตอนที่ 4: เชื่อมต่อการป้อนข้อมูลจากแป้นพิมพ์ไปยังเหตุการณ์ (ผู้เผยแพร่)
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: กดปุ่มลูกศรซ้าย
    Keyboard->>EventEmitter: emit('HERO_MOVE_LEFT')
    EventEmitter->>Hero: เคลื่อนที่ไปทางซ้าย 5 พิกเซล
    EventEmitter->>SoundSystem: เล่นเสียงก้าวเดิน
    EventEmitter->>Camera: ติดตามฮีโร่
    
    Hero->>Hero: อัปเดตตำแหน่ง
    SoundSystem->>SoundSystem: เล่นเสียง
    Camera->>Camera: ปรับมุมมองหน้าจอ

💡 เคล็ดลับมือโปร: ความสวยงามของรูปแบบนี้คือความยืดหยุ่น! คุณสามารถเพิ่มเสียง เอฟเฟกต์หน้าจอ เขย่า หรืออนุภาคง่าย ๆ โดยแค่เพิ่มผู้ฟังเหตุการณ์ใหม่ ๆ โดยไม่ต้องแก้โค้ดคีย์บอร์ดหรือการเคลื่อนที่ที่มีอยู่

นี่คือเหตุผลที่คุณจะชอบวิธีนี้:

  • การเพิ่มฟีเจอร์ใหม่ง่ายมาก — แค่ฟังเหตุการณ์ที่คุณสนใจ
  • หลายสิ่งตอบสนองต่อเหตุการณ์เดียวกันโดยไม่ขัดแย้งกัน
  • การทดสอบง่ายขึ้นมากเพราะแต่ละส่วนทำงานอิสระกัน
  • เมื่อมีปัญหา คุณรู้ได้เลยว่าจะดูตรงไหน

ทำไม Pub/Sub จึงขยายผลได้ดี

รูปแบบ pub/sub รักษาความเรียบง่ายเมื่อแอปพลิเคชันซับซ้อนขึ้น ไม่ว่าจะจัดการศัตรูนับสิบ อัปเดต UI แบบไดนามิก หรือระบบเสียง รูปแบบช่วยให้ขยายได้โดยไม่ต้องเปลี่ยนแปลงโครงสร้าง ฟีเจอร์ใหม่สามารถผนวกเข้ากับระบบเหตุการณ์ที่มีอยู่โดยไม่กระทบฟังก์ชันที่ตั้งไว้

⚠️ ข้อผิดพลาดทั่วไป: อย่าสร้างประเภทข้อความเฉพาะเกินไปตั้งแต่แรก เริ่มจากหมวดกว้าง ๆ แล้วปรับละเอียดเมื่อความต้องการของเกมชัดเจนขึ้น

แนวปฏิบัติที่ดี:

  • จัดกลุ่ม ข้อความเกี่ยวข้องกันเป็นหมวดหมู่
  • ใช้ ชื่อที่บรรยายชัดเจนว่าเกิดอะไรขึ้น
  • เก็บ ข้อมูลส่งผ่านข้อความให้ง่ายและตรงประเด็น
  • จดบันทึก ประเภทข้อความเพื่อการทำงานร่วมกันในทีม

🔄 ตรวจเช็คความเข้าใจเชิงการสอน

ความเข้าใจสถาปัตยกรรมขับเคลื่อนด้วยเหตุการณ์: ตรวจสอบความเข้าใจระบบโดยรวม:

  • รูปแบบ pub/sub ป้องกันการพึ่งพากันแน่นแฟ้นอย่างไร?
  • ทำไมการขับเคลื่อนด้วยเหตุการณ์ช่วยให้ง่ายต่อการเพิ่มฟีเจอร์ใหม่?
  • บทบาทของ EventEmitter ในการสื่อสารคืออะไร?
  • การใช้ค่าคงที่ข้อความช่วยลดบั๊กและเพิ่มการบำรุงรักษาอย่างไร?

ความท้าทายการออกแบบ: คุณจะจัดการสถานการณ์เกมเหล่านี้ด้วย pub/sub อย่างไร?

  1. ศัตรูตาย: อัปเดตคะแนน เล่นเสียง สปอนส์ไอเท็มเสริมพลัง ลบออกจากหน้าจอ
  2. ผ่านเลเวล: หยุดเพลง แสดง UI บันทึกความคืบหน้า โหลดเลเวลถัดไป
  3. เก็บไอเท็มเสริมพลัง: เพิ่มความสามารถ อัปเดต UI เล่นเอฟเฟกต์ เริ่มจับเวลา

การเชื่อมโยงกับโลกมืออาชีพ: รูปแบบนี้พบใน:

  • เฟรมเวิร์คด้านหน้า: ระบบเหตุการณ์ของ React/Vue
  • บริการเบื้องหลัง: การสื่อสารไมโครเซอร์วิส
  • เอนจินเกม: ระบบเหตุการณ์ของ Unity
  • การพัฒนามือถือ: ระบบแจ้งเตือนของ iOS/Android

ความท้าทาย GitHub Copilot Agent 🚀

ใช้โหมด Agent เพื่อทำความท้าทายดังนี้:

คำอธิบาย: สร้างระบบวัตถุเกมง่าย ๆ โดยใช้ทั้ง inheritance และแพทเทิร์น pub/sub คุณจะสร้างเกมพื้นฐานที่วัตถุต่าง ๆ สามารถสื่อสารกันผ่านเหตุการณ์โดยไม่ต้องรู้จักกันโดยตรง

คำสั่ง: สร้างระบบเกม JavaScript โดยมีข้อกำหนดดังนี้: 1) สร้างคลาส GameObject พื้นฐานที่มีพิกัด x, y และคุณสมบัติ type 2) สร้างคลาส Hero ที่สืบทอด GameObject และสามารถเคลื่อนที่ได้ 3) สร้างคลาส Enemy ที่สืบทอด GameObject และสามารถไล่ตามฮีโร่ได้ 4) สร้างคลาส EventEmitter สำหรับแพทเทิร์น pub/sub 5) ตั้งค่าผู้ฟังเหตุการณ์เพื่อให้เมื่่อฮีโร่เคลื่อนที่ ศัตรูนอกใกล้เคียงได้รับเหตุการณ์ 'HERO_MOVED' และอัปเดตตำแหน่งเพื่อเคลื่อนไปยังฮีโร่ พร้อมแสดงข้อความ console.log แสดงการสื่อสารระหว่างวัตถุ

เรียนรู้เพิ่มเติมเกี่ยวกับ โหมดเอเจนต์ ที่นี่

🚀 ความท้าทาย

พิจารณาว่าแพทเทิร์น pub-sub ช่วยเสริมสถาปัตยกรรมเกมอย่างไร ระบุส่วนประกอบที่ควรส่งอีเวนต์และระบบควรตอบสนองอย่างไร ออกแบบแนวคิดเกมและแผนผังรูปแบบการสื่อสารระหว่างส่วนประกอบต่างๆ

Post-Lecture Quiz

Post-lecture quiz

Review & Self Study

เรียนรู้เพิ่มเติมเกี่ยวกับ Pub/Sub โดยการ อ่านเกี่ยวกับมัน

สิ่งที่คุณสามารถทำได้ใน 5 นาทีถัดไป

  • เปิดเกม HTML5 ใดก็ได้ทางออนไลน์และตรวจสอบโค้ดด้วย DevTools
  • สร้างองค์ประกอบ HTML5 Canvas ง่ายๆ และวาดรูปร่างพื้นฐาน
  • ลองใช้ setInterval เพื่อสร้างแอนิเมชันลูปง่ายๆ
  • สำรวจเอกสาร Canvas API และลองใช้วิธีการวาดภาพ

🎯 สิ่งที่คุณสามารถทำให้สำเร็จภายในชั่วโมงนี้

  • ทำแบบทดสอบหลังบทเรียนให้เสร็จและเข้าใจแนวคิดพัฒนาเกม
  • ตั้งค่าโครงสร้างโปรเจกต์เกมของคุณด้วยไฟล์ HTML, CSS และ JavaScript
  • สร้างเกมลูปพื้นฐานที่อัปเดตและแสดงผลอย่างต่อเนื่อง
  • วาดสไปรต์เกมแรกของคุณบนแคนวาส
  • นำเข้าทรัพยากรพื้นฐานสำหรับภาพและเสียง

📅 การสร้างเกมตลอดสัปดาห์ของคุณ

  • ทำเกมอวกาศที่สมบูรณ์พร้อมฟีเจอร์ที่วางแผนไว้ทั้งหมด
  • เพิ่มกราฟิกที่ปรับแต่งแล้ว เอฟเฟกต์เสียง และแอนิเมชันที่ราบรื่น
  • ใช้สถานะเกม (หน้าจอเริ่มเกม, การเล่นเกม, เกมจบ)
  • สร้างระบบคะแนนและติดตามความก้าวหน้าของผู้เล่น
  • ทำให้เกมของคุณตอบสนองและเข้าถึงได้บนอุปกรณ์หลากหลาย
  • แชร์เกมของคุณออนไลน์และรับคำติชมจากผู้เล่น

🌟 การพัฒนาเกมตลอดเดือนของคุณ

  • สร้างเกมหลายเกมโดยสำรวจแนวเกมและกลไกที่แตกต่างกัน
  • เรียนรู้เฟรมเวิร์กพัฒนาเกมเช่น Phaser หรือ Three.js
  • มีส่วนร่วมในโปรเจกต์พัฒนาเกมแบบโอเพนซอร์ส
  • เชี่ยวชาญแพทเทิร์นโปรแกรมเกมขั้นสูงและการปรับแต่งประสิทธิภาพ
  • สร้างพอร์ตโฟลิโอที่แสดงทักษะการพัฒนาเกมของคุณ
  • เป็นเมนทอร์ให้กับผู้ที่สนใจพัฒนาเกมและสื่อโต้ตอบ

🎯 ไทม์ไลน์ความชำนาญด้านการพัฒนาเกมของคุณ

timeline
    title ความก้าวหน้าการเรียนรู้สถาปัตยกรรมเกม
    
    section รูปแบบวัตถุ (20 นาที)
        การจัดระเบียบโค้ด: การสืบทอดคลาส
                         : รูปแบบคอมโพสิชัน
                         : ฟังก์ชันโรงงาน
                         : การผสมพฤติกรรม
        
    section ระบบการสื่อสาร (25 นาที)
        สถาปัตยกรรมเหตุการณ์: การใช้งาน Pub/Sub
                          : การออกแบบข้อความ
                          : ตัวปล่อยเหตุการณ์
                          : การเชื่อมโยงแบบหลวม
        
    section การออกแบบวัตถุของเกม (30 นาที)
        ระบบเอนทิตี้: การจัดการคุณสมบัติ
                      : การประกอบพฤติกรรม
                      : การจัดการสถานะ
                      : การจัดการวงจรชีวิต
        
    section รูปแบบสถาปัตยกรรม (35 นาที)
        การออกแบบระบบ: ระบบคอมโพเนนต์
                     : รูปแบบผู้สังเกตการณ์
                     : รูปแบบคำสั่ง
                     : เครื่องสถานะ
        
    section แนวคิดขั้นสูง (45 นาที)
        สถาปัตยกรรมที่ปรับขนาดได้: การเพิ่มประสิทธิภาพ
                             : การจัดการหน่วยความจำ
                             : การออกแบบแบบโมดูลาร์
                             : กลยุทธ์การทดสอบ
        
    section แนวคิดเอนจินเกม (1 สัปดาห์)
        การพัฒนาเชิงมืออาชีพ: แผนผังฉาก
                                 : การจัดการทรัพย์สิน
                                 : ท่อการเรนเดอร์
                                 : การผสานฟิสิกส์
        
    section ความเชี่ยวชาญกรอบงาน (2 สัปดาห์)
        การพัฒนาเกมสมัยใหม่: รูปแบบเกม React
                               : การเพิ่มประสิทธิภาพ Canvas
                               : พื้นฐาน WebGL
                               : เกม PWA
        
    section แนวปฏิบัติอุตสาหกรรม (1 เดือน)
        ทักษะเชิงมืออาชีพ: การทำงานร่วมกันในทีม
                           : การตรวจทานโค้ด
                           : รูปแบบการออกแบบเกม
                           : การวิเคราะห์ประสิทธิภาพ

🛠️ สรุปชุดเครื่องมือสถาปัตยกรรมเกมของคุณ

หลังจากเรียนจบบทนี้ คุณจะมี:

  • ความชำนาญในแพทเทิร์นการออกแบบ: เข้าใจข้อดีข้อเสียของการสืบทอดและการประกอบ
  • สถาปัตยกรรมขับเคลื่อนด้วยเหตุการณ์: การใช้งาน pub/sub เพื่อการสื่อสารที่ปรับขยายได้
  • การออกแบบเชิงวัตถุ: ลำดับชั้นคลาสและการประกอบพฤติกรรม
  • JavaScript สมัยใหม่: ฟังก์ชันโรงงาน, syntax กระจาย และแพทเทิร์น ES6+
  • สถาปัตยกรรมที่สามารถปรับขยาย: หลวมและหลักการออกแบบโมดูลาร์
  • พื้นฐานการพัฒนาเกม: ระบบเอนทิตีและแพทเทิร์นคอมโพเนนท์
  • แพทเทิร์นระดับมืออาชีพ: วิธีปฏิบัติมาตรฐานอุตสาหกรรมสำหรับการจัดการโค้ด

การประยุกต์ใช้ในโลกจริง: แพทเทิร์นเหล่านี้ใช้โดยตรงกับ:

  • เฟรมเวิร์กหน้าเว็บ: สถาปัตยกรรมคอมโพเนนต์และการจัดการสถานะของ React/Vue
  • บริการแบ็คเอนด์: การสื่อสารไมโครเซอร์วิสและระบบขับเคลื่อนด้วยเหตุการณ์
  • การพัฒนาโมบาย: สถาปัตยกรรมแอป iOS/Android และระบบแจ้งเตือน
  • เอนจินเกม: Unity, Unreal และการพัฒนาเกมบนเว็บ
  • ซอฟต์แวร์องค์กร: การเก็บแหล่งข้อมูลเหตุการณ์และการออกแบบระบบแบบกระจาย
  • การออกแบบ API: บริการ RESTful และการสื่อสารเรียลไทม์

ทักษะระดับมืออาชีพที่ได้รับ: คุณสามารถ:

  • ออกแบบ สถาปัตยกรรมซอฟต์แวร์ที่ปรับขยายโดยใช้แพทเทิร์นที่พิสูจน์แล้ว
  • ใช้งาน ระบบขับเคลื่อนด้วยเหตุการณ์ที่จัดการปฏิสัมพันธ์ซับซ้อนได้
  • เลือก กลยุทธ์การจัดองค์กรโค้ดที่เหมาะสมกับสถานการณ์ต่างๆ
  • ดีบัก และดูแลระบบที่หลวมเชื่อมโยงได้อย่างมีประสิทธิภาพ
  • สื่อสาร การตัดสินใจทางเทคนิคด้วยคำศัพท์มาตรฐานอุตสาหกรรม

ระดับถัดไป: คุณพร้อมที่จะใช้แพทเทิร์นเหล่านี้ในเกมจริง สำรวจหัวข้อการพัฒนาเกมขั้นสูง หรือใช้แนวคิดสถาปัตยกรรมนี้กับเว็บแอปพลิเคชัน!

🌟 ความสำเร็จที่ปลดล็อกแล้ว: คุณได้ชำนาญแพทเทิร์นสถาปัตยกรรมซอฟต์แวร์พื้นฐานที่เป็นแรงผลักดันทุกอย่างตั้งแต่เกมง่ายๆ ถึงระบบองค์กรที่ซับซ้อน!

Assignment

Mock up a game


ข้อจำกัดความรับผิดชอบ:
เอกสารฉบับนี้แปลโดยใช้บริการแปลภาษาอัตโนมัติ Co-op Translator แม้เราจะพยายามให้มีความถูกต้อง โปรดทราบว่าการแปลโดยระบบอัตโนมัติอาจมีข้อผิดพลาดหรือความคลาดเคลื่อนได้ เอกสารต้นฉบับในภาษาเดิมถือเป็นแหล่งข้อมูลที่ถูกต้องที่สุด สำหรับข้อมูลสำคัญ ควรใช้บริการแปลโดยมนุษย์ที่มีความเชี่ยวชาญ ทางเราไม่รับผิดชอบต่อความเข้าใจผิดหรือการตีความที่ผิดพลาดใด ๆ อันเกิดจากการใช้การแปลนี้