วิธีการเชิงวัตถุเป็นวิดีโอเกม? [ปิด]


18

ฉันสงสัยอยู่เสมอว่าการวางแนววัตถุในขอบเขตใดโดยวิดีโอเกมโดยเฉพาะโครงการ 3D ขนาดใหญ่ ฉันคิดว่ามันคงเจ๋งที่ทั้งสองtrollและwerewolfสืบทอดคุณลักษณะจากenemyและเขียนทับบางส่วนของพวกเขา แต่บางทีชั้นเรียนอาจหนักเกินไปที่จะใช้งานได้จริงฉันไม่รู้ ...


2
การวัดปริมาณการวางแนวของวัตถุ (หรือแม้กระทั่งมีคุณสมบัติเป็นกลาง) คุณต้องการคำตอบในเมเยอร์สหรือ Dahl-Nygaards หรือไม่?

เห็นได้ชัดว่าพวกเขาหนักมากว่าภาษาที่ใช้ OO เป็นมาตรฐานอุตสาหกรรม
The Duck คอมมิวนิสต์

4
ถ้าคุณหมายถึง C ++ มันถูกเลือกเพราะมันเป็นภาษาที่ดีสำหรับการสำรวจการเขียนโปรแกรมทั่วไปประเภทที่ปลอดภัยในวิธีที่คำนึงถึงความเร็ว เห็นได้ชัดว่าคุณสมบัติของ OOP ไม่กี่ตัวนั้นเป็นการออกแบบที่ผิดพลาดที่โชคร้าย ;)

คำตอบ:


20

มาถึงตัวอย่างของคุณฉันจะอธิบายความคิดของฉันเกี่ยวกับ Entites ในวิดีโอเกม ฉันจะไม่พูดถึงข้อดีและข้อเสียทั่วไปของวัตถุและคลาสรวมถึงบทบาททั้งหมดในวิดีโอเกม

เอนทิตีในวิดีโอเกมขนาดเล็กส่วนใหญ่จะถูกกำหนดโดยชั้นเรียนแยกในเกมใหญ่พวกเขามักจะถูกกำหนดในไฟล์ มีวิธีการทั่วไปสองวิธีในการติดตาม:

ขยาย : ในตัวอย่างของคุณTrollและWerewolfจะขยายซึ่งทอดตัวEnemy ดูแลเกี่ยวกับสิ่งพื้นฐานเช่นการเคลื่อนไหวสุขภาพ ฯลฯ ในขณะที่จะระบุคลาสย่อยเป็นศัตรูและทำสิ่งอื่น ๆ (Minecraft ทำตามวิธีนี้)EntityEntityEnemy

ส่วนประกอบตาม : วิธีที่สอง (และรายการโปรดของฉัน) คือEntityชั้นหนึ่งซึ่งมีส่วนประกอบ ส่วนประกอบที่อาจจะหรือMoveable Enemyส่วนประกอบเหล่านี้ดูแลสิ่งหนึ่งอย่างเช่นการเคลื่อนไหวหรือฟิสิกส์ วิธีนี้แบ่งส่วนต่อขยายที่ยาวและลดความเสี่ยงที่จะเกิดข้อขัดแย้ง ตัวอย่างเช่น: คุณจะสร้างศัตรูที่ไม่สามารถเคลื่อนที่ได้ได้อย่างไรหากพวกมันสืบทอดมาจากตัวละครที่เคลื่อนย้ายได้ .

ในวิดีโอเกมขนาดใหญ่เช่น World of Warcraft หรือ Starcraft 2, Entities ไม่ใช่คลาส แต่เป็นชุดของข้อมูลซึ่งระบุ Entity ทั้งหมด การเขียนสคริปต์ก็มีความสำคัญเช่นกันเพราะคุณกำหนดสิ่งที่เอ็นติตี้ไม่ได้อยู่ในคลาส แต่เป็นสคริปต์ (หากเป็นเอกลักษณ์ไม่เหมือนการเคลื่อนไหว)

