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/4-collision-detection
localizeflow[bot] 4dc412aa0e
chore(i18n): sync translations with latest source changes (chunk 1/1, 291 changes)
7 months ago
..
solution chore(i18n): sync translations with latest source changes (chunk 1/1, 291 changes) 7 months ago
your-work chore(i18n): sync translations with latest source changes (chunk 1/1, 291 changes) 7 months ago
README.md chore(i18n): sync translations with latest source changes (chunk 1/1, 291 changes) 7 months ago
assignment.md chore(i18n): sync translations with latest source changes (chunk 1/1, 291 changes) 7 months ago

README.md

สร้างเกมอวกาศ ตอนที่ 4: เพิ่มเลเซอร์และตรวจจับการชน

journey
    title การเดินทางของคุณในการตรวจจับการชน
    section พื้นฐานฟิสิกส์
      เข้าใจรูปสี่เหลี่ยมผืนผ้า: 3: นักเรียน
      เรียนรู้คณิตศาสตร์การตัดกัน: 4: นักเรียน
      เข้าใจระบบพิกัด: 4: นักเรียน
    section กลไกของเกม
      ใช้การยิงเลเซอร์: 4: นักเรียน
      เพิ่มวงจรชีวิตของวัตถุ: 5: นักเรียน
      สร้างกฎการชนกัน: 5: นักเรียน
    section การรวมระบบ
      สร้างระบบตรวจจับการชน: 5: นักเรียน
      ปรับปรุงประสิทธิภาพ: 5: นักเรียน
      ทดสอบระบบการโต้ตอบ: 5: นักเรียน

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

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

ลองนึกถึงช่วงเวลาหนึ่งใน Star Wars ที่หลุมจรวดโปรตอนของลุคยิงโดนช่องระบายของดาวมรณะ การตรวจจับการชนที่แม่นยำนี้เปลี่ยนแปลงชะตากรรมของกาแล็กซี! ในเกม การตรวจจับการชนทำงานในลักษณะเดียวกัน - ซึ่งจะตัดสินว่าเมื่อไหร่ที่วัตถุมีปฏิสัมพันธ์และเกิดอะไรขึ้นต่อไป

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

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

mindmap
  root((Collision Detection))
    Physics Concepts
      ขอบเขตสี่เหลี่ยมผืนผ้า
      การทดสอบการตัดกัน
      ระบบพิกัด
      ตรรกะการแยกส่วน
    Game Objects
      กระสุนเลเซอร์
      เรือศัตรู
      ตัวละครหลัก
      โซนการชน
    Lifecycle Management
      การสร้างวัตถุ
      การอัปเดตการเคลื่อนที่
      การทำเครื่องหมายทำลาย
      การล้างหน่วยความจำ
    Event Systems
      การป้อนข้อมูลจากแป้นพิมพ์
      เหตุการณ์การชน
      การเปลี่ยนแปลงสถานะเกม
      เอฟเฟกต์เสียง/ภาพ
    Performance
      อัลกอริทึมที่มีประสิทธิภาพ
      การเพิ่มประสิทธิภาพอัตราเฟรม
      การจัดการหน่วยความจำ
      การแบ่งพื้นที่

ทำการค้นคว้าเล็กน้อยเกี่ยวกับเกมคอมพิวเตอร์เกมแรกสุดที่เคยถูกเขียนขึ้น ฟังก์ชันการทำงานของมันคืออะไร?

การตรวจจับการชน

การตรวจจับการชนทำงานเหมือนเซ็นเซอร์ระยะใกล้บนโมดูลดวงจันทร์ Apollo — จะตรวจสอบระยะห่างอย่างต่อเนื่องและแจ้งเตือนเมื่อวัตถุใกล้เกินไป ในเกม ระบบนี้จะตัดสินว่าเมื่อไหร่ที่วัตถุมีปฏิสัมพันธ์และควรเกิดอะไรขึ้นต่อไป

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

การแทนที่สี่เหลี่ยมผืนผ้า

