วิธีสร้างเกมเสมือนจริงแบบผู้เล่นหลายคนแบบเรียลไทม์ (ตอนที่ 1)
เผยแพร่แล้ว: 2022-03-10ในซีรีส์บทช่วยสอนนี้ เราจะสร้างเกมเสมือนจริงแบบผู้เล่นหลายคนบนเว็บ ซึ่งผู้เล่นจะต้องร่วมมือกันไขปริศนา เราจะใช้ A-Frame สำหรับการสร้างแบบจำลอง VR, MirrorVR สำหรับการซิงโครไนซ์แบบเรียลไทม์ข้ามอุปกรณ์ และ A-Frame Low Poly เพื่อความสวยงามแบบโพลีต่ำ ในตอนท้ายของบทช่วยสอนนี้ คุณจะมีเดโมออนไลน์ที่ใช้งานได้อย่างสมบูรณ์ซึ่งทุกคนสามารถเล่นได้
ผู้เล่นแต่ละคู่จะได้รับแหวนลูกกลม เป้าหมายคือการ "เปิด" ลูกกลมทั้งหมด โดยที่ลูกกลมจะ "เปิด" หากอยู่สูงและสว่าง ลูกกลมจะ "ปิด" ถ้ามันอยู่ต่ำกว่าและสลัว อย่างไรก็ตาม ลูกกลม "เด่น" บางลูกส่งผลกระทบต่อเพื่อนบ้าน: ถ้ามันเปลี่ยนสถานะ เพื่อนบ้านก็เปลี่ยนสถานะด้วย มีเพียงผู้เล่น 2 เท่านั้นที่สามารถควบคุม orb ที่โดดเด่นได้ ในขณะที่ผู้เล่น 1 เท่านั้นที่สามารถควบคุม orb ที่ไม่โดดเด่นได้ สิ่งนี้บังคับให้ผู้เล่นทั้งสองร่วมมือกันไขปริศนา ในส่วนแรกของบทช่วยสอนนี้ เราจะสร้างสภาพแวดล้อมและเพิ่มองค์ประกอบการออกแบบสำหรับเกม VR ของเรา
เจ็ดขั้นตอนในบทช่วยสอนนี้แบ่งออกเป็นสามส่วน:
- การจัดฉาก (ขั้นตอนที่ 1–2)
- การสร้างลูกแก้ว (ขั้นตอนที่ 3-5)
- ทำให้ลูกแก้วโต้ตอบได้ (ขั้นตอนที่ 6–7)
ส่วนแรกนี้จะจบลงด้วยลูกแก้วที่คลิกได้ซึ่งเปิดและปิด (ดังภาพด้านล่าง) คุณจะใช้ A-Frame VR และส่วนขยาย A-Frame หลายรายการ
การจัดฉาก
1. ไปกับฉากพื้นฐานกันเถอะ
ในการเริ่มต้น มาดูว่าเราจะสร้างฉากง่ายๆ กับพื้นได้อย่างไร:
คำแนะนำสามข้อแรกด้านล่างคัดลอกมาจากบทความก่อนหน้าของฉัน คุณจะเริ่มต้นด้วยการตั้งค่าเว็บไซต์ด้วยหน้า HTML แบบคงที่หน้าเดียว สิ่งนี้ทำให้คุณสามารถเขียนโค้ดจากเดสก์ท็อปของคุณและปรับใช้กับเว็บได้โดยอัตโนมัติ เว็บไซต์ที่ปรับใช้แล้วสามารถโหลดบนโทรศัพท์มือถือของคุณและวางไว้ในชุดหูฟัง VR เว็บไซต์ที่ปรับใช้สามารถโหลดได้ด้วยชุดหูฟัง VR แบบสแตนด์อโลน
เริ่มต้นโดยไปที่ glitch.com จากนั้นทำดังต่อไปนี้:
- คลิกที่ "โครงการใหม่" ที่ด้านบนขวา
- คลิกที่ "สวัสดีหน้าเว็บ" ในเมนูแบบเลื่อนลง
- ถัดไป ให้คลิกที่ index.html ในแถบด้านข้างทางซ้าย เราจะเรียกสิ่งนี้ว่า "บรรณาธิการ" ของคุณ
ตอนนี้คุณควรเห็นหน้าจอ Glitch ต่อไปนี้พร้อมไฟล์ HTML เริ่มต้น
เช่นเดียวกับบทช่วยสอนที่เชื่อมโยงด้านบน ให้เริ่มต้นด้วยการลบโค้ดที่มีอยู่ทั้งหมดในไฟล์ index.html ปัจจุบัน จากนั้นพิมพ์ข้อมูลต่อไปนี้สำหรับโปรเจ็กต์ webVR พื้นฐาน โดยใช้ A-Frame VR สิ่งนี้จะสร้างฉากที่ว่างเปล่าโดยใช้แสงและกล้องเริ่มต้นของ A-Frame
<!DOCTYPE html> <html> <head> <title>Lightful</title> <script src="https://aframe.io/releases/0.8.0/aframe.min.js"></script> </head> <body> <a-scene> </a-scene> </body> </html>
ยกกล้องขึ้นสูงขณะยืน ตามคำแนะนำ A-Frame VR (ปัญหา Github) ห่อกล้องด้วยเอนทิตีใหม่และย้ายเอนทิตีหลักแทนกล้องโดยตรง ระหว่างแท็ก a-scene
ในบรรทัดที่ 8 ถึง 9 ให้เพิ่มสิ่งต่อไปนี้
<!-- Camera! --> <a-entity position="0 3 0"> <a-camera wasd-controls look-controls></a-camera> </a-entity>
ถัดไป ให้เพิ่มกล่องขนาดใหญ่เพื่อแสดงพื้นโดยใช้ a-box
วางสิ่งนี้ไว้ใต้กล้องของคุณโดยตรงจากคำแนะนำก่อนหน้า
<!-- Action! --> <a-box shadow width="75" height="0.1" depth="75" position="0 -1 0" color="#222"></a-box>
ไฟล์ index.html ของคุณควรตรงกับข้อมูลต่อไปนี้ทุกประการ คุณสามารถค้นหาซอร์สโค้ดแบบเต็มได้ที่นี่บน Github
<html> <head> <title>Lightful</title> <script src="https://aframe.io/releases/0.8.0/aframe.min.js"></script> </head> <body> <a-scene> <!-- Camera! --> <a-entity position="0 3 0"> <a-camera wasd-controls look-controls></a-camera> </a-entity> <!-- Action! --> <a-box shadow width="75" height="0.1" depth="75" position="0 -1 0" color="#222"></a-box> </a-scene> </body> </html>
นี้สรุปการตั้งค่า ต่อไป เราจะปรับแต่งแสงเพื่อให้บรรยากาศลึกลับยิ่งขึ้น
2. เพิ่มบรรยากาศ
ในขั้นตอนนี้ เราจะตั้งค่าไฟตัดหมอกและไฟแบบปรับแต่งเอง
เพิ่มหมอกซึ่งจะบดบังวัตถุที่อยู่ห่างไกลสำหรับเรา แก้ไขแท็ก a-scene
ในบรรทัดที่ 8 ในที่นี้ เราจะเพิ่มหมอกสีดำที่บดบังขอบพื้นดินอย่างรวดเร็ว ทำให้เกิดเอฟเฟกต์ของเส้นขอบฟ้าที่ห่างไกล
<a-scene fog="type: linear; color: #111; near:10; far:15"></a-scene>
สีเทาเข้ม #111
จางลงเป็นเส้นตรงจากระยะ 10 ถึงระยะ 15 วัตถุทั้งหมดที่อยู่ห่างออกไป 15 หน่วยถูกบดบังอย่างสมบูรณ์ และวัตถุทั้งหมดที่อยู่ห่างออกไปน้อยกว่า 10 หน่วยจะมองเห็นได้อย่างสมบูรณ์ วัตถุใด ๆ ในระหว่างนั้นถูกบดบังบางส่วน
เพิ่มแสงรอบข้างเพื่อทำให้วัตถุในเกมสว่างขึ้น และแสงทิศทางเดียวเพื่อเน้นพื้นผิวสะท้อนแสงที่คุณจะเพิ่มในภายหลัง วางไว้หลังแท็ก a-scene
คุณแก้ไขในคำสั่งก่อนหน้าโดยตรง
<!-- Lights! --> <a-light type="directional" castshadow="true" intensity="0.5" color="#FFF" position="2 5 0"></a-light> <a-light intensity="0.1" type="ambient" position="1 1 1" color="#FFF"></a-light>
ใต้แสงไฟในคำแนะนำก่อนหน้าโดยตรง ให้เพิ่มท้องฟ้าที่มืดมิด สังเกตสีเทาเข้ม #111
ตรงกับหมอกที่อยู่ห่างไกล
<a-sky color="#111"></a-sky>
นี่เป็นการสรุปการปรับเปลี่ยนอารมณ์พื้นฐานและการตั้งค่าฉากในวงกว้างมากขึ้น ตรวจสอบว่ารหัสของคุณตรงกับซอร์สโค้ดสำหรับขั้นตอนที่ 2 บน Github ทุกประการ ต่อไป เราจะเพิ่มลูกแก้วโพลีต่ำ และเริ่มปรับแต่งความสวยงามของลูกแก้ว
การสร้างลูกกลม
3. สร้างลูกโลกโพลีต่ำ
ในขั้นตอนนี้ เราจะสร้างลูกแก้วสะท้อนแสงที่หมุนได้ดังภาพด้านล่าง ลูกกลมประกอบด้วยทรงกลมทรงโพลีต่ำสองลูกที่มีสไตล์พร้อมลูกเล่นเล็กๆ น้อยๆ เพื่อแนะนำวัสดุสะท้อนแสง
เริ่มต้นด้วยการนำเข้าไลบรารี low-poly ในแท็ก head
ของคุณ แทรกสิ่งต่อไปนี้ระหว่างบรรทัดที่ 4 และ 5
<script src="https://cdn.jsdelivr.net/gh/alvinwan/[email protected]/dist/aframe-low-poly.min.js"></script>
สร้างม้าหมุน เครื่องห่อ และภาชนะลูกกลม วง carousel
จะมีลูกกลมหลายลูก wrapper
จะช่วยให้เราหมุนลูกกลมทั้งหมดรอบแกนกลางโดยไม่ต้องหมุนลูกกลมแต่ละลูกแยกกัน และ container
จะมีส่วนประกอบลูกกลมทั้งหมดตามชื่อ
<a-entity> <a-entity rotation="0 90 0" class="wrapper" position="0 0 0"> <a-entity class="container" position="8 3 0" scale="1 1 1"> <!-- place orb here --> </a-entity> </a-entity> </a-entity>
ภายในที่บรรจุลูกกลม ให้เพิ่มลูกกลมเข้าไปเอง: ทรงกลมหนึ่งจะโปร่งแสงและออฟเซ็ตเล็กน้อย และอีกอันเป็นของแข็งอย่างสมบูรณ์ พื้นผิวสะท้อนแสงเลียนแบบทั้งสองแบบรวมกัน
<a-entity class="orb" data-> <lp-sphere seed="0" shadow max-amplitude="1 1 1" position="-0.5 0 -0.5"></lp-sphere> <lp-sphere seed="0" shadow max-amplitude="1 1 1" rotation="0 45 45" opacity="0.5" position="-0.5 0 -0.5"></lp-sphere> </a-entity>
สุดท้าย หมุนทรงกลมไปเรื่อย ๆ โดยเพิ่มแท็ก a-animation
ต่อไปนี้ทันทีหลังจาก lp-sphere
ภายในเอนทิตี . .orb
ในคำสั่งสุดท้าย
<a-animation attribute="rotation" repeat="indefinite" from="0 0 0" to="0 360 0" dur="5000"></a-animation>
ซอร์สโค้ดของคุณสำหรับ orb wrappers และ orb เองควรตรงกับสิ่งต่อไปนี้ทุกประการ
<a-entity> <a-entity rotation="0 90 0" class="wrapper" position="0 0 0"> <a-entity class="container" position="8 3 0" scale="1 1 1"> <a-entity class="orb" data-> <lp-sphere seed="0" shadow max-amplitude="1 1 1" position="-0.5 0 -0.5"></lp-sphere> <lp-sphere seed="0" shadow max-amplitude="1 1 1" rotation="0 45 45" opacity="0.5" position="-0.5 0 -0.5"></lp-sphere> <a-animation attribute="rotation" repeat="indefinite" from="0 0 0" to="0 360 0" dur="5000"></a-animation> </a-entity> </a-entity> </a-entity> </a-entity>
ตรวจสอบว่าซอร์สโค้ดของคุณตรงกับซอร์สโค้ดแบบเต็มสำหรับขั้นตอนที่ 3 บน Github การแสดงตัวอย่างของคุณควรจะตรงกับสิ่งต่อไปนี้
ต่อไป เราจะเพิ่มแสงให้กับลูกแก้วมากขึ้นเพื่อให้เป็นสีทอง
4. ส่องสว่างลูกโลก
ในขั้นตอนนี้ เราจะเพิ่มไฟสองดวง แสงสีหนึ่งและไฟสีขาวอีกหนึ่งดวง สิ่งนี้สร้างเอฟเฟกต์ต่อไปนี้
เริ่มต้นด้วยการเพิ่มแสงสีขาวเพื่อทำให้วัตถุสว่างขึ้นจากด้านล่าง เราจะใช้ไฟส่องเฉพาะจุด ก่อน #orb0
แต่ภายใน #container-orb0
ให้เพิ่มไฟจุดออฟเซ็ตต่อไปนี้
<a-entity position="-2 -1 0"> <a-light distance="8" type="point" color="#FFF" intensity="0.8"></a-light> </a-entity>
ในการแสดงตัวอย่างของคุณ คุณจะเห็นสิ่งต่อไปนี้
โดยค่าเริ่มต้น ไฟจะไม่สลายไปตามระยะทาง โดยการเพิ่ม distance="8"
เรามั่นใจว่าแสงจะสลายตัวเต็มที่ด้วยระยะห่าง 8 หน่วย เพื่อป้องกันไม่ให้แสงจุดส่องไปทั่วทั้งฉาก ถัดไปเพิ่มแสงสีทอง เพิ่มสิ่งต่อไปนี้โดยตรงเหนือแสงสุดท้าย
<a-light class="light-orb" distance="8" type="point" color="#f90" intensity="1"></a-light>
ตรวจสอบว่าโค้ดของคุณตรงกับซอร์สโค้ดสำหรับขั้นตอนที่ 4 ทุกประการ การแสดงตัวอย่างของคุณจะตรงกับรายการต่อไปนี้
ถัดไป คุณจะทำการปรับเปลี่ยนความงามขั้นสุดท้ายกับลูกโลกและเพิ่มวงแหวนหมุน
5. เพิ่มแหวน
ในขั้นตอนนี้ คุณจะสร้างลูกแก้วสุดท้ายดังภาพด้านล่าง
เพิ่มวงแหวนใน #container-orb0
โดยตรงก่อน #orb0
<a-ring color="#fff" material="side:double" position="0 0.5 0" radius-inner="1.9" radius-outer="2" opacity="0.25"></a-ring>
สังเกตว่าตัววงแหวนไม่มีสี เนื่องจากสีจะอิ่มตัวด้วยไฟจุดในขั้นตอนที่แล้ว ยิ่งไปกว่านั้น material="side:double"
นั้นมีความสำคัญ เนื่องจากหากไม่มีแล้ว ด้านหลังของวงแหวนก็จะไม่แสดงผล นี่หมายความว่าแหวนจะหายไปครึ่งรอบของการหมุน
อย่างไรก็ตาม การแสดงตัวอย่างที่มีเพียงโค้ดด้านบนเท่านั้นจะไม่แตกต่างไปจากนี้ เนื่องจากขณะนี้วงแหวนตั้งฉากกับหน้าจอ ดังนั้นจะมองเห็นเฉพาะ "ด้าน" ของวงแหวน (ซึ่งมีความหนา 0) เท่านั้น วางแอนิเมชั่นต่อไปนี้ไว้ระหว่างแท็ก a-ring
ในคำสั่งก่อนหน้า
<a-animation attribute="rotation" easing="linear" repeat="indefinite" from="0 0 0" to="0 360 0" dur="8000"></a-animation>
การแสดงตัวอย่างของคุณควรจะตรงกับสิ่งต่อไปนี้:
สร้างจำนวนวงแหวนที่แปรผันได้โดยมีแกนหมุน ความเร็ว และขนาดต่างกัน คุณสามารถใช้วงแหวนตัวอย่างต่อไปนี้ ควรวางวงแหวนใหม่ไว้ใต้ a-ring
สุดท้าย
<a-ring color="#fff" material="side:double" position="0 0.5 0" radius-inner="2.4" radius-outer="2.5" opacity="0.25"> <a-animation attribute="rotation" easing="linear" repeat="indefinite" from="0 45 0" to="360 45 0" dur="8000"></a-animation> </a-ring> <a-ring color="#fff" material="side:double" position="0 0.5 0" radius-inner="1.4" radius-outer="1.5" opacity="0.25"> <a-animation attribute="rotation" easing="linear" repeat="indefinite" from="0 -60 0" to="-360 -60 0" dur="3000"></a-animation> </a-ring>
การแสดงตัวอย่างของคุณจะตรงกับรายการต่อไปนี้
ตรวจสอบว่าโค้ดของคุณตรงกับซอร์สโค้ดสำหรับขั้นตอนที่ 5 บน Github จบการตกแต่งสำหรับลูกกลม เมื่อลูกแก้วเสร็จแล้ว ต่อไปเราจะเพิ่มการโต้ตอบให้กับลูกแก้ว ในขั้นตอนต่อไป เราจะเพิ่มเคอร์เซอร์ที่มองเห็นได้ด้วยภาพเคลื่อนไหวการคลิกโดยเฉพาะเมื่อชี้ไปที่วัตถุที่คลิกได้
ทำให้ Orbs Interactive
6. เพิ่มเคอร์เซอร์
ในขั้นตอนนี้ เราจะเพิ่มเคอร์เซอร์สีขาวที่สามารถเรียกวัตถุที่คลิกได้ เคอร์เซอร์เป็นภาพด้านล่าง
ในแท็ก a-camera
ของคุณ ให้เพิ่มเอนทิตีต่อไปนี้ แอตทริบิวต์ fuse
ช่วยให้เอนทิตีนี้สามารถทริกเกอร์เหตุการณ์การคลิกได้ แอตทริบิวต์ raycaster
กำหนดความถี่และระยะในการตรวจสอบวัตถุที่คลิกได้ แอตทริบิวต์ objects
ยอมรับตัวเลือกเพื่อกำหนดว่าเอนทิตีใดบ้างที่สามารถคลิกได้ ในกรณีนี้ ออบเจ็กต์ทั้งหมดของคลาสที่ clickable
สามารถคลิกได้
<a-entity cursor="fuse: true; fuseTimeout: 250" position="0 0 -1" geometry="primitive: ring; radiusInner: 0.03; radiusOuter: 0.04" material="color: white; shader: flat; opacity: 0.5" scale="0.5 0.5 0.5" raycaster="far: 20; interval: 1000; objects: .clickable"> <!-- Place cursor animation here --> </a-entity>
ถัดไป เพิ่มแอนิเมชั่นเคอร์เซอร์และวงแหวนเสริมเพื่อความสวยงาม วางสิ่งต่อไปนี้ภายในวัตถุเคอร์เซอร์เอนทิตีด้านบน การทำเช่นนี้จะเพิ่มภาพเคลื่อนไหวให้กับวัตถุเคอร์เซอร์เพื่อให้มองเห็นการคลิกได้
<a-circle radius="0.01" color="#FFF" opacity="0.5" material="shader: flat"></a-circle> <a-animation begin="fusing" easing="ease-in" attribute="scale" fill="backwards" from="1 1 1" to="0.2 0.2 0.2" dur="250"></a-animation>
ถัดไป เพิ่มคลาสที่ clickable
ใน #orb0
เพื่อให้ตรงกับสิ่งต่อไปนี้
<a-entity class="orb clickable" data->
ตรวจสอบว่าโค้ดของคุณตรงกับซอร์สโค้ดสำหรับขั้นตอนที่ 6 บน Github ในการแสดงตัวอย่าง ให้ลากเคอร์เซอร์ออกจากเคอร์เซอร์ไปยังออร์บเพื่อดูการทำงานของแอนิเมชั่นการคลิก นี่คือภาพด้านล่าง
โปรดทราบว่าแอตทริบิวต์ที่คลิกได้ถูกเพิ่มไปยัง orb เอง ไม่ใช่คอนเทนเนอร์ของ orb เพื่อป้องกันไม่ให้วงแหวนกลายเป็นวัตถุที่คลิกได้ ด้วยวิธีนี้ ผู้ใช้จะต้องคลิกที่ทรงกลมที่ประกอบเป็นลูกกลมเอง
ในขั้นตอนสุดท้ายของเราในส่วนนี้ คุณจะเพิ่มแอนิเมชั่นเพื่อควบคุมสถานะเปิดและปิดของออร์บ
7. เพิ่มสถานะลูกโลก
ในขั้นตอนนี้ คุณจะเคลื่อนไหวลูกโลกเข้าและออกจากสถานะปิดเมื่อคลิก นี่คือภาพด้านล่าง
ในการเริ่มต้น คุณจะต้องย่อและลดขนาดลูกโลกลงกับพื้น เพิ่มแท็ก a-animation
ใน #container-orb0
หลัง #orb0
ภาพเคลื่อนไหวทั้งสองถูกทริกเกอร์โดยการคลิกและใช้ฟังก์ชันการค่อยๆ เปลี่ยนแบบเดียวกัน ease-elastic
สำหรับการตีกลับเล็กน้อย
<a-animation class="animation-scale" easing="ease-elastic" begin="click" attribute="scale" from="0.5 0.5 0.5" to="1 1 1" direction="alternate" dur="2000"></a-animation> <a-animation class="animation-position" easing="ease-elastic" begin="click" attribute="position" from="8 0.5 0" to="8 3 0" direction="alternate" dur="2000"></a-animation>
เพื่อเน้นย้ำถึงสถานะปิด เราจะเอาแสงจุดสีทองออกเมื่อลูกกลมปิดอยู่ อย่างไรก็ตาม ไฟของลูกกลมจะถูกวางไว้นอกวัตถุลูกกลม ดังนั้น เหตุการณ์การคลิกจะไม่ถูกส่งไปยังแสงไฟเมื่อมีการคลิกลูกโลก เพื่อหลีกเลี่ยงปัญหานี้ เราจะใช้ light Javascript เพื่อส่งเหตุการณ์ click ไปที่ light วางแท็กภาพเคลื่อนไหวต่อไปนี้ใน #light-orb0
ไฟถูกกระตุ้นโดยเหตุการณ์ switch
แบบกำหนดเอง
<a-animation class="animation-intensity" begin="switch" attribute="intensity" from="0" to="1" direction="alternate"></a-animation>
ถัดไป เพิ่มตัวฟังเหตุการณ์คลิกต่อไปนี้ใน #container-orb0
สิ่งนี้จะถ่ายทอดการคลิกไปยังไฟลูกโลก
<a-entity ...>
ตรวจสอบว่ารหัสของคุณตรงกับซอร์สโค้ดสำหรับขั้นตอนที่ 7 บน Github สุดท้าย ดึงภาพตัวอย่างของคุณขึ้นมา และเลื่อนเคอร์เซอร์ไปเปิดและปิดออร์บเพื่อสลับระหว่างสถานะเปิดและปิด นี่คือภาพด้านล่าง
นี้สรุปการโต้ตอบของลูกกลม ตอนนี้ผู้เล่นสามารถเปิดและปิด orb ได้ตามต้องการ โดยมีสถานะการเปิดและปิดที่อธิบายตนเองได้
บทสรุป
ในบทช่วยสอนนี้ คุณได้สร้างออร์บอย่างง่ายที่มีสถานะเปิดและปิด ซึ่งสามารถสลับได้ด้วยการคลิกเคอร์เซอร์ที่เหมาะกับชุดหูฟัง VR ด้วยเทคนิคการจัดแสงและแอนิเมชั่นที่หลากหลาย คุณจึงสามารถแยกแยะความแตกต่างระหว่างสองสถานะนี้ได้ นี่เป็นการสรุปองค์ประกอบการออกแบบเสมือนจริงสำหรับลูกกลม ในส่วนถัดไปของบทช่วยสอน เราจะเติม orbs แบบไดนามิก เพิ่มกลไกของเกม และตั้งค่าโปรโตคอลการสื่อสารระหว่างผู้เล่นสองคน