ขณะนี้ฉันกำลังเขียนโปรแกรม RTS และฉันใช้วิธีการแบบคอมโพเนนต์กับ Descriptor และไฟล์สคริปต์สำหรับ Entites, ทักษะ, ไอเท็มและทุกอย่างอื่นที่มีชีวิตชีวาในเกม


2
เสียงที่น่าสนใจ อย่างไรก็ตามฉันจะไม่โกหกฉันไม่รู้ว่าอะไรcomponentอยู่ในบริบทนี้ ลิงค์จะนิยมมาก
vemv

ส่วนประกอบคือเอนทิตีที่มีความรับผิดชอบในการใช้งานฟังก์ชั่นเดียว นิติบุคคลที่ใช้องค์ประกอบจะเป็นเจ้าขององค์ประกอบ (ถ้าเป็นกรณี) มันจะไม่ได้รับมรดกจากมัน ความเป็นเจ้าของหมายความว่าองค์กรสามารถปิดการใช้งานหนึ่งในองค์ประกอบของการเปลี่ยนแปลงพฤติกรรม ในกระบวนทัศน์การขยายแบบคลาสสิกพฤติกรรมเกิดจาก "เป็นของ" ซุปเปอร์คลาส เอนทิตีสามารถเป็นส่วนประกอบและส่วนประกอบสามารถสร้างแบบจำลองเป็นคลาสหรือเป็นโครงสร้างได้หากคุณต้องการ
FxIII

คอมโพเนนต์ (บางครั้งเรียกว่าระบบเอนทิตี) - คุณสามารถค้นหาบล็อกนี้เพื่อหาแนวคิดt-machine.org มีหลากหลายรูปแบบ แต่แนวคิดพื้นฐานคือส่วนประกอบเป็นวัตถุวัตถุประสงค์พิเศษและนักแสดงของคุณเชื่อมโยงองค์ประกอบหลายอย่างเข้าด้วยกันเช่นสร้างแบบจำลอง จาก Legos
Patrick Hughes

2
ฉันเริ่มบล็อกเกี่ยวกับการพัฒนาเกมและเขียนบล็อกแรกของฉันเกี่ยวกับสิ่งนี้ ไม่มีอะไรใหม่ แต่ด้วยรหัสเล็กน้อย: jagamedev.wordpress.com/2011/06/26/…
Marco

23

ฉันคิดว่ามันคงเจ๋งที่ทั้งโทรลล์และมนุษย์หมาป่าจะสืบทอดคุณสมบัติของมันจากศัตรูและเขียนทับพวกมันบางส่วน

น่าเสียดายที่วิธีนี้มีความแตกต่างซึ่งเป็นที่นิยมใน 90s แสดงให้เห็นว่าตัวเองมีความคิดที่ไม่ดีในทางปฏิบัติ ลองนึกภาพคุณเพิ่ม 'wolf' ลงในรายชื่อศัตรู - มันแชร์คุณสมบัติบางอย่างกับมนุษย์หมาป่าดังนั้นคุณจึงต้องการรวมเหล่านั้นไว้ในคลาสฐานที่ใช้ร่วมกันเช่น 'WolfLike' ตอนนี้คุณเพิ่ม 'มนุษย์' ลงในรายการศัตรู แต่มนุษย์หมาป่าบางครั้งก็เป็นมนุษย์ดังนั้นพวกเขาจึงแบ่งปันคุณลักษณะเช่นกันเช่นเดินบน 2 ขาสามารถพูดคุย ฯลฯ คุณสร้างฐานร่วม 'Humanoid' สำหรับมนุษย์และมนุษย์หมาป่า และคุณต้องหยุดมนุษย์หมาป่าที่มาจาก WolfLike หรือไม่? หรือคุณคูณรับมรดกจากทั้งสองอย่าง - ซึ่งในกรณีนี้คุณลักษณะใดที่สำคัญกว่าเมื่อบางสิ่งใน Humanoid ปะทะกับบางสิ่งใน WolfLike