วัตถุในเกมทุกตัวต้องมีพิกัดขอบเขต คล้ายกับที่ยาน Pathfinder สำรวจดาวอังคารกำหนดตำแหน่งของมันบนพื้นผิวดาวอังคาร นี่คือวิธีที่เรากำหนดพิกัดขอบเขตเหล่านี้:

flowchart TD
    A["🎯 วัตถุเกม"] --> B["📍 ตำแหน่ง (x, y)"]
    A --> C["📏 ขนาด (กว้าง, สูง)"]
    
    B --> D["บน: y"]
    B --> E["ซ้าย: x"]
    
    C --> F["ล่าง: y + สูง"]
    C --> G["ขวา: x + กว้าง"]
    
    D --> H["🔲 ขอบเขตสี่เหลี่ยม"]
    E --> H
    F --> H
    G --> H
    
    H --> I["พร้อมสำหรับตรวจจับการชน"]
    
    style A fill:#e3f2fd
    style H fill:#e8f5e8
    style I fill:#fff3e0
rectFromGameObject() {
  return {
    top: this.y,
    left: this.x,
    bottom: this.y + this.height,
    right: this.x + this.width
  }
}

มาลงลึกกัน:

  • ขอบบน: คือจุดเริ่มต้นของวัตถุในแนวตั้ง (ตำแหน่ง y)
  • ขอบซ้าย: จุดเริ่มต้นในแนวนอน (ตำแหน่ง x)
  • ขอบล่าง: บวกความสูงกับตำแหน่ง y — เราจะรู้ว่าขอบล่างอยู่ตรงไหน!
  • ขอบขวา: บวกความกว้างกับตำแหน่ง x — และเราจะได้ขอบเขตสมบูรณ์

อัลกอริทึมตรวจจับการทับซ้อน

การตรวจจับการทับซ้อนของสี่เหลี่ยมผืนผ้าใช้ตรรกะคล้ายกับกล้องโทรทรรศน์อวกาศฮับเบิลที่ตรวจสอบว่าดวงดาวหรือวัตถุท้องฟ้าทับซ้อนในมุมมองหรือไม่ อัลกอริทึมจะตรวจสอบว่ามีการแยกกันไหม:

flowchart LR
    A["สี่เหลี่ยมผืนผ้า 1"] --> B{"การทดสอบการแยก"}
    C["สี่เหลี่ยมผืนผ้า 2"] --> B
    
    B --> D["R2 ซ้าย > R1 ขวา?"]
    B --> E["R2 ขวา < R1 ซ้าย?"]
    B --> F["R2 บน > R1 ล่าง?"]
    B --> G["R2 ล่าง < R1 บน?"]
    
    D --> H{"มีค่าใดเป็นจริงไหม?"}
    E --> H
    F --> H
    G --> H
    
    H -->|ใช่| I["❌ ไม่มีการชนกัน"]
    H -->|ไม่ใช่| J["✅ ตรวจพบการชนกัน"]
    
    style B fill:#e3f2fd
    style I fill:#ffebee
    style J fill:#e8f5e8
function intersectRect(r1, r2) {
  return !(r2.left > r1.right ||
    r2.right < r1.left ||
    r2.top > r1.bottom ||
    r2.bottom < r1.top);
}

การทดสอบการแยกนี้ทำงานคล้ายระบบเรดาร์:

  • สี่เหลี่ยมผืนผ้าที่ 2 อยู่ทางขวาทั้งหมดของสี่เหลี่ยมผืนผ้าที่ 1 หรือไม่?
  • สี่เหลี่ยมผืนผ้าที่ 2 อยู่ทางซ้ายทั้งหมดของสี่เหลี่ยมผืนผ้าที่ 1 หรือไม่?
  • สี่เหลี่ยมผืนผ้าที่ 2 อยู่ด้านล่างทั้งหมดของสี่เหลี่ยมผืนผ้าที่ 1 หรือไม่?
  • สี่เหลี่ยมผืนผ้าที่ 2 อยู่ด้านบนทั้งหมดของสี่เหลี่ยมผืนผ้าที่ 1 หรือไม่?

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

