|
|
1 month ago | |
|---|---|---|
| .. | ||
| solution | 3 months ago | |
| your-work | 3 months ago | |
| README.md | 1 month ago | |
| assignment.md | 3 months ago | |
README.md
สร้างเกมอวกาศ ตอนที่ 5: คะแนนและชีวิต
แบบทดสอบก่อนเรียน
พร้อมที่จะทำให้เกมอวกาศของคุณรู้สึกเหมือนเกมจริงหรือยัง? มาเพิ่มระบบคะแนนและการจัดการชีวิตกัน - กลไกหลักที่เปลี่ยนเกมอาร์เคดยุคแรกอย่าง Space Invaders จากการสาธิตธรรมดาให้กลายเป็นความบันเทิงที่น่าติดใจ นี่คือจุดที่เกมของคุณจะกลายเป็นเกมที่เล่นได้จริง
การแสดงข้อความบนหน้าจอ - เสียงของเกมคุณ
เพื่อแสดงคะแนนของคุณ เราต้องเรียนรู้วิธีการแสดงข้อความบน canvas โดยใช้วิธี fillText() ซึ่งเป็นเครื่องมือหลักของคุณ - เป็นเทคนิคเดียวกับที่ใช้ในเกมอาร์เคดคลาสสิกเพื่อแสดงคะแนนและข้อมูลสถานะ
คุณมีการควบคุมเต็มรูปแบบเกี่ยวกับลักษณะของข้อความ:
ctx.font = "30px Arial";
ctx.fillStyle = "red";
ctx.textAlign = "right";
ctx.fillText("show this on the screen", 0, 0);
✅ ลองศึกษาเพิ่มเติมเกี่ยวกับ การเพิ่มข้อความลงใน canvas - คุณอาจจะประหลาดใจกับความสร้างสรรค์ที่คุณสามารถทำได้กับฟอนต์และการออกแบบ!
ชีวิต - มากกว่าตัวเลข
ในงานออกแบบเกม "ชีวิต" หมายถึงขอบเขตของความผิดพลาดที่ผู้เล่นสามารถทำได้ แนวคิดนี้มีมาตั้งแต่เครื่องพินบอลที่คุณจะได้ลูกบอลหลายลูกเพื่อเล่น ในเกมวิดีโอยุคแรกอย่าง Asteroids ชีวิตช่วยให้ผู้เล่นกล้าเสี่ยงและเรียนรู้จากความผิดพลาด
การแสดงผลภาพมีความสำคัญอย่างมาก - การแสดงไอคอนยานอวกาศแทนที่จะเป็นแค่ "Lives: 3" สร้างการรับรู้ทางภาพทันที คล้ายกับวิธีที่ตู้เกมอาร์เคดยุคแรกใช้ไอคอนเพื่อสื่อสารข้ามอุปสรรคทางภาษา
สร้างระบบรางวัลของเกมคุณ
ตอนนี้เราจะเพิ่มระบบตอบสนองหลักที่ทำให้ผู้เล่นมีส่วนร่วม:
- ระบบคะแนน: ทุกครั้งที่ทำลายยานศัตรูจะได้รับ 100 คะแนน (ตัวเลขกลมๆ ทำให้ผู้เล่นคำนวณได้ง่ายขึ้น) คะแนนจะแสดงที่มุมล่างซ้าย
- ตัวนับชีวิต: ฮีโร่ของคุณเริ่มต้นด้วยสามชีวิต - มาตรฐานที่กำหนดโดยเกมอาร์เคดยุคแรกเพื่อสร้างสมดุลระหว่างความท้าทายและความสามารถในการเล่น ทุกการชนกับศัตรูจะเสียชีวิตหนึ่งครั้ง เราจะแสดงชีวิตที่เหลืออยู่ที่มุมล่างขวาโดยใช้ไอคอนยานอวกาศ