ปัญหาคือการพยายามสร้างแบบจำลองโลกแห่งความเป็นจริงเป็นต้นไม้ที่ไม่มีประสิทธิภาพ ทำอะไร 3 อย่างและคุณอาจพบวิธีที่แตกต่างกัน 4 วิธีในการคำนึงถึงพฤติกรรมของพวกเขาในการแชร์และไม่แชร์ นี่คือสาเหตุที่หลายคนหันไปใช้โมเดลแบบแยกส่วนหรือส่วนประกอบแทนโดยที่วัตถุประกอบด้วยวัตถุขนาดเล็กจำนวนมากที่ประกอบเป็นทั้งหมดและวัตถุขนาดเล็กสามารถเปลี่ยนหรือเปลี่ยนแปลงเพื่อให้สอดคล้องกับพฤติกรรมที่คุณต้องการ ที่นี่คุณอาจมีคลาสศัตรูเพียง 1 คลาสและมีวัตถุย่อยหรือส่วนประกอบสำหรับวิธีการเดิน (เช่น Bipedal vs. Quadrupedal) วิธีการโจมตี (เช่นกัด, กรงเล็บ, อาวุธ, กำปั้น), ผิวของมัน (สีเขียว สำหรับ trolls, ขนยาวสำหรับมนุษย์หมาป่าและหมาป่า) ฯลฯ

สิ่งนี้ยังคงเป็นเชิงวัตถุอย่างสมบูรณ์ แต่ความคิดของสิ่งที่เป็นประโยชน์นั้นแตกต่างจากสิ่งที่เคยสอนกันโดยทั่วไปในหนังสือเรียน แทนที่จะมีต้นไม้มรดกขนาดใหญ่ของคลาสนามธรรมที่หลากหลายและคลาสคอนกรีตจำนวนมากที่ปลายของต้นไม้คุณมักจะมีเพียง 1 คลาสคอนกรีตที่แสดงแนวคิดนามธรรม (เช่น 'ศัตรู') แต่มีคลาสคอนกรีตที่มากขึ้นซึ่งแสดงแนวคิดนามธรรมที่เป็นนามธรรมมากกว่า (เช่นการโจมตีประเภทของผิว) บางครั้งคลาสที่สองเหล่านี้สามารถใช้งานได้ดีที่สุดผ่านการสืบทอดระดับ 1 (เช่นคลาสการโจมตีพื้นฐานและคลาสที่ได้รับหลายคลาสสำหรับการโจมตีเฉพาะ) แต่โครงสร้างการสืบทอดลึกจะหายไป

แต่บางทีชั้นเรียนอาจหนักเกินไปที่จะใช้งานได้จริงฉันไม่รู้ ...

ในภาษาที่ทันสมัยส่วนใหญ่ชั้นเรียนจะไม่ 'หนัก' พวกมันเป็นอีกวิธีหนึ่งในการเขียนโค้ดและพวกเขามักจะห่อวิธีการที่คุณจะเขียนต่อไปยกเว้นด้วยไวยากรณ์ที่ง่ายกว่า แต่โดยทั้งหมดอย่าเขียนคลาสที่ฟังก์ชันจะทำ ชั้นเรียนไม่ได้ดีขึ้นอย่างแท้จริงเฉพาะที่พวกเขาทำให้รหัสง่ายต่อการจัดการหรือเข้าใจ


3
รักคำตอบนี้ :)
Czarek Tomczak

8

ฉันไม่แน่ใจว่าสิ่งที่คุณหมายถึง "หนักเกินไป" แต่ C ++ / OOP เป็นภาษากลางของการพัฒนาเกมด้วยเหตุผลเดียวกันกับที่ใช้ในที่อื่น