การจัดการวงจรชีวิตวัตถุ

เมื่อเลเซอร์ชนศัตรู วัตถุทั้งสองต้องถูกลบออกจากเกม อย่างไรก็ตาม การลบวัตถุระหว่างลูปเกมอาจทำให้เกิดข้อผิดพลาดได้ — เป็นบทเรียนที่ได้เรียนรู้จากระบบคอมพิวเตอร์ยุคแรก เช่น Apollo Guidance Computer แทนที่จะลบเลย เราใช้วิธี "ทำเครื่องหมายเพื่อลบทิ้ง" ซึ่งปลอดภัยกว่าเพราะลบวัตถุระหว่างเฟรม

stateDiagram-v2
    [*] --> Active: สร้างวัตถุแล้ว
    Active --> Collided: ตรวจพบการชน
    Collided --> MarkedDead: ตั้งค่า dead = true
    MarkedDead --> Filtered: เฟรมถัดไป
    Filtered --> [*]: ลบวัตถุแล้ว
    
    Active --> OutOfBounds: ออกนอกหน้าจอ
    OutOfBounds --> MarkedDead
    
    note right of MarkedDead
        ปลอดภัยที่จะดำเนินต่อ
        เฟรมปัจจุบัน
    end note
    
    note right of Filtered
        วัตถุที่ถูกลบ
        ระหว่างเฟรม
    end note

นี่คือวิธีที่เราทำเครื่องหมายเพื่อลบทิ้ง:

// ทำเครื่องหมายวัตถุสำหรับลบ
enemy.dead = true;

ทำไมวิธีนี้ถึงใช้ได้:

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

จากนั้นกรองวัตถุที่ทำเครื่องหมายออกก่อนรอบการเรนเดอร์ถัดไป:

gameObjects = gameObjects.filter(go => !go.dead);

การกรองนี้ทำอะไร:

  • สร้างรายการใหม่ที่มีเฉพาะวัตถุ "ยังมีชีวิต"
  • ทิ้งวัตถุที่ถูกทำเครื่องหมายตาย
  • ทำให้เกมทำงานราบรื่น
  • ป้องกันการใช้หน่วยความจำมากเกินไปจากวัตถุที่ถูกทำลายสะสม

การใช้งานกลไกเลเซอร์

กระสุนเลเซอร์ในเกมทำงานเหมือนกับโฟตอนทอร์ปิโดใน Star Trek — เป็นวัตถุแยกชิ้นที่เดินทางเป็นเส้นตรงจนกระทั่งชนอะไรบางอย่าง ทุกครั้งที่กด spacebar จะสร้างวัตถุเลเซอร์ใหม่ที่เคลื่อนผ่านหน้าจอ

เพื่อให้ทำงานได้ เราต้องประสานงานส่วนต่างๆ ดังนี้:

ส่วนประกอบสำคัญที่ต้องใช้งาน:

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

การควบคุมอัตราการยิง

อัตราการยิงไม่จำกัดจะทำให้เครื่องยนต์เกมล้นและเกมง่ายเกินไป ระบบอาวุธจริงก็มีข้อจำกัดเช่นกัน — แม้กระทั่งปืนเลเซอร์ของ USS Enterprise ก็ต้องใช้เวลาชาร์จระหว่างยิง

เราจะสร้างระบบ cooldown เพื่อป้องกันการยิงรวดเร็วมากเกินไป ในขณะที่ยังควบคุมการตอบสนองดีอยู่:

sequenceDiagram
    participant Player
    participant Weapon
    participant Cooldown
    participant Game
    
    Player->>Weapon: กดปุ่ม Spacebar
    Weapon->>Cooldown: ตรวจสอบว่าคูลไหม
    
    alt อาวุธพร้อมใช้งาน
        Cooldown->>Weapon: คูล = จริง
        Weapon->>Game: สร้างเลเซอร์
        Weapon->>Cooldown: เริ่มการคูลดาวน์ใหม่
        Cooldown->>Cooldown: คูล = เท็จ
        
        Note over Cooldown: รอ 500มิลลิวินาที
        
        Cooldown->>Cooldown: คูล = จริง
    else อาวุธกำลังคูลดาวน์
        Cooldown->>Weapon: คูล = เท็จ
        Weapon->>Player: ไม่มีการกระทำ
    end
