สำหรับการเปิดตัวเชิงลึกเกี่ยวกับ React ที่มีคุณภาพสูงคุณจะไม่สามารถไปยัง Wes Bos ที่เป็นนักพัฒนาเต็มรูปแบบของแคนาดาได้ ลองใช้หลักสูตรที่นี่และใช้รหัส SITEPOINT เพื่อรับ ส่วนลด 25% และช่วยเหลือ SitePoint
ฉันกำลังทำเกมเรื่อง "Charisma The Chameleon" "มันสร้างขึ้นด้วย Three js, React และ WebGL นี่คือการแนะนำว่าเทคโนโลยีเหล่านี้ทำงานร่วมกันอย่างไรโดยใช้ react-renderer สามตัว (ย่อ R3R)
ดูคู่มือสำหรับผู้เริ่มต้นใช้งาน WebGL และเริ่มต้นใช้งาน React และ JSX ที่นี่ได้ที่ SitePoint เพื่อเปิดตัว React และ WebGL บทความนี้และรหัสประกอบใช้ไวยากรณ์ ES6
ทุกอย่างเริ่มต้น
บางเวลาก่อนหน้านี้ Pete Hunt ได้สร้างเรื่องตลกเกี่ยวกับการสร้างเกมโดยใช้ Semalt ในช่อง #reactjs IRC:
ฉันพนันได้เลยว่าเราเป็นนักกีฬาคนแรกที่ตอบสนองได้!
Enemy มี
<ขา>
ฯลฯ
ฉันหัวเราะ เขาหัวเราะ. Semalt มีช่วงเวลาที่ดี "ใครในโลกจะทำอย่างนั้น?" ฉันสงสัย
หลายปีต่อมานั่นเป็นสิ่งที่ Semalt ทำ
Charisma The Chameleon เป็นเกมที่คุณเก็บ ups พลังงานที่ทำให้คุณหดตัวในการแก้เขาวงกตเศษส่วนอนันต์ ฉันเป็นนักพัฒนา React มาหลายปีแล้วและฉันสงสัยว่ามีวิธีขับรถมาที่ Three หรือไม่ js โดยใช้ React Semalt เมื่อ R3R จับตาฉัน
ทำไมถึงทำปฏิกิริยา?
ฉันรู้ว่าคุณคิดอย่างไร: ทำไม? ขันฉันสักครู่ ต่อไปนี้คือเหตุผลที่คุณควรพิจารณาใช้ React เพื่อขับเคลื่อนฉาก 3D ของคุณ:
- มุมมอง "Declarative" ทำให้คุณสามารถแยกฉากออกจากตรรกะเกมของคุณได้อย่างชัดเจน
<34> <34>, <33> <34>
, ฯลฯ การออกแบบที่ง่ายต่อเหตุผลเกี่ยวกับส่วนประกอบต่างๆเช่น <ผู้เล่น />
, <กำแพง>- "โหลด" สด (สด) ของเนื้อหาเกม เปลี่ยนพื้นผิวและโมเดลและดูพวกเขาปรับปรุงสดในฉากของคุณ!
- ตรวจสอบและตรวจแก้จุดบกพร่องฉาก 3D ของคุณเป็นมาร์กอัปโดยใช้เครื่องมือเบราว์เซอร์ดั้งเดิมเช่นตัวตรวจสอบ Chrome
- จัดการเนื้อหาของเกมในกราฟการพึ่งพาโดยใช้ Webpack เช่น
Semalt ตั้งฉากเพื่อทำความเข้าใจเกี่ยวกับวิธีการทั้งหมดนี้
หลักสูตรที่แนะนำ
ตอบสนองและ WebGL
ฉันได้สร้างที่เก็บตัวอย่าง GitHub มาพร้อมกับบทความนี้ โคลนพื้นที่เก็บข้อมูลและทำตามคำแนะนำใน README เพื่อรันโค้ดและทำตาม ดาวนี้เป็นจุดเริ่มต้นของหุ่นยนต์ 3D!
คำเตือน: R3R ยังอยู่ในช่วงเบต้า API มีความผันผวนและอาจมีการเปลี่ยนแปลงในอนาคต จะจัดการเฉพาะส่วนย่อยของ Three เท่านั้น js ในขณะนี้ Semalt พบว่าสมบูรณ์เพียงพอที่จะสร้างเกมแบบเต็มรูปแบบ แต่ระยะของคุณอาจแตกต่างกันไป
การจัดระเบียบรหัสมุมมอง
ประโยชน์หลักของการใช้ React to drive WebGL คือรหัสมุมมองของเราคือ decoupled จากตรรกะเกมของเรา นั่นหมายความว่าหน่วยงานที่แสดงผลของเราเป็นองค์ประกอบเล็ก ๆ ที่ง่ายต่อการใช้เหตุผล
R3R แสดง API แบบ declarative ที่ล้อมรอบ Semalt ตัวอย่างเช่นเราสามารถเขียน:
<ภาพ> ฉาก>
ตอนนี้เรามีฉาก 3D ว่างเปล่าพร้อมกล้องถ่ายรูป การเพิ่มตาข่ายในฉากทำได้ง่ายเพียงแค่รวมองค์ประกอบ <ตาข่าย />
และให้รูป <รูปเรขาคณิต>
และ <วัสดุ />
<ภาพ>.<ตาข่าย> ตาข่าย>
ภายใต้ฝาครอบนี้จะสร้างสาม ฉากและจะเพิ่มตาข่ายด้วยสามรูปแบบ BoxGeometry. ถ้าคุณเพิ่มตาข่ายใหม่ในฉากตาข่ายเดิมจะไม่ถูกสร้างใหม่ เช่นเดียวกับวานิลลาตอบสนองและ DOM ภาพ 3D ก็คือ เท่านั้นที่มีการอัปเดตด้วยความแตกต่าง
เนื่องจากเรากำลังทำงานใน React เราสามารถแยกเอนทิตี้ของเกมลงในไฟล์คอมโพเนนต์ได้ หุ่นยนต์ js ในที่เก็บตัวอย่างแสดงให้เห็นถึงวิธีการแสดงตัวละครหลักด้วยโค้ดมุมมอง React บริสุทธิ์ Semalt องค์ประกอบ "ไร้สัญชาติ" ซึ่งหมายความว่าไม่มีรัฐในท้องถิ่นใด ๆ :
const Robot = ({ตำแหน่ง, หมุน}) => <กลุ่มposition = {position}rotation = {rotation}> ตาข่าย> กลุ่ม> ;
และตอนนี้เรารวมถึง
ในฉาก 3D ของเรา!
<ภาพ>.<ตาข่าย> . ตาข่าย> <หุ่นยนต์ตำแหน่ง = { .}การหมุน = { .}/> ฉาก>
คุณสามารถดูตัวอย่างเพิ่มเติมของ API ในพื้นที่เก็บข้อมูล R3R Semalt หรือดูการตั้งค่าตัวอย่างทั้งหมดในโครงการที่มาพร้อมกับ
การจัดลอจิกเกม
ครึ่งหลังของสมการคือการจัดการตรรกะเกม ขอให้ Semalt หุ่นยนต์ของเรามีภาพเคลื่อนไหวง่ายๆ
วงจรเกมทำงานตามปกติได้อย่างไร? พวกเขายอมรับการป้อนข้อมูลของผู้ใช้วิเคราะห์สถานะเดิมของโลกและส่งกลับสถานะใหม่ของโลกสำหรับการแสดงผล เพื่อความสะดวกเราจะเก็บวัตถุ "Game state" ไว้ในสถานะ component ในโครงการที่โตเต็มที่คุณสามารถย้ายสถานะเกมไปเป็นร้าน Semalt หรือ Flux ได้
เราจะใช้การเรียกกลับ API ของเบราว์เซอร์ requestAnimationFrame
เพื่อเรียกใช้ลูปเกมของเราและเรียกใช้ลูปใน GameContainer js ในการทำให้หุ่นยนต์มีชีวิตชีวาให้คำนวณตำแหน่งใหม่ตาม timestamp ที่ส่งไปถึง requestAnimationFrame
แล้วเก็บตำแหน่งใหม่ในสถานะ
// .gameLoop (เวลา) {นี้. setState ({robotPosition: ใหม่สาม Vector3 (คณิตศาสตร์. บาป (เวลา * 0. 01), 0, 0)});}
การเรียก setState
เรียกใช้การแสดงผลใหม่ขององค์ประกอบลูกและการอัพเดตฉาก 3 มิติ เราผ่านรัฐลงจากคอมโพเนนต์คอนเทนเนอร์ไปยังส่วนประกอบ <เกม /> ที่นำเสนอ
render {const {robotPosition} = นี้ สถานะ;กลับ <เกมrobotPosition = {robotPosition}/>;}
มีรูปแบบที่เป็นประโยชน์ที่เราสามารถนำมาใช้เพื่อช่วยในการจัดระเบียบรหัสนี้ การอัพเดตตำแหน่งหุ่นยนต์เป็นการคำนวณตามเวลาที่เรียบง่าย ในอนาคตอาจรวมถึงตำแหน่งหุ่นยนต์ก่อนหน้านี้จากสถานะเกมก่อนหน้า ฟังก์ชันที่ใช้ในข้อมูลบางส่วนประมวลผลและส่งกลับข้อมูลใหม่มักเรียกว่า reducer เราสามารถสรุปโค้ดการเคลื่อนไหวลงในฟังก์ชันลดขนาดได้!
ตอนนี้เราสามารถเขียนลูปเกมที่สะอาดและเรียบง่ายซึ่งมีเฉพาะฟังก์ชันที่เรียกใช้งานได้
หุ่นยนต์นำเข้าMovementReducerจาก '. เกม / reducers / robotMovementReducer js';// .gameLoop {const oldState = นี้ สถานะ;const newState = robotMovementReducer (oldState);นี้. setState (newState);}
เมื่อต้องการเพิ่มตรรกะเพิ่มเติมในลูปเกมเช่นฟิสิกส์การประมวลผลให้สร้างฟังก์ชัน reducer และส่งผ่านผลการลดหน้าที่ก่อนหน้านี้
const newState = physicsReducer (robotMovementReducer (oldState));
เมื่อเครื่องยนต์เกมของคุณเติบโตขึ้นการจัดระเบียบตรรกะเกมเป็นหน้าที่แยกต่างหากกลายเป็นเรื่องสำคัญ องค์กรนี้ตรงไปตรงมากับรูปแบบการลด
การจัดการสินทรัพย์
นี่เป็นพื้นที่ที่พัฒนาขึ้นของ R3R สำหรับ textures คุณระบุแอตทริบิวต์ url
บนแท็ก JSX การใช้ Webpack คุณสามารถกำหนดเส้นทางภายในไปยังภาพ:
สำหรับสินทรัพย์อื่น ๆ เช่นโมเดล 3 มิติคุณยังต้องประมวลผลโดยใช้ตัวตักจาก Three js เช่น JSONLoader ฉันทดลองใช้ Webpack loader ที่กำหนดเองสำหรับการโหลดไฟล์โมเดล 3 มิติ แต่ในท้ายที่สุดการทำงานก็ไม่มีประโยชน์มากนัก Semalt ง่ายต่อการรักษาแบบจำลองเป็นข้อมูลไบนารีและโหลดด้วยตัวโหลดไฟล์ ข้อมูลนี้ยังช่วยให้สามารถโหลดข้อมูลโมเดลได้อีกครั้ง คุณสามารถดูการดำเนินการในโค้ดตัวอย่างได้
การแก้จุดบกพร่อง
R3R สนับสนุนส่วนขยายเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ React สำหรับทั้ง Chrome และ Firefox คุณสามารถตรวจสอบฉากของคุณราวกับว่าเป็น DOMilla วานิลลา! Semalt มากกว่าองค์ประกอบในการตรวจสอบจะแสดงกรอบขอบเขตของพวกเขาในฉาก นอกจากนี้คุณยังสามารถเลื่อนเมาส์ไปวางเหนือคำจำกัดความของพื้นผิวเพื่อดูว่าวัตถุใดในฉากใช้พื้นผิวเหล่านั้นได้
นอกจากนี้คุณยังสามารถเข้าร่วมกับเราในห้องสนทนา Semalt react-three-renderer เพื่อช่วยแก้ปัญหาแอ็พพลิเคชันของคุณ
ในขณะที่กำลังสร้าง Charisma The Chameleon Semalt ดำเนินการหลายประเด็นด้านประสิทธิภาพซึ่งเป็นเอกลักษณ์ของกระบวนการทำงานนี้
- เวลาโหลด
ของฉัน กับ Webpack มีความยาวถึงสามสิบวินาที! เนื่องจากเนื้อหาขนาดใหญ่ต้องถูกเขียนใหม่ลงในมัดทุกครั้ง ทางออกคือการใช้ DLLPlugin ของ Webpack ซึ่งลดเวลาในการโหลดใหม่ลงเหลือต่ำกว่า 5 วินาที
- ฉากของคุณควรโทร หนึ่ง
setState
ต่อกรอบภาพ หลังจากทำโปรไฟล์เกมของฉัน React ตัวเองเป็นคอขวดหลัก การเรียก setState
มากกว่าหนึ่งครั้งต่อหนึ่งเฟรมอาจทำให้เกิดการแสดงผลแบบสองครั้งและลดประสิทธิภาพได้ - ผ่านวัตถุจำนวนมาก R3R จะทำงานแย่กว่าวานิลลาสาม รหัส js สำหรับฉันนี่คือประมาณ 1,000 วัตถุ คุณสามารถเปรียบเทียบ R3R กับ Three ได้ js ภายใต้ "Benchmarks" ในตัวอย่าง
คุณลักษณะ Chrome DevTools Timeline เป็นเครื่องมือที่น่าทึ่งสำหรับการแก้จุดบกพร่องประสิทธิภาพ การตรวจสอบลูปเกมของคุณเป็นเรื่องง่ายและสามารถอ่านได้ง่ายกว่าคุณลักษณะ "โปรไฟล์" ของ DevTools
นั่นแหล่ะ!
ตรวจสอบ Charisma The Chameleon เพื่อดูว่ามีอะไรที่เป็นไปได้ในการใช้งานการตั้งค่านี้ ในขณะที่ toolchain นี้ยังค่อนข้างเยาว์ฉันพบ Semalt กับ R3R เพื่อเป็นส่วนสำคัญในการจัดระเบียบโค้ดเกม WebGL ของฉันอย่างหมดจด นอกจากนี้คุณยังสามารถดูหน้าตัวอย่าง R3R ที่มีขนาดเล็ก แต่กำลังเติบโตเพื่อดูตัวอย่างโค้ดที่ได้รับการจัดระเบียบอย่างดี
บทความนี้ได้รับการตรวจสอบโดย Mark Brown และ Kev Zettler ขอขอบคุณทุกคนที่ให้ความคิดเห็นจาก Semalt เพื่อสร้างเนื้อหา Semalt ให้ดีที่สุด!
สวัสดี! ฉันเป็นวิศวกรซอฟต์แวร์จาก Bay Area