พูดถึงการเป่าแคชเป็นปัญหาการออกแบบไม่ใช่คุณสมบัติทางภาษา C ++ ต้องไม่เลวร้ายนักเพราะมันถูกใช้ในเกมมานานกว่า 15-20 ปีแล้ว Java นั้นไม่เลวร้ายนักเนื่องจากมันถูกใช้ในสภาพแวดล้อมรันไทม์ที่เข้มงวดของสมาร์ทโฟน

ต่อไปนี้เป็นคำถามที่แท้จริง: หลายปีที่ผ่านมาลำดับชั้นของชั้นเรียนลึกและเริ่มประสบปัญหาที่เกี่ยวข้อง ในช่วงเวลาที่ผ่านมาลำดับชั้นของคลาสนั้นแบนและองค์ประกอบและการออกแบบที่ขับเคลื่อนด้วยข้อมูลอื่น ๆ นั้นเป็นมากกว่าการสืบทอดเชิงตรรกะ

มันคือ OOP ทั้งหมดและยังคงใช้เป็นพื้นฐานในการออกแบบซอฟต์แวร์ใหม่เพียงแค่มุ่งเน้นไปที่สิ่งที่ชั้นเรียนรวบรวม


2

คลาสไม่เกี่ยวข้องกับค่าใช้จ่ายในการดำเนินการใด ๆ ความหลากหลายเวลาทำงานเป็นเพียงการเรียกผ่านตัวชี้ฟังก์ชั่น ค่าโสหุ้ยเหล่านี้มีน้อยมากเมื่อเทียบกับค่าใช้จ่ายอื่น ๆ เช่นการโทรแบบวาดการซิงโครไนซ์พร้อมกันดิสก์ I / O สวิตช์โหมดเคอร์เนลตำแหน่งหน่วยความจำไม่ดีการใช้หน่วยความจำแบบไดนามิกมากเกินไป ไปที่. มีเหตุผลที่การวางแนววัตถุได้แทนที่สิ่งที่เกิดขึ้นก่อนหน้านี้และเป็นเพราะมันดีกว่ามาก


การแจกจ่ายในกลุ่มโพลีมอร์ฟิคประเภทต่างๆนั้นกระทำในลักษณะที่ทำให้พื้นที่ความจำไม่ดี แม้ในการใช้งานที่มีน้ำหนักเบาที่สุดเช่น C ++ vtables หรือ Objective-C การแคช IMP ถ้าคุณใช้ polymorphism เพื่อจัดการกับวัตถุประเภทต่าง ๆ คุณจะเป่าแคชของคุณ แน่นอนถ้าคุณไม่ได้ใช้ความหลากหลายที่แตกต่างจาก vtable ที่อยู่ในแคชของคุณหรือข้อความแคชที่นำไปสู่ตำแหน่งที่ถูกต้อง แต่ทำไมต้องรำคาญ? และใน Java หรือ C # ราคาจะหนักกว่าและใน JavaScript หรือ Python ราคาจะหนักกว่า

1
@Joe Wreschnig: หากคุณใช้ภาษาที่ช้ากว่านั้นค่าใช้จ่ายของ OO นั้นเล็กน้อยเมื่อเทียบกับค่าใช้จ่ายอื่น ๆ เช่นการตีความ / JIT ที่สำคัญกว่านั้นคุณสามารถสร้างทฤษฎีสิ่งที่คุณต้องการเกี่ยวกับตำแหน่งหน่วยความจำที่ไม่ดี แต่ความจริงก็คือการคาดการณ์ของสาขาการดำเนินการที่ไม่เป็นไปตามสั่งและคุณลักษณะที่คล้ายกัน ถ้าอย่างนั้นทำไมซอฟต์แวร์ที่มีประสิทธิภาพสูงจำนวนมากถูกเขียนขึ้นโดยใช้การวางวัตถุ?
DeadMG

1