class Cooldown {
  constructor(time) {
    this.cool = false;
    setTimeout(() => {
      this.cool = true;
    }, time);
  }
}

class Weapon {
  constructor() {
    this.cooldown = null;
  }
  
  fire() {
    if (!this.cooldown || this.cooldown.cool) {
      // สร้างกระสุนเลเซอร์
      this.cooldown = new Cooldown(500);
    } else {
      // อาวุธยังอยู่ในช่วงระบายความร้อน
    }
  }
}

ระบบ cooldown ทำงานว่า:

  • เมื่อสร้าง จะเริ่มสถานะ "ร้อน" (ยิงไม่ได้ทันที)
  • หลังหมดเวลารอ จะกลายเป็น "เย็น" (พร้อมยิง)
  • ก่อนยิง จะเช็คว่า "อาวุธพร้อมยิงหรือยัง?"
  • ป้องกันการยิงสแปมโดยยังคงควบคุมได้ดี

อ้างอิงบทเรียนที่ 1 ในชุดเกมอวกาศเพื่อทบทวนเรื่อง cooldowns

การสร้างระบบตรวจจับการชน

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

เริ่มจากโค้ดที่มีอยู่ในบทเรียนก่อนหน้า คุณจะเพิ่มระบบตรวจจับการชนโดยมีกฎเฉพาะที่ควบคุมปฏิสัมพันธ์ของวัตถุ

💡 เคล็ดลับมือโปร: ตัว sprite ของเลเซอร์ได้ถูกรวมไว้ในโฟลเดอร์ assets ของคุณแล้วและอ้างอิงในโค้ดพร้อมใช้งานทันที

กฎการชนที่ต้องใช้งาน

กลไกเกมที่จะเพิ่ม:

  1. เลเซอร์ชนศัตรู: วัตถุศัตรูถูกทำลายเมื่อโดนเลเซอร์ยิง
  2. เลเซอร์ชนขอบจอ: เลเซอร์ถูกลบเมื่อถึงขอบบนของหน้าจอ
  3. ศัตรูและฮีโร่ชนกัน: วัตถุทั้งสองถูกทำลายเมื่อทับซ้อนกัน
  4. ศัตรูถึงขอบล่าง: สถานะเกมจบเมื่อศัตรูถึงขอบล่างจอ

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

พื้นฐานการตรวจจับการชน: ก่อนลงมือทำต้องเข้าใจ:

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

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

ความเข้าใจฟิสิกส์: ตอนนี้คุณเข้าใจ:

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

การตั้งค่าสภาพแวดล้อมพัฒนา

ข่าวดี — เราได้ตั้งค่าพื้นฐานส่วนใหญ่ไว้ให้คุณแล้ว! ไฟล์ทรัพยากรทั้งหมดและโครงสร้างพื้นฐานรอคุณอยู่ในโฟลเดอร์ your-work พร้อมให้คุณเพิ่มฟีเจอร์การตรวจจับการชนเจ๋งๆ

โครงสร้างโปรเจ็กต์

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

ความเข้าใจโครงสร้างไฟล์:

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

เริ่มเซิร์ฟเวอร์สำหรับพัฒนา

ไปที่โฟลเดอร์โปรเจ็กต์ของคุณและเริ่มเซิร์ฟเวอร์ในเครื่อง:

cd your-work
npm start

คำสั่งนี้:

  • เปลี่ยน โฟลเดอร์ไปยังโฟลเดอร์โปรเจ็กต์ของคุณ
  • เริ่ม เซิร์ฟเวอร์ HTTP ในเครื่องที่ http://localhost:5000
  • ให้บริการ ไฟล์เกมเพื่อทดสอบและพัฒนา
  • เปิดใช้งาน การพัฒนาสดด้วยการโหลดอัตโนมัติ

