|
|
7 months ago | |
|---|---|---|
| .. | ||
| solution | 7 months ago | |
| your-work | 7 months ago | |
| README.md | 7 months ago | |
| assignment.md | 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 ของคุณแล้วและอ้างอิงในโค้ดพร้อมใช้งานทันที
กฎการชนที่ต้องใช้งาน
กลไกเกมที่จะเพิ่ม:
- เลเซอร์ชนศัตรู: วัตถุศัตรูถูกทำลายเมื่อโดนเลเซอร์ยิง
- เลเซอร์ชนขอบจอ: เลเซอร์ถูกลบเมื่อถึงขอบบนของหน้าจอ
- ศัตรูและฮีโร่ชนกัน: วัตถุทั้งสองถูกทำลายเมื่อทับซ้อนกัน
- ศัตรูถึงขอบล่าง: สถานะเกมจบเมื่อศัตรูถึงขอบล่างจอ
🔄 เช็กความเข้าใจเชิงการสอน
พื้นฐานการตรวจจับการชน: ก่อนลงมือทำต้องเข้าใจ:
- ✅ วิธีการที่ขอบเขตของสี่เหลี่ยมกำหนดโซนการชน
- ✅ ทำไมการทดสอบแยกส่วนจึงมีประสิทธิภาพกว่าการคำนวณทับซ้อนโดยตรง
- ✅ ความสำคัญของการจัดการวงจรชีวิตของวัตถุในลูปเกม
- ✅ วิธีการที่ระบบขับเคลื่อนด้วยเหตุการณ์ประสานงานการตอบสนองการชน
ทดสอบตัวเองอย่างรวดเร็ว: จะเกิดอะไรขึ้นถ้าคุณลบวัตถุทันทีแทนที่จะทำเครื่องหมาย? คำตอบ: การลบระหว่างลูปจะทำให้เกิดข้อผิดพลาดหรือข้ามวัตถุในการวนลูป
ความเข้าใจฟิสิกส์: ตอนนี้คุณเข้าใจ:
- ระบบพิกัด: วิธีที่ตำแหน่งและขนาดสร้างขอบเขต
- ตรรกะการทับซ้อน: หลักคณิตศาสตร์เบื้องหลังการตรวจจับการชน
- การเพิ่มประสิทธิภาพการทำงาน: ทำไมอัลกอริทึมที่มีประสิทธิภาพจึงสำคัญในระบบเรียลไทม์
- การจัดการหน่วยความจำ: รูปแบบการจัดการวงจรชีวิตวัตถุที่ปลอดภัยสำหรับความเสถียร
การตั้งค่าสภาพแวดล้อมพัฒนา
ข่าวดี — เราได้ตั้งค่าพื้นฐานส่วนใหญ่ไว้ให้คุณแล้ว! ไฟล์ทรัพยากรทั้งหมดและโครงสร้างพื้นฐานรอคุณอยู่ในโฟลเดอร์ 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 และลองเพิ่มการระเบิดเมื่อเลเซอร์ชนเอเลี่ยน
แบบทดสอบหลังบรรยาย
ทบทวน & ศึกษาด้วยตนเอง
ทดลองเปลี่ยนช่วงเวลาระหว่างเหตุการณ์ในเกมของคุณจนถึงตอนนี้ จะเกิดอะไรขึ้นถ้าคุณเปลี่ยนค่าพวกนี้? อ่านเพิ่มเติมเกี่ยวกับ เหตุการณ์จับเวลาด้วย JavaScript
การบ้าน
ข้อจำกัดความรับผิดชอบ: เอกสารนี้ได้รับการแปลโดยใช้บริการแปลด้วย AI Co-op Translator แม้ว่าเราจะพยายามให้ความถูกต้อง โปรดทราบว่าการแปลอัตโนมัติอาจมีข้อผิดพลาดหรือความคลาดเคลื่อน เอกสารต้นฉบับในภาษาต้นฉบับถือเป็นแหล่งข้อมูลที่เชื่อถือได้ สำหรับข้อมูลที่สำคัญ ขอแนะนำให้ใช้การแปลโดยมืออาชีพที่เป็นมนุษย์ เราไม่มีความรับผิดชอบต่อความเข้าใจผิดหรือการตีความที่ผิดพลาดใด ๆ ที่เกิดจากการใช้การแปลนี้