สิ่งหนึ่งที่ต้องระวังคือแนวคิดของโค้ดเชิงวัตถุมักมีค่ามากกว่าการนำไปใช้ในภาษา โดยเฉพาะอย่างยิ่งการเรียกการอัปเดตเสมือน 1,000 ครั้งบนเอนทิตีในลูปหลักอาจทำให้เกิดความยุ่งเหยิงในแคชใน C ++ บนแพลตฟอร์มเช่น 360 หรือ PS3 ดังนั้นการนำไปใช้อาจหลีกเลี่ยงคำหลัก "เสมือน" หรือแม้แต่ "คลาส" เพื่อประโยชน์ ของความเร็ว

บ่อยครั้งที่มันจะยังคงเป็นไปตามแนวคิดของ OO เกี่ยวกับการสืบทอดและการห่อหุ้ม - เพียงนำพวกเขาไปใช้ในลักษณะที่แตกต่างกับภาษาของตัวเอง (เช่นเทมเพลตแบบเรียกซ้ำแบบซ้ำ ๆ หากการสืบทอดสามารถแก้ไขได้ตลอดเวลาการคอมไพล์แล้วปัญหาประสิทธิภาพจะหายไป แต่โค้ดอาจกลายเป็นปัญหาเล็กน้อยกับเทมเพลตการปรับใช้ RTTI แบบกำหนดเอง (อีกครั้งที่บิวท์อินมักจะช้า) มาโคร ฯลฯ

ใน Objective-C สำหรับ iOS / Mac มีความคล้ายคลึงกัน แต่ปัญหาที่เลวร้ายยิ่งกว่ากับรูปแบบการส่งข้อความ (แม้จะมีสิ่งแคชแฟนซี) ...


0

วิธีการที่ฉันจะพยายามใช้การสืบทอดคลาสและส่วนประกอบผสม (ก่อนอื่นฉันไม่ทำให้ Enemy เป็นคลาส - ฉันสร้างชิ้นส่วนนั้นขึ้นมา) ฉันไม่ชอบความคิดในการใช้คลาสเอนทิตี้ทั่วไปสำหรับทุกสิ่งจากนั้นเพิ่มส่วนประกอบที่จำเป็นเพื่อทำให้เอนทิตีออก แต่ฉันต้องการให้คลาสเพิ่มส่วนประกอบ (และค่าเริ่มต้น) ใน Constructor โดยอัตโนมัติ จากนั้นคลาสย่อยจะเพิ่มคอมโพเนนต์เพิ่มเติมลงในตัวสร้างดังนั้นคลาสย่อยจะมีส่วนประกอบและส่วนประกอบคลาสพาเรนต์ ตัวอย่างเช่นคลาสอาวุธจะเพิ่มองค์ประกอบพื้นฐานที่เหมือนกันกับอาวุธทั้งหมดแล้วคลาสย่อย Sword จะเพิ่มส่วนประกอบเพิ่มเติมใด ๆ สำหรับดาบโดยเฉพาะ ฉันยังคงถกเถียงกันว่าจะใช้เนื้อหาข้อความ / xml เพื่อกำหนดค่าสำหรับเอนทิตี (หรือยกตัวอย่างเช่นดาบ) หรือที่จะทำทั้งหมดในรหัสหรือสิ่งที่ผสมผสานที่ถูกต้องคือ สิ่งนี้ยังช่วยให้เกมใช้ข้อมูลประเภทของรหัสภาษาและ polymorphism และทำให้ ObjectFactories ง่ายกว่ามาก


3
เฮ้คริส ในขณะที่แบ่งปันประสบการณ์และแผนของคุณนั้นยอดเยี่ยม แต่ก็ไม่ได้ตอบคำถามโดยตรง ฉันคิดว่าคำถามนี้เกี่ยวกับการทำสิ่งเหล่านี้โดยทั่วไปในขณะที่คุณตอบคำถามว่าคุณวางแผนอย่างไร พวกเขาเป็นคำถามที่คล้ายกัน แต่ไม่เหมือนกันจริงๆ
MichaelHouse
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.