เปิดเบราว์เซอร์และไปที่ http://localhost:5000 เพื่อดูเกมของคุณพร้อมแสดงฮีโร่และศัตรูบนหน้าจอ

การดำเนินการทีละขั้นตอน

เหมือนกับวิธีระบบ NASA ตั้งโปรแกรมยาน Voyager เราจะทำการใช้งานระบบตรวจจับการชนทีละส่วนอย่างเป็นระบบ

flowchart TD
    A["1. ขอบเขตสี่เหลี่ยม"] --> B["2. การตรวจจับจุดตัด"]
    B --> C["3. ระบบเลเซอร์"]
    C --> D["4. การจัดการเหตุการณ์"]
    D --> E["5. กฎการชน"]
    E --> F["6. ระบบคูลดาวน์"]
    
    G["ขอบเขตวัตถุ"] --> A
    H["อัลกอริทึมฟิสิกส์"] --> B
    I["การสร้างกระสุน"] --> C
    J["การป้อนข้อมูลแป้นพิมพ์"] --> D
    K["ตรรกะเกม"] --> E
    L["การจำกัดอัตรา"] --> F
    
    F --> M["🎮 เกมสมบูรณ์"]
    
    style A fill:#e3f2fd
    style B fill:#e8f5e8
    style C fill:#fff3e0
    style D fill:#f3e5f5
    style E fill:#e0f2f1
    style F fill:#fce4ec
    style M fill:#e1f5fe

1. เพิ่มขอบเขตสี่เหลี่ยมสำหรับการชน

เริ่มต้นด้วยการสอนวัตถุเกมของคุณให้บอกขอบเขตของตัวเอง เพิ่มเมธอดนี้ในคลาส GameObject ของคุณ:

rectFromGameObject() {
    return {
      top: this.y,
      left: this.x,
      bottom: this.y + this.height,
      right: this.x + this.width,
    };
  }

เมธอดนี้ทำอะไร:

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

2. ใช้งานฟังก์ชันตรวจจับการทับซ้อน

ตอนนี้เราจะสร้างนักสืบการชน—a ฟังก์ชันที่บอกได้ว่าสี่เหลี่ยมสองสี่เหลี่ยมทับซ้อนกันหรือไม่:

function intersectRect(r1, r2) {
  return !(
    r2.left > r1.right ||
    r2.right < r1.left ||
    r2.top > r1.bottom ||
    r2.bottom < r1.top
  );
}

อัลกอริทึมนี้ทำงานโดย:

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

3. สร้างระบบยิงเลเซอร์

ตรงนี้จะเริ่มมันส์! เรามาตั้งระบบยิงเลเซอร์กัน

ค่าคงที่ข้อความ

เริ่มด้วยการกำหนดประเภทข้อความเพื่อให้ส่วนต่างๆ ของเกมสื่อสารกันได้:

KEY_EVENT_SPACE: "KEY_EVENT_SPACE",
COLLISION_ENEMY_LASER: "COLLISION_ENEMY_LASER",
COLLISION_ENEMY_HERO: "COLLISION_ENEMY_HERO",

ค่าคงที่เหล่านี้ให้:

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

เพิ่มการตรวจจับปุ่ม space ในอีเวนต์ลิสต์เนอร์ของคุณ:

} else if(evt.keyCode === 32) {
  eventEmitter.emit(Messages.KEY_EVENT_SPACE);
}

ตัวจัดการป้อนข้อมูลนี้:

  • ตรวจจับ การกดปุ่ม space (keyCode 32)
  • ส่งออก ข้อความเหตุการณ์มาตรฐาน
  • เปิดใช้งาน ลอจิกการยิงที่แยกส่วน
การตั้งค่าอีเวนต์ลิสต์เนอร์

ลงทะเบียนพฤติกรรมยิงในฟังก์ชัน initGame() ของคุณ:

eventEmitter.on(Messages.KEY_EVENT_SPACE, () => {
 if (hero.canFire()) {
   hero.fire();
 }
});

