|
|
4 months ago | |
|---|---|---|
| .. | ||
| solution | 8 months ago | |
| your-work | 8 months ago | |
| README.md | 4 months ago | |
| assignment.md | 6 months ago | |
README.md
สร้างเกมอวกาศ ตอนที่ 6: สิ้นสุดและเริ่มใหม่
journey
title การเดินทางสู่การจบเกมของคุณ
section เงื่อนไขการสิ้นสุด
กำหนดสถานะชนะ/แพ้: 3: Student
ดำเนินการตรวจสอบเงื่อนไข: 4: Student
จัดการการเปลี่ยนสถานะ: 4: Student
section ประสบการณ์ผู้เล่น
ออกแบบระบบตอบกลับ: 4: Student
สร้างกลไกการเริ่มต้นใหม่: 5: Student
ขัดเงาอินเทอร์เฟซผู้ใช้: 5: Student
section การรวมระบบ
จัดการวงจรชีวิตเกม: 5: Student
จัดการล้างหน่วยความจำ: 5: Student
สร้างประสบการณ์ที่สมบูรณ์: 5: Student
เกมที่ยอดเยี่ยมทุกเกมต้องมีเงื่อนไขการจบที่ชัดเจนและกลไกเริ่มใหม่ที่ราบรื่น คุณได้สร้างเกมอวกาศที่น่าประทับใจที่มีการเคลื่อนที่ การต่อสู้ และการให้คะแนนแล้ว - ตอนนี้ถึงเวลาที่จะเพิ่มส่วนสุดท้ายที่ทำให้เกมรู้สึกสมบูรณ์
เกมของคุณตอนนี้ทำงานได้ไม่สิ้นสุด เหมือนกับยานสำรวจ Voyager ที่ NASA ส่งขึ้นไปในปี 1977 - ยังเดินทางในอวกาศอยู่หลายสิบปีหลังจากนั้น แม้ว่าจะดีสำหรับการสำรวจอวกาศ แต่เกมต้องมีจุดสิ้นสุดที่กำหนดเพื่อสร้างประสบการณ์ที่น่าพึงพอใจ
วันนี้เราจะนำเงื่อนไขชนะ/แพ้ที่เหมาะสมและระบบเริ่มต้นใหม่มาใช้ เมื่อจบบทเรียนนี้ คุณจะมีเกมที่ขัดเกลาแล้วที่ผู้เล่นสามารถจบและเล่นซ้ำได้ เหมือนกับเกมอาร์เคดคลาสสิกที่เป็นตัวแทนของวงการนี้
mindmap
root((การจบเกม))
End Conditions
Victory States [สถานะชัยชนะ]
Defeat Conditions [เงื่อนไขความพ่ายแพ้]
Progress Tracking [การติดตามความคืบหน้า]
State Validation [การตรวจสอบสถานะ]
Player Feedback
Visual Messages [ข้อความภาพ]
Color Psychology [จิตวิทยาสี]
Clear Communication [การสื่อสารที่ชัดเจน]
Emotional Response [การตอบสนองทางอารมณ์]
State Management
Game Loop Control [การควบคุมลูปเกม]
Memory Cleanup [การล้างหน่วยความจำ]
Object Lifecycle [วงจรชีวิตของวัตถุ]
Event Handling [การจัดการเหตุการณ์]
Restart Systems
Input Handling [การจัดการอินพุต]
State Reset [การรีเซ็ตสถานะ]
Fresh Initialization [การเริ่มต้นใหม่]
User Experience [ประสบการณ์ผู้ใช้]
Polish Elements
Message Display [การแสดงข้อความ]
Smooth Transitions [การเปลี่ยนผ่านที่ราบรื่น]
Error Prevention [การป้องกันข้อผิดพลาด]
Accessibility [การเข้าถึง]
แบบทดสอบก่อนเรียน
ความเข้าใจเกี่ยวกับเงื่อนไขการจบเกม
เกมของคุณควรจบเมื่อใด? คำถามพื้นฐานนี้ได้กำหนดการออกแบบเกมตั้งแต่ยุคแรกของอาร์เคด Pac-Man จบเมื่อคุณถูกผีจับหรือเก็บจุดทั้งหมด ในขณะที่ Space Invaders จบเมื่อมนุษย์ต่างดาวบุกถึงด้านล่างหรือถูกทำลายหมดแล้ว
ในฐานะผู้สร้างเกม คุณเป็นผู้กำหนดเงื่อนไขชนะและแพ้ สำหรับเกมอวกาศของเรา นี่คือวิธีที่พิสูจน์แล้วว่าสร้างการเล่นเกมที่น่าดึงดูดใจ:
flowchart TD
A["🎮 เริ่มเกม"] --> B{"ตรวจสอบเงื่อนไข"}
B --> C["จำนวนศัตรู"]
B --> D["ชีวิตของฮีโร่"]
B --> E["คะแนนเป้าหมาย"]
B --> F["ความก้าวหน้าในระดับ"]
C --> C1{"ศัตรู = 0?"}
D --> D1{"ชีวิต = 0?"}
E --> E1{"คะแนน ≥ เป้าหมาย?"}
F --> F1{"ทำภารกิจเสร็จสมบูรณ์?"}
C1 -->|ใช่| G["🏆 ชัยชนะ"]
D1 -->|ใช่| H["💀 แพ้"]
E1 -->|ใช่| G
F1 -->|ใช่| G
C1 -->|ไม่| B
D1 -->|ไม่| B
E1 -->|ไม่| B
F1 -->|ไม่| B
G --> I["🔄 ตัวเลือกเริ่มใหม่"]
H --> I
style G fill:#e8f5e8
style H fill:#ffebee
style I fill:#e3f2fd
- ทำลายยานศัตรู
Nลำ: เป็นเรื่องปกติถ้าคุณแบ่งเกมออกเป็นเลเวลต่างๆ ที่ต้องทำลายยานศัตรูจำนวนNเพื่อผ่านเลเวล - ยานของคุณถูกทำลาย: มีเกมหลายเกมที่คุณจะแพ้ถ้ายานตัวเองถูกทำลาย อีกวิธีหนึ่งที่ใช้คือมีแนวคิดของชีวิต ทุกครั้งที่ยานถูกทำลายจะเสียชีวิตหนึ่งครั้ง เมื่อเสียชีวิตหมดแล้วจึงแพ้
- คุณเก็บคะแนนได้
Nคะแนน: อีกเงื่อนไขการจบที่พบบ่อยคือการเก็บคะแนน วิธีที่คุณได้คะแนนขึ้นอยู่กับคุณ แต่มักจะให้คะแนนจากกิจกรรมต่างๆ เช่น ทำลายยานศัตรูหรือเก็บไอเท็มที่หล่นจากการทำลาย - ผ่านเลเวล: อาจจะรวมหลายเงื่อนไข เช่น ทำลายยานศัตรู
Xลำ, เก็บคะแนนได้Yคะแนน หรือเก็บไอเท็มเฉพาะได้
การใช้งานฟังก์ชันเริ่มเกมใหม่
เกมที่ดีสร้างความน่าสนใจให้ผู้เล่นเล่นซ้ำด้วยระบบเริ่มใหม่ที่ราบรื่น เมื่อผู้เล่นจบเกม (หรือแพ้) พวกเขามักอยากเล่นใหม่ทันที ไม่ว่าจะเพื่อทำคะแนนให้ดีกว่าหรือพัฒนาฝีมือ
stateDiagram-v2
[*] --> Playing: เริ่มเกม
Playing --> Victory: ทำลายศัตรูทั้งหมด
Playing --> Defeat: ชีวิต = 0
Victory --> MessageDisplay: แสดงข้อความชนะ
Defeat --> MessageDisplay: แสดงข้อความแพ้
MessageDisplay --> WaitingRestart: กด Enter เพื่อดำเนินการต่อ
WaitingRestart --> Resetting: กดปุ่ม Enter
Resetting --> CleanupMemory: ล้างอินเทอร์วัล
CleanupMemory --> ClearEvents: ลบผู้ฟังเหตุการณ์
ClearEvents --> InitializeGame: เริ่มต้นเกมใหม่
InitializeGame --> Playing: เกมใหม่เริ่มต้น
note right of MessageDisplay
ข้อเสนอแนะตามสี:
เขียว = ชนะ
แดง = แพ้
end note
note right of Resetting
รีเซ็ตสถานะทั้งหมด
ป้องกันการรั่วไหลของหน่วยความจำ
end note
เกม Tetris เป็นตัวอย่างที่ดีมาก: เมื่อบล็อกของคุณสูงสุดแล้ว คุณสามารถเริ่มเกมใหม่ได้ทันทีโดยไม่ต้องเข้าเมนูซับซ้อน เราจะสร้างระบบเริ่มใหม่ที่รีเซ็ตสถานะเกมให้สะอาดและพาผู้เล่นกลับมาเล่นได้อย่างรวดเร็ว
✅ ข้อคิด: นึกถึงเกมที่คุณเคยเล่น พวกมันจบเมื่อไรและพวกเขาให้คุณเริ่มใหม่อย่างไร? อะไรทำให้การเริ่มใหม่รู้สึกราบรื่นหรือหงุดหงิด?
สิ่งที่คุณจะสร้าง
คุณจะเพิ่มฟีเจอร์สุดท้ายที่เปลี่ยนโปรเจกต์ของคุณให้เป็นประสบการณ์เกมสมบูรณ์ ฟีเจอร์เหล่านี้แยกความแตกต่างระหว่างเกมที่ขัดเกลาและต้นแบบพื้นฐาน
นี่คือสิ่งที่เราจะเพิ่มวันนี้:
- เงื่อนไขชนะ: ทำลายศัตรูทั้งหมดและมีการเฉลิมฉลองอย่างเหมาะสม (สมควรแล้ว!)
- เงื่อนไขแพ้: หมดชีวิตและเผชิญหน้ากับหน้าจอแพ้
- กลไกเริ่มใหม่: กด Enter เพื่อเริ่มใหม่ทันที - เพราะเล่นเกมเดียวไม่เคยพอ
- การจัดการสถานะ: เริ่มต้นสะอาดทุกครั้ง - ไม่มีศัตรูหลงเหลือหรือบั๊กแปลกๆ จากเกมก่อนหน้า
เริ่มต้น
เตรียมสภาพแวดล้อมสำหรับการพัฒนา คุณควรมีไฟล์เกมอวกาศจากบทเรียนก่อนหน้าครบถ้วน
โปรเจกต์ของคุณควรมีโครงสร้างประมาณนี้:
-| assets
-| enemyShip.png
-| player.png
-| laserRed.png
-| life.png
-| index.html
-| app.js
-| package.json
เริ่มเซิร์ฟเวอร์สำหรับพัฒนา:
cd your-work
npm start
คำสั่งนี้:
- รันเซิร์ฟเวอร์บน
http://localhost:5000 - ให้บริการไฟล์ของคุณอย่างถูกต้อง
- รีเฟรชอัตโนมัติเมื่อคุณมีการเปลี่ยนแปลง
เปิด http://localhost:5000 บนเบราว์เซอร์และตรวจสอบว่าเกมทำงานได้ คุณควรจะสามารถเคลื่อนที่ ยิง และโต้ตอบกับศัตรูได้ เมื่อตรวจสอบแล้ว เราจะไปทำการใช้งานต่อ
💡 เคล็ดลับโปร: เพื่อหลีกเลี่ยงการเตือนใน Visual Studio Code ให้ประกาศ
gameLoopIdที่ด้านบนของไฟล์ด้วยlet gameLoopId;แทนการประกาศในฟังก์ชันwindow.onloadซึ่งเป็นแนวปฏิบัติที่ดีใน JavaScript สมัยใหม่
flowchart TD
A["1. การติดตามเงื่อนไข"] --> B["2. ตัวจัดการเหตุการณ์"]
B --> C["3. ค่าคงที่ข้อความ"]
C --> D["4. ควบคุมการเริ่มต้นใหม่"]
D --> E["5. การแสดงข้อความ"]
E --> F["6. รีเซ็ตระบบ"]
G["isHeroDead()\nisEnemiesDead()"] --> A
H["เหตุการณ์การชน\nเหตุการณ์จบเกม"] --> B
I["GAME_END_WIN\nGAME_END_LOSS"] --> C
J["ปุ่ม Enter\nตัวกระตุ้นเริ่มใหม่"] --> D
K["ชัยชนะ/ความพ่ายแพ้\nข้อความที่มีสีแยก"] --> E
L["การทำความสะอาดสถานะ\nการเริ่มต้นใหม่"] --> 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: สร้างฟังก์ชันติดตามเงื่อนไขการจบเกม
เราต้องฟังก์ชันที่ตรวจสอบว่าเกมควรจบเมื่อไร เหมือนเซนเซอร์ของสถานีอวกาศนานาชาติที่คอยตรวจตราระบบสำคัญ ฟังก์ชันเหล่านี้จะตรวจสอบสถานะเกมอย่างต่อเนื่อง
function isHeroDead() {
return hero.life <= 0;
}
function isEnemiesDead() {
const enemies = gameObjects.filter((go) => go.type === "Enemy" && !go.dead);
return enemies.length === 0;
}
สิ่งที่เกิดขึ้นใต้เครือง:
- ตรวจสอบ ว่าฮีโร่ของเราหมดชีวิตหรือยัง (เจ็บปวด!)
- นับ จำนวนศัตรูที่ยังมีชีวิตและต่อสู้ได้
- คืนค่า
trueเมื่อสนามรบปลอดศัตรู - ใช้ ลอจิกแบบ true/false ทำให้ง่ายต่อความเข้าใจ
- กรอง ผ่านวัตถุเกมทั้งหมดเพื่อหาเหล่าสมาชิกที่รอดชีวิต
ขั้นตอนที่ 2: อัปเดตตัวจัดการเหตุการณ์สำหรับเงื่อนไขการจบ
ตอนนี้เราจะเชื่อมการตรวจสอบเงื่อนไขเข้ากับระบบเหตุการณ์ของเกม ทุกครั้งที่เกิดการชน เกมจะประเมินว่ามันเป็นเหตุให้จบไหม วิธีนี้ทำให้มีฟีดแบ็กทันทีสำหรับเหตุการณ์สำคัญในเกม
sequenceDiagram
participant Collision
participant GameLogic
participant Conditions
participant EventSystem
participant Display
Collision->>GameLogic: เลเซอร์โดนศัตรู
GameLogic->>GameLogic: ทำลายวัตถุ
GameLogic->>Conditions: ตรวจสอบ isEnemiesDead()
alt ศัตรูทั้งหมดถูกกำจัด
Conditions->>EventSystem: ส่งสัญญาณ GAME_END_WIN
EventSystem->>Display: แสดงข้อความชนะ
else ศัตรูยังเหลือ
Conditions->>GameLogic: ต่อเกม
end
Collision->>GameLogic: ศัตรูชนฮีโร่
GameLogic->>GameLogic: ลดจำนวนชีวิต
GameLogic->>Conditions: ตรวจสอบ isHeroDead()
alt ชีวิต = 0
Conditions->>EventSystem: ส่งสัญญาณ GAME_END_LOSS
EventSystem->>Display: แสดงข้อความแพ้
else ชีวิตยังเหลือ
GameLogic->>Conditions: ตรวจสอบ isEnemiesDead()
alt ศัตรูทั้งหมดถูกกำจัด
Conditions->>EventSystem: ส่งสัญญาณ GAME_END_WIN
end
end
eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => {
first.dead = true;
second.dead = true;
hero.incrementPoints();
if (isEnemiesDead()) {
eventEmitter.emit(Messages.GAME_END_WIN);
}
});
eventEmitter.on(Messages.COLLISION_ENEMY_HERO, (_, { enemy }) => {
enemy.dead = true;
hero.decrementLife();
if (isHeroDead()) {
eventEmitter.emit(Messages.GAME_END_LOSS);
return; // การสูญเสียก่อนชัยชนะ
}
if (isEnemiesDead()) {
eventEmitter.emit(Messages.GAME_END_WIN);
}
});
eventEmitter.on(Messages.GAME_END_WIN, () => {
endGame(true);
});
eventEmitter.on(Messages.GAME_END_LOSS, () => {
endGame(false);
});
สิ่งที่เกิดขึ้นที่นี่:
- เลเซอร์โดนศัตรู: ทั้งคู่หายไป คุณได้คะแนน และเราตรวจสอบว่าคุณชนะหรือยัง
- ศัตรูชนคุณ: คุณเสียชีวิตหนึ่งชีวิต และเราตรวจสอบว่าคุณยังมีชีวิตอยู่ไหม
- เรียงลำดับอย่างชาญฉลาด: เราตรวจสอบการแพ้ก่อน (ไม่มีใครอยากชนะและแพ้ในเวลาเดียวกัน!)
- ตอบสนองทันที: ทันทีที่เกิดเหตุสำคัญ เกมจะรับรู้ทันที
ขั้นตอนที่ 3: เพิ่มค่าคงที่ข้อความใหม่
คุณต้องเพิ่มประเภทข้อความใหม่ในออบเจ็กต์ค่าคงที่ Messages ค่าคงที่เหล่านี้ช่วยรักษาความสม่ำเสมอและป้องกันการสะกดผิดในระบบเหตุการณ์ของคุณ
GAME_END_LOSS: "GAME_END_LOSS",
GAME_END_WIN: "GAME_END_WIN",
ในข้างต้นเราได้:
- เพิ่ม ค่าคงที่สำหรับเหตุการณ์จบเกมเพื่อความสม่ำเสมอ
- ใช้ ชื่อที่บรรยายชัดเจนเกี่ยวกับจุดประสงค์ของเหตุการณ์
- ปฏิบัติตาม คอนเวนชันการตั้งชื่อเดิมสำหรับประเภทข้อความ
ขั้นตอนที่ 4: ใช้งานการควบคุมการเริ่มเกมใหม่
ตอนนี้คุณจะเพิ่มการควบคุมผ่านคีย์บอร์ดที่ช่วยให้ผู้เล่นเริ่มเกมใหม่ได้ ปุ่ม Enter เป็นตัวเลือกที่เหมาะสมเพราะมักใช้เพื่อยืนยันการกระทำและเริ่มเกมใหม่
เพิ่มการตรวจจับปุ่ม Enter ในตัวรับฟังเหตุการณ์ keydown ที่มีอยู่:
else if(evt.key === "Enter") {
eventEmitter.emit(Messages.KEY_EVENT_ENTER);
}
เพิ่มค่าคงที่ข้อความใหม่:
KEY_EVENT_ENTER: "KEY_EVENT_ENTER",
สิ่งที่คุณต้องรู้:
- ขยาย ระบบจัดการเหตุการณ์คีย์บอร์ดที่มีอยู่แล้ว
- ใช้ ปุ่ม Enter เป็นทริกเกอร์เริ่มใหม่เพื่อประสบการณ์ผู้ใช้ที่เข้าใจง่าย
- ส่ง เหตุการณ์ที่กำหนดเองซึ่งส่วนอื่นของเกมสามารถฟังได้
- รักษา รูปแบบเดียวกับการควบคุมคีย์บอร์ดอื่นๆ
ขั้นตอนที่ 5: สร้างระบบแสดงข้อความ
เกมของคุณต้องสื่อสารผลลัพธ์ให้ผู้เล่นอย่างชัดเจน เราจะสร้างระบบข้อความที่แสดงสถานะแพ้ชนะด้วยข้อความสีต่างๆ คล้ายกับอินเทอร์เฟซเทอร์มินอลของระบบคอมพิวเตอร์ยุคแรกที่ใช้สีเขียวแสดงความสำเร็จและสีแดงแสดงข้อผิดพลาด
สร้างฟังก์ชัน displayMessage():
function displayMessage(message, color = "red") {
ctx.font = "30px Arial";
ctx.fillStyle = color;
ctx.textAlign = "center";
ctx.fillText(message, canvas.width / 2, canvas.height / 2);
}
ทีละขั้นตอน สิ่งที่เกิดขึ้น:
- ตั้งค่า ขนาดและฟอนต์เพื่อข้อความที่อ่านง่าย
- ใช้ พารามิเตอร์สี โดยค่าเริ่มต้นคือ "แดง" สำหรับคำเตือน
- จัดกึ่งกลาง ข้อความทั้งแนวนอนและแนวตั้งบนแคนวาส
- ใช้ พารามิเตอร์ดีฟอลต์ของ JavaScript เพื่อความยืดหยุ่นในสี
- ใช้ 2D context ของแคนวาสสำหรับการเรนเดอร์ข้อความโดยตรง
สร้างฟังก์ชัน endGame():
function endGame(win) {
clearInterval(gameLoopId);
// ตั้งค่าการหน่วงเวลาเพื่อให้การเรนเดอร์ที่รอดำเนินการเสร็จสมบูรณ์
setTimeout(() => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canvas.width, canvas.height);
if (win) {
displayMessage(
"Victory!!! Pew Pew... - Press [Enter] to start a new game Captain Pew Pew",
"green"
);
} else {
displayMessage(
"You died !!! Press [Enter] to start a new game Captain Pew Pew"
);
}
}, 200)
}
หน้าที่ของฟังก์ชันนี้:
- หยุด การเคลื่อนที่ทั้งหมด - ไม่มีการเคลื่อนที่ของยานหรือเลเซอร์
- หยุดชั่วครู่ (200ms) เพื่อให้เฟรมสุดท้ายวาดเสร็จ
- ล้างหน้าจอ และทาสีดำเพื่อสร้างเอฟเฟกต์ดราม่า
- แสดง ข้อความที่ต่างกันสำหรับผู้ชนะและผู้แพ้
- ใช้สี เขียวสำหรับดี และแดงสำหรับ... ไม่ค่อยดี
- บอก วิธีเริ่มใหม่แก่ผู้เล่นอย่างชัดเจน
🔄 สรุปเชิงการสอน
การจัดการสถานะเกม: ก่อนใช้งานฟังก์ชันรีเซ็ต ให้แน่ใจว่าคุณเข้าใจ:
- ✅ เงื่อนไขจบเกมกำหนดวัตถุประสงค์เพื่อการเล่นเกมได้อย่างไร
- ✅ ทำไมฟีดแบ็กด้วยภาพถึงสำคัญสำหรับความเข้าใจของผู้เล่น
- ✅ ความสำคัญของการทำความสะอาดที่เหมาะสมในการป้องกันหน่วยความจำรั่วไหล
- ✅ สถาปัตยกรรมขับเคลื่อนด้วยเหตุการณ์ช่วยให้เปลี่ยนสถานะได้อย่างเรียบร้อยอย่างไร
ทดสอบตนเองอย่างรวดเร็ว: จะเกิดอะไรขึ้นหากคุณไม่ลบตัวรับฟังเหตุการณ์เมื่อรีเซ็ต? คำตอบ: เกิดหน่วยความจำรั่วและตัวจัดการเหตุการณ์ซ้ำซ้อนทำให้เกมทำงานไม่คาดคิด
หลักการออกแบบเกม: ตอนนี้คุณกำลังใช้งาน:
- วัตถุประสงค์ที่ชัดเจน: ผู้เล่นรู้ชัดเจนว่าสิ่งใดคือความสำเร็จและความล้มเหลว
- การตอบสนองทันที: การเปลี่ยนแปลงสถานะเกมสื่อสารให้รู้ทันที
- การควบคุมของผู้ใช้: ผู้เล่นสามารถเริ่มใหม่เมื่อพร้อม
- ความน่าเชื่อถือของระบบ: การทำความสะอาดที่เหมาะสมป้องกันบั๊กและปัญหาประสิทธิภาพ
ขั้นตอนที่ 6: ใช้งานฟังก์ชันรีเซ็ตเกม
ระบบรีเซ็ตต้องทำความสะอาดสถานะเกมทั้งหมดและเริ่มเซสชันเกมใหม่เพื่อให้ผู้เล่นเริ่มต้นใหม่อย่างสะอาด ไม่มีข้อมูลตกค้างจากเกมก่อนหน้า
สร้างฟังก์ชัน resetGame():
function resetGame() {
if (gameLoopId) {
clearInterval(gameLoopId);
eventEmitter.clear();
initGame();
gameLoopId = setInterval(() => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canvas.width, canvas.height);
drawPoints();
drawLife();
updateGameObjects();
drawGameObjects(ctx);
}, 100);
}
}
มาทำความเข้าใจแต่ละส่วน:
- ตรวจสอบ ว่าตอนนี้มี game loop ทำงานอยู่หรือไม่ก่อนรีเซ็ต
- ลบ game loop ที่มีอยู่เพื่อหยุดกิจกรรมเกมทั้งหมด
- ลบ ตัวรับฟังเหตุการณ์ทั้งหมดเพื่อป้องกันหน่วยความจำรั่ว
- เริ่มใหม่ สถานะเกมด้วยออบเจ็กต์และตัวแปรใหม่
- เริ่ม game loop ใหม่พร้อมฟังก์ชันที่จำเป็นทั้งหมด
- ใช้ เวลาหน่วง 100ms เดิมเพื่อประสิทธิภาพเกมที่คงที่
เพิ่มตัวจัดการเหตุการณ์กด Enter ในฟังก์ชัน initGame():
eventEmitter.on(Messages.KEY_EVENT_ENTER, () => {
resetGame();
});
เพิ่มเมธอด clear() ให้คลาส EventEmitter ของคุณ:
clear() {
this.listeners = {};
}
จุดสำคัญที่ต้องจำ:
- เชื่อม การกดปุ่ม Enter กับฟังก์ชันรีเซ็ตเกม
- ลงทะเบียน ตัวรับฟังเหตุการณ์นี้ในตอนเริ่มเกม
- ให้วิธีล้างตัวรับฟังทั้งหมดเมื่อรีเซ็ต
- ป้องกัน หน่วยความจำรั่วโดยการล้างตัวจัดการเหตุการณ์ระหว่างเกม
- รีเซ็ต ออบเจ็กต์ listeners ให้เป็นสถานะว่างเพื่อเริ่มต้นใหม่
ยินดีด้วย! 🎉
👽 💥 🚀 คุณสร้างเกมสมบูรณ์ตั้งแต่เริ่มต้นได้สำเร็จ เหมือนนักโปรแกรมเมอร์ที่สร้างวิดีโอเกมแรกในยุค 1970 คุณได้แปลงโค้ดเป็นประสบการณ์ที่โต้ตอบได้พร้อมกลไกเกมและฟีดแบ็กของผู้ใช้ที่เหมาะสมแล้ว 🚀 💥 👽
สิ่งที่คุณทำสำเร็จ:
- ใช้งาน เงื่อนไขชนะและแพ้อย่างครบถ้วนพร้อมฟีดแบ็กของผู้ใช้
- สร้าง ระบบเริ่มเกมใหม่ที่ราบรื่นสำหรับการเล่นต่อเนื่อง
- ออกแบบ การสื่อสารสถานะเกมด้วยภาพที่ชัดเจน
- จัดการ การเปลี่ยนสถานะเกมและการทำความสะอาดซับซ้อน
- รวม ส่วนประกอบทั้งหมดเข้าด้วยกันเป็นเกมที่เล่นได้อย่างลงตัว
🔄 สรุปเชิงการสอน
ระบบพัฒนาเกมครบวงจร: เฉลิมฉลองความชำนาญในการพัฒนาเกมครบถ้วน:
- ✅ เงื่อนไขจบเกมสร้างประสบการณ์ที่น่าพึงพอใจอย่างไร
- ✅ ทำไมการจัดการสถานะที่เหมาะสมจึงสำคัญต่อความเสถียรของเกม
- ✅ ฟีดแบ็กด้วยภาพช่วยเพิ่มความเข้าใจของผู้เล่นอย่างไร
- ✅ ระบบเริ่มใหม่ช่วยรักษาผู้เล่นไว้อย่างไร
ความชำนาญระบบ: เกมที่สมบูรณ์ของคุณแสดงให้เห็น:
- พัฒนาเกมเต็มรูปแบบ: ตั้งแต่กราฟิก อินพุต ไปจนถึงการจัดการสถานะ
- สถาปัตยกรรมมืออาชีพ: ระบบขับเคลื่อนด้วยเหตุการณ์ที่ทำความสะอาดได้ดี
- ออกแบบประสบการณ์ผู้ใช้: ฟีดแบ็กชัดเจนและควบคุมได้อย่างเข้าใจง่าย
- เพิ่มประสิทธิภาพ: การเรนเดอร์และจัดการหน่วยความจำอย่างมีประสิทธิภาพ
- ความสมบูรณ์และขัดเกลา: รายละเอียดทั้งหมดที่ทำให้เกมรู้สึกสมบูรณ์
ทักษะพร้อมใช้งานในอุตสาหกรรม: คุณใช้งาน:
- สถาปัตยกรรมเกมลูป: ระบบเรียลไทม์ที่มีประสิทธิภาพคงที่
- การเขียนโปรแกรมขับเคลื่อนด้วยเหตุการณ์: ระบบแยกกันที่สามารถขยายได้ดี
- การจัดการสถานะ: การจัดการข้อมูลซับซ้อนและวงจรชีวิต
- ออกแบบส่วนติดต่อผู้ใช้: สื่อสารชัดเจนและควบคุมตอบสนอง
- การทดสอบและดีบัก: การพัฒนาแบบวนซ้ำและแก้ปัญหา
⚡ สิ่งที่คุณสามารถทำได้ใน 5 นาทีถัดไป
- เล่นเกมสมบูรณ์และทดสอบทุกเงื่อนไขชนะและแพ้
- ทดลองเปลี่ยนพารามิเตอร์เงื่อนไขจบเกมต่างๆ
- เพิ่มคำสั่ง console.log เพื่อติดตามสถานะเกม
- แชร์เกมของคุณกับเพื่อนและรับคำติชม
🎯 สิ่งที่คุณสามารถทำได้ในชั่วโมงนี้
- ทำแบบทดสอบหลังเรียนและสะท้อนเส้นทางพัฒนาของคุณ
- เพิ่มเอฟเฟกต์เสียงสำหรับสถานะแพ้และชนะ
- ใช้งานเงื่อนไขจบเกมเพิ่มเติม เช่น จำกัดเวลา หรือภารกิจโบนัส
- สร้างระดับความยากต่างๆ ด้วยจำนวนศัตรูที่แตกต่างกัน
- ขัดเกลาการแสดงผลด้วยฟอนต์และสีที่ดียิ่งขึ้น
📅 การฝึกฝนพัฒนาเกมตลอดสัปดาห์ของคุณ
- ทำเกมอวกาศขั้นสูงที่มีหลายเลเวลและการพัฒนา
- เพิ่มฟีเจอร์ขั้นสูง เช่น power-ups, ศัตรูประเภทต่างๆ และอาวุธพิเศษ
- สร้างระบบคะแนนสูงที่เก็บข้อมูลได้ถาวร
- ออกแบบอินเทอร์เฟซสำหรับเมนู การตั้งค่า และตัวเลือกเกม
- ปรับปรุงประสิทธิภาพสำหรับอุปกรณ์และเบราว์เซอร์ต่างๆ
- เปิดเล่นเกมออนไลน์และแชร์กับชุมชน
🌟 สายอาชีพพัฒนาเกมของคุณตลอดหนึ่งเดือน
- สร้างเกมหลายเกมที่สมบูรณ์แบบโดยสำรวจแนวเกมและกลไกที่แตกต่างกัน
- เรียนรู้เฟรมเวิร์กพัฒนาเกมขั้นสูงอย่าง Phaser หรือ Three.js
- ร่วมช่วยพัฒนาโปรเจกต์เกมโอเพนซอร์ส
- ศึกษาหลักการออกแบบเกมและจิตวิทยาผู้เล่น
- สร้างผลงานเพื่อแสดงทักษะการพัฒนาเกมของคุณ
- ติดต่อสื่อสารกับชุมชนผู้พัฒนาเกมและเรียนรู้ต่อเนื่อง
🎯 ไทม์ไลน์ความเชี่ยวชาญการพัฒนาเกมของคุณ
timeline
title ความก้าวหน้าในการเรียนรู้การพัฒนาเกมครบถ้วน
section พื้นฐาน (บทเรียนที่ 1-2)
สถาปัตยกรรมเกม: โครงสร้างโปรเจกต์
: การจัดการทรัพยากร
: พื้นฐานแคนวาส
: ระบบเหตุการณ์
section ระบบปฏิสัมพันธ์ (บทเรียนที่ 3-4)
การควบคุมผู้เล่น: การจัดการอินพุต
: กลไกการเคลื่อนไหว
: การตรวจจับการชน
: การจำลองฟิสิกส์
section กลไกเกม (บทเรียนที่ 5)
ระบบตอบสนอง: กลไกการให้คะแนน
: การจัดการชีวิต
: การสื่อสารด้วยภาพ
: แรงจูงใจผู้เล่น
section การจบเกม (บทเรียนที่ 6)
การขัดเกลา & การไหล: เงื่อนไขการสิ้นสุด
: การจัดการสถานะ
: ระบบเริ่มต้นใหม่
: ประสบการณ์ผู้ใช้
section ฟีเจอร์ขั้นสูง (1 สัปดาห์)
ทักษะการเสริม: การผสานเสียง
: เอฟเฟกต์ภาพ
: ความก้าวหน้าของระดับ
: การเพิ่มประสิทธิภาพ
section การพัฒนาเชิงมืออาชีพ (1 เดือน)
ความพร้อมในอุตสาหกรรม: ความเชี่ยวชาญในเฟรมเวิร์ก
: การทำงานเป็นทีม
: การพัฒนาผลงาน
: การมีส่วนร่วมกับชุมชน
section ความก้าวหน้าในอาชีพ (3 เดือน)
ความชำนาญพิเศษ: เอนจินเกมขั้นสูง
: การนำไปใช้บนแพลตฟอร์ม
: กลยุทธ์การสร้างรายได้
: การสร้างเครือข่ายในอุตสาหกรรม
🛠️ สรุปชุดเครื่องมือพัฒนาเกมครบวงจรของคุณ
หลังจากจบซีรีส์เกมอวกาศทั้งหมดนี้ คุณได้เชี่ยวชาญในเรื่อง:
- สถาปัตยกรรมเกม: ระบบขับเคลื่อนด้วยเหตุการณ์, วงจรเกม, และการจัดการสถานะ
- การเขียนโปรแกรมกราฟิก: Canvas API, การแสดง sprite, และเอฟเฟกต์ภาพ
- ระบบอินพุต: การจัดการคีย์บอร์ด, ตรวจจับการชน, และการควบคุมที่ตอบสนอง
- การออกแบบเกม: การตอบรับผู้เล่น, ระบบความก้าวหน้า, และกลไกการดึงดูด
- การเพิ่มประสิทธิภาพ: การเรนเดอร์ที่มีประสิทธิผล, การจัดการหน่วยความจำ, และคุมเฟรมเรต
- ประสบการณ์ผู้ใช้: การสื่อสารที่ชัดเจน, การควบคุมที่เข้าใจง่าย, และรายละเอียดงานขัดเกลา
- รูปแบบการพัฒนาเชิงมืออาชีพ: โค้ดที่สะอาด, เทคนิคดีบัก, และการจัดการโปรเจกต์
การประยุกต์ใช้ในโลกจริง: ทักษะการพัฒนาเกมของคุณนำไปใช้ได้โดยตรงกับ:
- แอปพลิเคชันเว็บแบบโต้ตอบ: อินเทอร์เฟซที่มีการไดนามิกและระบบเรียลไทม์
- การแสดงข้อมูล: แผนภูมิที่มีแอนิเมชันและกราฟิกแบบโต้ตอบ
- เทคโนโลยีเพื่อการศึกษา: การทำเกมเป็นบทเรียนและประสบการณ์การเรียนรู้ที่น่าสนใจ
- การพัฒนาโมบาย: การโต้ตอบด้วยสัมผัสและการเพิ่มประสิทธิภาพ
- ซอฟต์แวร์จำลองสถานการณ์: เอนจินฟิสิกส์และการจำลองแบบเรียลไทม์
- อุตสาหกรรมสร้างสรรค์: ศิลปะโต้ตอบ, ความบันเทิง, และประสบการณ์ดิจิทัล
ทักษะเชิงมืออาชีพที่ได้รับ: ตอนนี้คุณสามารถ:
- ออกแบบสถาปัตยกรรม ระบบโต้ตอบที่ซับซ้อนตั้งแต่เริ่มต้น
- ดีบัก แอปพลิเคชันแบบเรียลไทม์ด้วยวิธีการเป็นระบบ
- เพิ่มประสิทธิภาพ เพื่อประสบการณ์ใช้งานที่ราบรื่น
- ออกแบบ อินเทอร์เฟซและรูปแบบการโต้ตอบที่น่าสนใจ
- ร่วมมือ ในโปรเจกต์เชิงเทคนิคได้อย่างมีประสิทธิภาพโดยจัดการโค้ดดี
แนวคิดพัฒนาการเกมที่เชี่ยวชาญ:
- ระบบแบบเรียลไทม์: วงจรเกม, การควบคุมเฟรมเรต, และประสิทธิภาพ
- สถาปัตยกรรมขับเคลื่อนด้วยเหตุการณ์: ระบบแยกส่วนและกระบวนการส่งข้อความ
- การจัดการสถานะ: การจัดการข้อมูลซับซ้อนและวงจรชีวิต
- การเขียนโปรแกรมอินเทอร์เฟซผู้ใช้: กราฟิก Canvas และการออกแบบตอบสนอง
- ทฤษฎีการออกแบบเกม: จิตวิทยาผู้เล่นและกลไกการดึงดูด
ระดับถัดไป: คุณพร้อมที่จะสำรวจเฟรมเวิร์กเกมขั้นสูง กราฟิก 3D ระบบผู้เล่นหลายคน หรือเปลี่ยนไปสู่บทบาทนักพัฒนาเกมมืออาชีพ!
🌟 สำเร็จแล้ว: คุณได้ทำเสร็จสิ้นเส้นทางพัฒนาเกมเต็มรูปแบบและสร้างประสบการณ์โต้ตอบคุณภาพมืออาชีพขึ้นมาได้ตั้งแต่ต้น!
ยินดีต้อนรับสู่ชุมชนผู้พัฒนาเกม! 🎮✨
ความท้าทาย GitHub Copilot Agent 🚀
ใช้โหมด Agent เพื่อทำความท้าทายต่อไปนี้ให้สำเร็จ:
คำอธิบาย: ปรับปรุงเกมอวกาศโดยเพิ่มระบบความก้าวหน้าระดับที่มีความยากเพิ่มขึ้นพร้อมฟีเจอร์โบนัส
พรอมต์: สร้างระบบเกมอวกาศหลายระดับ โดยแต่ละระดับจะมีเรือศัตรูมากขึ้นด้วยความเร็วและพลังชีวิตที่เพิ่มขึ้น เพิ่มตัวคูณคะแนนที่เพิ่มขึ้นตามระดับ และเพิ่ม power-ups (เช่น ยิงเร็วหรือเกราะ) ที่สุ่มปรากฏเมื่อศัตรูถูกทำลาย รวมโบนัสจบระดับและแสดงระดับปัจจุบันบนหน้าจอพร้อมคะแนนและชีวิตเดิม
เรียนรู้เพิ่มเติมเกี่ยวกับ agent mode ที่นี่
🚀 ความท้าทายเสริม (ไม่บังคับ)
เพิ่มเสียงในเกมของคุณ: เพิ่มประสบการณ์เล่นเกมของคุณด้วยการเพิ่มเอฟเฟกต์เสียง! พิจารณาเพิ่มเสียงสำหรับ:
- เสียงเลเซอร์ เมื่อผู้เล่นยิง
- เสียงศัตรูถูกทำลาย เมื่อเรือโดนโจมตี
- เสียงฮีโร่ถูกโจมตี เมื่อผู้เล่นได้รับความเสียหาย
- เสียงเพลงชัยชนะ เมื่อชนะเกม
- เสียงพ่ายแพ้ เมื่อแพ้เกม
ตัวอย่างการใช้งานเสียง:
// สร้างวัตถุเสียง
const laserSound = new Audio('assets/laser.wav');
const explosionSound = new Audio('assets/explosion.wav');
// เล่นเสียงในระหว่างเหตุการณ์เกม
function playLaserSound() {
laserSound.currentTime = 0; // รีเซ็ตไปที่ต้นฉบับ
laserSound.play();
}
สิ่งที่ควรรู้:
- สร้าง ออบเจ็กต์เสียงสำหรับเอฟเฟกต์เสียงต่างๆ
- รีเซ็ต
currentTimeเพื่อให้เล่นเสียงซ้ำได้อย่างรวดเร็ว - จัดการ นโยบายอัตโนมัติเล่นเสียงของเบราว์เซอร์โดยเรียกเสียงจากปฏิสัมพันธ์ของผู้ใช้
- ควบคุม ความดังและเวลาของเสียงเพื่อประสบการณ์เล่นเกมที่ดีขึ้น
💡 แหล่งเรียนรู้: สำรวจ audio sandbox นี้เพื่อเรียนรู้เพิ่มเติมเกี่ยวกับการใช้งานเสียงในการพัฒนาเกม JavaScript
แบบทดสอบหลังบรรยาย
ทบทวน & ศึกษาด้วยตนเอง
ภารกิจของคุณคือการสร้างเกมตัวอย่างใหม่ ดังนั้นลองสำรวจเกมน่าสนใจต่าง ๆ เพื่อดูว่าคุณอยากสร้างเกมแบบไหน
งานมอบหมาย
ข้อจำกัดความรับผิดชอบ:
เอกสารฉบับนี้ได้รับการแปลโดยใช้บริการแปลภาษาด้วย AI Co-op Translator แม้เราจะพยายามให้ความถูกต้องสูงสุด แต่โปรดทราบว่าการแปลอัตโนมัติอาจมีข้อผิดพลาดหรือความไม่ถูกต้องได้ เอกสารต้นฉบับในภาษาดั้งเดิมถือเป็นแหล่งข้อมูลที่เชื่อถือได้ที่สุด สำหรับข้อมูลที่มีความสำคัญ แนะนำให้ใช้บริการแปลโดยมืออาชีพ เรายินดีรับผิดชอบในความเข้าใจผิดหรือการตีความที่ผิดพลาดใด ๆ ที่อาจเกิดขึ้นจากการใช้การแปลนี้