ฉันกำลังสร้างเกมแบบสตรีทไฟท์เตอร์ 2 มิติที่ไม่ได้มีการปูกระเบื้อง โดยทั่วไปแล้วคนมักแนะนำให้เอนทิตีถูกกำหนดให้กับตัวเรนเดอร์ที่แสดงพวกมันไม่ใช่ตัวเรนเดอร์ แต่ดูเหมือนว่าอินเวอร์สจะดีกว่า
ทำไมคนหนึ่งถึงดีกว่าอีกคนหนึ่ง?
ขอบคุณ
ฉันกำลังสร้างเกมแบบสตรีทไฟท์เตอร์ 2 มิติที่ไม่ได้มีการปูกระเบื้อง โดยทั่วไปแล้วคนมักแนะนำให้เอนทิตีถูกกำหนดให้กับตัวเรนเดอร์ที่แสดงพวกมันไม่ใช่ตัวเรนเดอร์ แต่ดูเหมือนว่าอินเวอร์สจะดีกว่า
ทำไมคนหนึ่งถึงดีกว่าอีกคนหนึ่ง?
ขอบคุณ
คำตอบ:
ข้อควรพิจารณาสองประการ:
ตามที่คุณได้กล่าวถึงเทพดาแต่ละตัวจะต้อง "บอกใบ้" เกี่ยวกับบิตแมปที่จะใช้ แต่ถ้าเอนทิตีต้องแสดงตัวเอง 'คำใบ้' นั้นจะเป็นอะไร? หากเป็นการอ้างอิงถึงบิตแมปสไปรต์ชีท ฯลฯ ... สำหรับแต่ละสไปรต์คุณอาจต้องใช้หน่วยความจำมากกว่าที่จำเป็นหรือมีปัญหาในการจัดการหน่วยความจำนั้น ข้อดีของตัวเรนเดอร์ที่แยกต่างหากคือคุณมีคลาสเพียงหนึ่งชั้นที่รับผิดชอบการจัดการสินทรัพย์ใด ๆ ที่กล่าวว่าในเกมต่อสู้เหมือน SF2 คุณอาจมีเพียงสองสไปรต์;)
ดังที่กล่าวไว้ที่อื่นเมื่อใดก็ตามที่คุณต้องการเปลี่ยน API กราฟิกของคุณคุณจะต้องเปลี่ยนรหัสสำหรับ Sprite ทั้งหมดของคุณ
การเรนเดอร์ทำได้ยากโดยไม่อ้างอิงถึงบริบททางกราฟิก ดังนั้นอาจมีตัวแปรทั่วโลกที่แสดงถึงแนวคิดนี้หรือแต่ละสไปรต์มีส่วนต่อประสานกับ render (GraphicalContext ctx) สิ่งนี้จะผสม API แบบกราฟิกและตรรกะของเกมของคุณ (ซึ่งบางคนอาจพบว่าไม่เหมาะ) และอาจทำให้เกิดปัญหาในการรวบรวม
ฉันพบว่าการแยกการเรนเดอร์ออกจากแต่ละเอนทิตีเป็นขั้นตอนแรกที่น่าสนใจในการดูเกมของคุณในฐานะระบบที่ไม่จำเป็นต้องใช้กราฟิกเลย สิ่งที่ฉันหมายถึงคือเมื่อคุณแสดงผลออกไปคุณจะรู้ว่ามีการเล่นเกมมากมายเกิดขึ้นใน "โลกที่ไม่ใช่กราฟฟิค" ซึ่งพิกัดของเอนทิตีสถานะภายในของพวกเขา ฯลฯ ... เป็นเรื่องสำคัญ นี่เป็นการเปิดประตูสู่การทดสอบอัตโนมัติ, ระบบแยกเพิ่มเติมและอื่น ๆ ...
โดยรวมแล้วฉันมักจะชอบระบบที่การเรนเดอร์ทำได้โดยคลาสแยกต่างหาก นั่นไม่ได้หมายความว่าสไปรต์ของคุณไม่สามารถมีคุณลักษณะบางอย่างที่ "เกี่ยวข้องกับกราฟิก" (ชื่อภาพเคลื่อนไหว, กรอบภาพเคลื่อนไหว, ความสูง x ความกว้าง, สไปรท์ id ฯลฯ ... ) หากนั่นทำให้นักแสดงเขียนง่ายขึ้นหรือมีประสิทธิภาพมากขึ้น
และฉันไม่รู้ว่าจะใช้กับ 3D ได้หรือไม่ (ซึ่งความคิดของ meshes และตัวแปรพิกัดที่คุณจะใช้อาจเชื่อมโยงกับ 3D API ของคุณได้ในขณะที่ x, y, h, w เป็นอิสระจาก 2D ใด ๆ API)
หวังว่านี่จะช่วยได้
คุณต้องการให้ระบบการเรนเดอร์สามารถควบคุมสิ่งที่จะเกิดขึ้นได้ ถ้าสไปรท์อยู่ในการควบคุมของการเรนเดอร์คุณจะสูญเสียประสิทธิภาพและความยืดหยุ่นที่เพิ่มขึ้นมากมาย ฉันเห็นว่าการมีระบบการแสดงผลในการควบคุมนั้นทำให้โค้ดสะอาดขึ้น
ข้อดีของการเรนเดอร์แบบรวมศูนย์:
วิธีที่ฉันใช้สิ่งนี้ในเกมของฉันเพื่อให้เกมวัตถุลงทะเบียนสไปรต์ที่พวกเขาต้องการด้วยระบบเรนเดอร์ เมื่อวัตถุไม่ต้องการให้วัตถุถูกดึงอีกต่อไปมันจะถอนการลงทะเบียนสไปรต์หรือทำเครื่องหมายว่าไม่ใช้งาน
ทั้งหมดที่กล่าวมา ถ้ามันง่ายกว่าที่วัตถุเกมของคุณจะแสดงผลออกมาโดยตัวของมันเอง มันสำคัญมากที่จะทำให้ความคืบหน้าและรับบางสิ่งบางอย่าง / สิ่งที่ดึงดูดมากกว่าที่จะมีสถาปัตยกรรมที่สมบูรณ์แบบ
ข้อจำกัดความรับผิดชอบ: คำถามของคุณไม่มีรายละเอียดมากนักดังนั้นฉันจึงตอบกลับด้วยหลักการทั่วไป โปรดขอโทษด้วยถ้าฉันเข้าใจผิดเกี่ยวกับการใช้งานของคุณหรือ 'แสดงผล'
โดยทั่วไปฉันใช้วัตถุภายนอกเพื่อทำให้นักแสดงหลายคนในฉากเป็นวิธีการห่อหุ้มคุณสมบัติและวิธีการของฉากระดับภายนอกของ 'นักแสดงวัตถุ' วัตถุในฉากควรมีวิธีการและคุณสมบัติภายในเท่านั้น พวกเขาควรรู้เกี่ยวกับสิ่งที่ตัวเองเป็นและสิ่งที่พวกเขาทำ สันนิษฐานว่าพวกเขาจะได้รับอิทธิพลจากวัตถุอื่น ๆ ในเกมเช่นเดียวกับการป้อนข้อมูลของผู้ใช้ วิธีนี้จะมีผลกับการแสดงผลบนหน้าจอ ยกตัวอย่างเช่น 'วัตถุผู้กำกับ' สามารถแปลปุ่มกด 'w' เพื่อกระโดดแล้วบอกวัตถุนักแสดง. jump () ตรรกะระดับผู้กำกับดังกล่าวยังสามารถบอกนักแสดงให้เข้าหรือออกจากฉากโดยสิ้นเชิง
ไชโยเดวิด
ถ้าวันหนึ่งคุณต้องการพอร์ตเกมของคุณให้มีความละเอียดที่แตกต่างกัน (เช่น iPhone และเพื่อน ๆ ) ดังนั้นสถานที่ให้บริการทั่วโลกเกี่ยวกับการแสดงผลการเปลี่ยนแปลงคุณจะปรับปรุงรหัสของคุณได้อย่างไร
สิ่งที่ฉันใช้คือการออกแบบโดยใช้ผู้สังเกตการณ์ เมื่อฉันสร้างอินสแตนซ์ของคลาสที่ฉันต้องการให้เรนเดอร์ตัวชี้ไปยังคลาสนั้นจะถูกเก็บไว้ในคลาส Renderer ส่วนกลาง เมื่อคุณเรียกRenderFrame()
ใช้ตัวแสดงผลจะมีออบเจ็กต์ที่มีอยู่ทั้งหมดที่จำเป็นต้องแสดงผลและเข้าถึงคุณสมบัติของพวกเขาเพื่อที่จะทำ ชั้นเรียนของตัวเองไม่รู้ว่าพวกเขาจะได้รับการแสดงผลทั้งหมด API นี้ดีและสะอาดและใช้งานง่าย
โดยทั่วไปมักจะเกี่ยวกับความง่ายในการบำรุงรักษาและขยายรหัสของคุณ พรุ่งนี้คุณคิดว่าคุณไม่ชอบ API กราฟิกที่คุณใช้อยู่ในปัจจุบันและต้องการเปลี่ยน ตอนนี้คุณจะต้องผ่านคลาสวัตถุของคุณทั้งหมดและเปลี่ยนแปลงทุกอย่างหรือไม่หรือคุณเพียงแค่ต้องเปลี่ยนรหัสของคุณในจุดศูนย์กลางเดียวของโครงการ
ขึ้นอยู่กับสิ่งที่วัตถุของคุณกำลังทำจริง ๆ เมื่อคุณเรียกใช้ render () ตราบใดที่พวกเขาเพิ่งเรียกเมธอดไปรอบ ๆ เอ็นจิ้นกราฟิคของคุณมันก็ใช้ได้ดีเนื่องจาก logics <-> ความแตกต่างของกราฟิกจะยังคงได้รับ
ตัวอย่างเช่นหากวิธีการเรนเดอร์ () ของคุณนั้นเป็นวิธีการอำนวยความสะดวกและเป็นดังนี้:
void MyClass::render(const Graphics &g)
{
g.draw(this);
}
หรือ
void MyClass::render()
{
mySprite->render();
}
หรือ
void MyClass::render()
{
mySprite->UseShader(thatshader);
mySprite->render();
}
หรือใกล้เคียงกับที่ฉันไม่คิดว่ามันเป็นปัญหาใด ๆ