อีเวนต์ลิสต์เนอร์นี้:

  • ตอบสนอง ต่อเหตุการณ์กดปุ่ม space
  • ตรวจสอบ สถานะ cooldown การยิง
  • เปิดใช้งาน การสร้างเลเซอร์เมื่อพร้อม

เพิ่มการจัดการการชนระหว่างเลเซอร์และศัตรู:

eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => {
  first.dead = true;
  second.dead = true;
});

ตัวจัดการการชนนี้:

  • รับ ข้อมูลเหตุการณ์ชนพร้อมวัตถุทั้งสอง
  • ทำเครื่องหมาย วัตถุทั้งคู่เพื่อลบ
  • รับประกัน การทำความสะอาดอย่างเหมาะสมหลังการชน

4. สร้างคลาส Laser

สร้างวัตถุกระสุนเลเซอร์ที่เคลื่อนที่ขึ้นบนและจัดการวงจรชีวิตตัวเอง:

class Laser extends GameObject {
  constructor(x, y) {
    super(x, y);
    this.width = 9;
    this.height = 33;
    this.type = 'Laser';
    this.img = laserImg;
    
    let id = setInterval(() => {
      if (this.y > 0) {
        this.y -= 15;
      } else {
        this.dead = true;
        clearInterval(id);
      }
    }, 100);
  }
}

การใช้งานคลาสนี้:

  • ขยาย จาก GameObject เพื่อสืบทอดฟังก์ชันพื้นฐาน
  • ตั้งค่า ขนาดที่เหมาะสมสำหรับ sprite เลเซอร์
  • สร้าง การเคลื่อนที่ขึ้นโดยอัตโนมัติด้วย setInterval()
  • จัดการ การทำลายตัวเองเมื่อถึงขอบบนหน้าจอ
  • บริหาร เวลาแอนิเมชันและการลบตัวเอง

5. ใช้งานระบบตรวจจับการชน

สร้างฟังก์ชันตรวจจับการชนที่ครอบคลุม:

function updateGameObjects() {
  const enemies = gameObjects.filter(go => go.type === 'Enemy');
  const lasers = gameObjects.filter(go => go.type === "Laser");
  
  // ทดสอบการชนกันระหว่างเลเซอร์กับศัตรู
  lasers.forEach((laser) => {
    enemies.forEach((enemy) => {
      if (intersectRect(laser.rectFromGameObject(), enemy.rectFromGameObject())) {
        eventEmitter.emit(Messages.COLLISION_ENEMY_LASER, {
          first: laser,
          second: enemy,
        });
      }
    });
  });

  // ลบวัตถุที่ถูกทำลายแล้ว
  gameObjects = gameObjects.filter(go => !go.dead);
}

ระบบการชนนี้:

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

⚠️ สำคัญ: เพิ่ม updateGameObjects() ลงในลูปเกมหลักใน window.onload เพื่อเปิดใช้งานการตรวจจับการชน

6. เพิ่มระบบ cooldown ในคลาส Hero

เพิ่มฟีเจอร์ยิงและระบบจำกัดอัตราการยิงในคลาส Hero:

class Hero extends GameObject {
  constructor(x, y) {
    super(x, y);
    this.width = 99;
    this.height = 75;
    this.type = "Hero";
    this.speed = { x: 0, y: 0 };
    this.cooldown = 0;
  }
  
  fire() {
    gameObjects.push(new Laser(this.x + 45, this.y - 10));
    this.cooldown = 500;

    let id = setInterval(() => {
      if (this.cooldown > 0) {
        this.cooldown -= 100;
      } else {
        clearInterval(id);
      }
    }, 200);
  }
  
  canFire() {
    return this.cooldown === 0;
  }
}

ความเข้าใจคลาส Hero ที่ปรับปรุง:

  • เริ่มต้น ตัวจับเวลาคูลดาวน์ที่ศูนย์ (พร้อมยิง)
  • สร้าง วัตถุเลเซอร์ที่ตำแหน่งเหนือตัวฮีโร่
  • ตั้งค่า เวลารอคูลดาวน์ เพื่อป้องกันการยิงรวดเร็วเกินไป
  • ลด ตัวจับเวลาคูลดาวน์ด้วยการอัปเดตแบบช่วงเวลา
  • ตรวจสอบ สถานะการยิงได้ผ่านเมธอด canFire()

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