มาเริ่มสร้างกันเลย!
ก่อนอื่น ตั้งค่าพื้นที่ทำงานของคุณ ไปที่ไฟล์ในโฟลเดอร์ย่อย your-work คุณควรเห็นไฟล์เหล่านี้:
-| assets
-| enemyShip.png
-| player.png
-| laserRed.png
-| index.html
-| app.js
-| package.json
เพื่อทดสอบเกมของคุณ เริ่มเซิร์ฟเวอร์พัฒนาในโฟลเดอร์ your_work:
cd your-work
npm start
เซิร์ฟเวอร์นี้จะรันที่ http://localhost:5000 เปิดที่อยู่นี้ในเบราว์เซอร์ของคุณเพื่อดูเกมของคุณ ทดสอบการควบคุมด้วยปุ่มลูกศรและลองยิงศัตรูเพื่อยืนยันว่าทุกอย่างทำงานได้
ถึงเวลาลงมือเขียนโค้ด!
-
นำทรัพย์สินภาพที่คุณต้องการมาใช้ คัดลอกไฟล์
life.pngจากโฟลเดอร์solution/assets/ไปยังโฟลเดอร์your-workจากนั้นเพิ่ม lifeImg ลงในฟังก์ชัน window.onload ของคุณ:lifeImg = await loadTexture("assets/life.png"); -
อย่าลืมเพิ่ม
lifeImgลงในรายการทรัพย์สินของคุณ:let heroImg, ... lifeImg, ... eventEmitter = new EventEmitter(); -
ตั้งค่าตัวแปรเกมของคุณ เพิ่มโค้ดเพื่อติดตามคะแนนรวมของคุณ (เริ่มต้นที่ 0) และชีวิตที่เหลืออยู่ (เริ่มต้นที่ 3) เราจะแสดงสิ่งเหล่านี้บนหน้าจอเพื่อให้ผู้เล่นรู้สถานะของตนเองเสมอ
-
เพิ่มการตรวจจับการชนกัน ขยายฟังก์ชัน
updateGameObjects()ของคุณเพื่อตรวจจับเมื่อศัตรูชนกับฮีโร่ของคุณ:enemies.forEach(enemy => { const heroRect = hero.rectFromGameObject(); if (intersectRect(heroRect, enemy.rectFromGameObject())) { eventEmitter.emit(Messages.COLLISION_ENEMY_HERO, { enemy }); } }) -
เพิ่มการติดตามชีวิตและคะแนนให้กับฮีโร่ของคุณ
-
เริ่มต้นตัวนับ ใต้
this.cooldown = 0ในคลาสHeroของคุณ ตั้งค่าชีวิตและคะแนน:this.life = 3; this.points = 0; -
แสดงค่าต่างๆ ให้ผู้เล่นเห็น สร้างฟังก์ชันเพื่อแสดงค่าต่างๆ บนหน้าจอ:
function drawLife() { // TODO, 35, 27 const START_POS = canvas.width - 180; for(let i=0; i < hero.life; i++ ) { ctx.drawImage( lifeImg, START_POS + (45 * (i+1) ), canvas.height - 37); } } function drawPoints() { ctx.font = "30px Arial"; ctx.fillStyle = "red"; ctx.textAlign = "left"; drawText("Points: " + hero.points, 10, canvas.height-20); } function drawText(message, x, y) { ctx.fillText(message, x, y); } -
เชื่อมโยงทุกอย่างเข้ากับลูปเกมของคุณ เพิ่มฟังก์ชันเหล่านี้ลงในฟังก์ชัน window.onload ของคุณหลังจาก
updateGameObjects():drawPoints(); drawLife();
-
-
เพิ่มผลกระทบและรางวัลในเกม ตอนนี้เราจะเพิ่มระบบตอบสนองที่ทำให้การกระทำของผู้เล่นมีความหมาย:
-
การชนกันทำให้เสียชีวิต ทุกครั้งที่ฮีโร่ของคุณชนกับศัตรู คุณควรเสียชีวิตหนึ่งครั้ง
เพิ่มเมธอดนี้ลงในคลาส
Heroของคุณ:decrementLife() { this.life--; if (this.life === 0) { this.dead = true; } } -
การยิงศัตรูได้รับคะแนน ทุกครั้งที่ยิงโดนจะได้รับ 100 คะแนน ซึ่งเป็นการตอบสนองเชิงบวกทันทีสำหรับการยิงที่แม่นยำ
ขยายคลาส Hero ของคุณด้วยเมธอดเพิ่มคะแนนนี้:
incrementPoints() { this.points += 100; }ตอนนี้เชื่อมโยงฟังก์ชันเหล่านี้กับเหตุการณ์การชนกัน:
eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => { first.dead = true; second.dead = true; hero.incrementPoints(); }) eventEmitter.on(Messages.COLLISION_ENEMY_HERO, (_, { enemy }) => { enemy.dead = true; hero.decrementLife(); });
-
✅ สนใจเกมอื่นๆ ที่สร้างด้วย JavaScript และ Canvas? ลองสำรวจดู - คุณอาจจะทึ่งกับสิ่งที่เป็นไปได้!
หลังจากเพิ่มฟีเจอร์เหล่านี้ ทดสอบเกมของคุณเพื่อดูระบบตอบสนองที่สมบูรณ์แบบในเกม คุณควรเห็นไอคอนชีวิตที่มุมล่างขวา คะแนนของคุณที่มุมล่างซ้าย และดูว่าการชนกันลดชีวิตลงในขณะที่การยิงที่สำเร็จเพิ่มคะแนนของคุณ
เกมของคุณตอนนี้มีกลไกสำคัญที่ทำให้เกมอาร์เคดยุคแรกน่าดึงดูด - เป้าหมายที่ชัดเจน การตอบสนองทันที และผลกระทบที่มีความหมายต่อการกระทำของผู้เล่น
GitHub Copilot Agent Challenge 🚀
ใช้โหมด Agent เพื่อทำภารกิจต่อไปนี้:
คำอธิบาย: เพิ่มระบบคะแนนของเกมอวกาศโดยการสร้างฟีเจอร์คะแนนสูงสุดที่มีการจัดเก็บแบบถาวรและกลไกการให้คะแนนโบนัส
คำสั่ง: สร้างระบบคะแนนสูงสุดที่บันทึกคะแนนที่ดีที่สุดของผู้เล่นลงใน localStorage เพิ่มคะแนนโบนัสสำหรับการฆ่าศัตรูต่อเนื่อง (ระบบคอมโบ) และเพิ่มค่าคะแนนที่แตกต่างกันสำหรับศัตรูแต่ละประเภท รวมถึงตัวบ่งชี้ภาพเมื่อผู้เล่นทำคะแนนสูงสุดใหม่ และแสดงคะแนนสูงสุดปัจจุบันบนหน้าจอเกม
🚀 ความท้าทาย
ตอนนี้คุณมีเกมที่ใช้งานได้พร้อมระบบคะแนนและชีวิต ลองพิจารณาว่าฟีเจอร์เพิ่มเติมใดที่อาจช่วยเพิ่มประสบการณ์ของผู้เล่น
แบบทดสอบหลังเรียน
ทบทวนและศึกษาด้วยตนเอง
อยากสำรวจเพิ่มเติม? ศึกษาแนวทางต่างๆ ในการสร้างระบบคะแนนและชีวิตในเกม มีเอนจินเกมที่น่าสนใจอย่าง PlayFab ที่จัดการคะแนน กระดานผู้นำ และการพัฒนาผู้เล่น การรวมสิ่งเหล่านี้เข้ากับเกมของคุณจะช่วยยกระดับเกมไปอีกขั้นได้อย่างไร?
งานที่ได้รับมอบหมาย
ข้อจำกัดความรับผิดชอบ:
เอกสารนี้ได้รับการแปลโดยใช้บริการแปลภาษา AI Co-op Translator แม้ว่าเราจะพยายามให้การแปลมีความถูกต้อง แต่โปรดทราบว่าการแปลโดยอัตโนมัติอาจมีข้อผิดพลาดหรือความไม่ถูกต้อง เอกสารต้นฉบับในภาษาดั้งเดิมควรถือเป็นแหล่งข้อมูลที่เชื่อถือได้ สำหรับข้อมูลที่สำคัญ ขอแนะนำให้ใช้บริการแปลภาษามืออาชีพ เราไม่รับผิดชอบต่อความเข้าใจผิดหรือการตีความผิดที่เกิดจากการใช้การแปลนี้