เข้าใจระบบครบถ้วน: ตรวจสอบความชำนาญของคุณกับระบบชน:

  • ขอบเขตสี่เหลี่ยมช่วยให้ตรวจจับชนอย่างมีประสิทธิภาพอย่างไร?
  • ทำไมการจัดการวงจรชีวิตวัตถุจึงสำคัญต่อความเสถียรของเกม?
  • ระบบ cooldown ป้องกันปัญหาประสิทธิภาพอย่างไร?
  • สถาปัตยกรรมขับเคลื่อนด้วยเหตุการณ์ช่วยจัดการการชนอย่างไร?

การรวมระบบ: ระบบตรวจจับชนของคุณแสดงให้เห็น:

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

รูปแบบมืออาชีพ: คุณได้ใช้งาน:

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

ทดสอบการใช้งานของคุณ

เกมอวกาศของคุณตอนนี้มีระบบตรวจจับการชนและกลไกการต่อสู้ครบถ้วนแล้ว 🚀 ทดสอบสิ่งใหม่ๆ เหล่านี้:

  • เลื่อนด้วยปุ่มลูกศร เพื่อตรวจสอบการควบคุมการเคลื่อนที่
  • ยิงเลเซอร์ด้วยปุ่ม spacebar — สังเกตว่าการ cooldown ป้องกันการยิงสแปม
  • สังเกตการชนเมื่อเลเซอร์ยิงโดนศัตรู และเกิดการลบวัตถุ
  • ตรวจสอบการทำความสะอาดวัตถุที่ถูกทำลายหายไปจากเกม

คุณได้สร้างระบบตรวจจับการชนที่ใช้หลักการทางคณิตศาสตร์เดียวกับที่นำทางยานอวกาศและหุ่นยนต์แล้ว

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

  • เปิด DevTools ของเบราว์เซอร์และตั้งเบรกพอยต์ในฟังก์ชันตรวจจับการชน
  • ทดลองแก้ไขความเร็วเลเซอร์หรือการเคลื่อนที่ของศัตรูเพื่อดูผลของการชน
  • ทดลองค่าคูลดาวน์ต่างๆ เพื่อทดสอบอัตราการยิง
  • เพิ่มคำสั่ง console.log เพื่อติดตามเหตุการณ์การชนแบบเรียลไทม์

🎯 สิ่งที่คุณสามารถทำได้ในชั่วโมงนี้

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

📅 โปรแกรมฟิสิกส์ตลอดสัปดาห์ของคุณ

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

🌟 ความเชี่ยวชาญฟิสิกส์เกมตลอดเดือนของคุณ

  • สร้างเกมด้วยเอนจินฟิสิกส์ขั้นสูงและการจำลองที่สมจริง
  • เรียนรู้อัลกอริทึมการตรวจจับการชน 3D และการแบ่งพื้นที่
  • มีส่วนร่วมในไลบรารีฟิสิกส์และเอนจินเกมแบบโอเพนซอร์ส
  • เชี่ยวชาญการปรับแต่งประสิทธิภาพสำหรับแอปพลิเคชันที่ใช้กราฟิกสูง
  • สร้างเนื้อหาการศึกษาเกี่ยวกับฟิสิกส์เกมและการตรวจจับการชน
  • สร้างผลงานเพื่อโชว์ทักษะการเขียนโปรแกรมฟิสิกส์ขั้นสูง

🎯 ไทม์ไลน์ความชำนาญด้านการตรวจจับการชนของคุณ

timeline
    title ความก้าวหน้าการเรียนรู้การตรวจจับการชน & ฟิสิกส์เกม
    
    section พื้นฐาน (10 นาที)
        Rectangle Math: ระบบพิกัด
                      : การคำนวณขอบเขต
                      : การติดตามตำแหน่ง
                      : การจัดการมิติ
        
    section การออกแบบอัลกอริทึม (20 นาที)
        Intersection Logic: การทดสอบการแยก
                          : การตรวจจับการทับซ้อน
                          : การปรับปรุงประสิทธิภาพ
                          : การจัดการกรณีขอบ
        
    section การประยุกต์ใช้ในเกม (30 นาที)
        Object Systems: การจัดการวงจรชีวิต
                      : การประสานงานเหตุการณ์
                      : การติดตามสถานะ
                      : การทำความสะอาดหน่วยความจำ
        
    section คุณสมบัติอินเทอร์แอคทีฟ (40 นาที)
        Combat Mechanics: ระบบโพรเจกไทล์
                        : การหน่วงเวลาอาวุธ
                        : การคำนวณความเสียหาย
                        : การตอบสนองภาพ
        
    section ฟิสิกส์ขั้นสูง (50 นาที)
        Real-time Systems: การปรับอัตราเฟรม
                         : การแบ่งพื้นที่
                         : การตอบสนองการชน
                         : การจำลองฟิสิกส์
        
    section เทคนิคมืออาชีพ (1 สัปดาห์)
        Game Engine Concepts: ระบบคอมโพเนนต์
                             : ท่อส่งฟิสิกส์
                             : การวัดประสิทธิภาพ
                             : การปรับแต่งข้ามแพลตฟอร์ม
        
    section การประยุกต์ใช้ในอุตสาหกรรม (1 เดือน)
        Production Skills: การปรับแต่งขนาดใหญ่
                         : การทำงานร่วมกันในทีม
                         : การพัฒนาเอนจิน
                         : การเปิดตัวบนแพลตฟอร์ม

🛠️ สรุปชุดเครื่องมือฟิสิกส์เกมของคุณ

หลังจากเสร็จสิ้นบทเรียนนี้ คุณได้เชี่ยวชาญใน:

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

การใช้งานในโลกจริง: ทักษะการตรวจจับการชนของคุณใช้ได้กับ:

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

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

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

แนวคิดการพัฒนาเกมที่ชำนาญ:

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

ระดับถัดไป: คุณพร้อมที่จะสำรวจเอนจินฟิสิกส์ขั้นสูงอย่าง Matter.js, การตรวจจับการชน 3D หรือสร้างระบบอนุภาคที่ซับซ้อนแล้ว!

🌟 สำเร็จแล้ว: คุณได้สร้างระบบปฏิสัมพันธ์ฟิสิกส์ครบวงจรพร้อมการตรวจจับการชนระดับมืออาชีพ!

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

ใช้โหมด Agent เพื่อทำภารกิจต่อไปนี้ให้สำเร็จ:

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

คำสั่ง: สร้างคลาส PowerUp ที่สืบทอดมาจาก GameObject และนำการตรวจจับการชนระหว่างฮีโร่กับพาวเวอร์อัพมาใช้ เพิ่มพาวเวอร์อัพอย่างน้อยสองประเภท: หนึ่งเพิ่มอัตราการยิง (ลดเวลาคูลดาวน์) และอีกหนึ่งสร้างโล่ป้องกันชั่วคราว รวมถึงตรรกะการเกิดพาวเวอร์อัพที่สุ่มเวลาและตำแหน่ง


🚀 ความท้าทาย

เพิ่มการระเบิด! ดูสินทรัพย์เกมใน the Space Art repo และลองเพิ่มการระเบิดเมื่อเลเซอร์ชนเอเลี่ยน

แบบทดสอบหลังบรรยาย

Post-lecture quiz

ทบทวน & ศึกษาด้วยตนเอง

ทดลองเปลี่ยนช่วงเวลาระหว่างเหตุการณ์ในเกมของคุณจนถึงตอนนี้ จะเกิดอะไรขึ้นถ้าคุณเปลี่ยนค่าพวกนี้? อ่านเพิ่มเติมเกี่ยวกับ เหตุการณ์จับเวลาด้วย JavaScript

การบ้าน

สำรวจการชน


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