เป็นวิธีที่ดีในการเล่นเสียงเมื่อเกิดอะไรขึ้น? เสียงนี้เป็นอย่างไร


10

ดังนั้นฉันจึงคิดว่าชั้นหินใหญ่ของฉันจะมีเวลามากแค่ไหน ตัวอย่างเช่นในวิธีการCharacterของชั้นเรียนJumpหนึ่งอาจมีการอ้างอิงไปยังวัตถุที่มีผลกระทบเสียงและเล่นที่ โดยตัวมันเองนั้นดี แต่เมื่อคำนึงถึงฟิสิกส์การเคลื่อนไหวการชน ฯลฯ วิธีการกระโดดนั้นมีขนาดใหญ่มากและCharacterชั้นเรียนมีการพึ่งพาสิ่งต่างๆมากมาย ถึงกระนั้นนี่อาจจะใช้ได้ อย่างไรก็ตามถ้าหากเราไม่ต้องการให้เสียงเล่นอีกต่อไปเมื่อตัวละครกระโดด ตอนนี้เราต้องค้นหาบรรทัดของรหัสที่ระบุในระเบียบที่ยุ่งเหยิงของJumpรหัสและแสดงความคิดเห็นหรืออะไรก็ตาม

ดังนั้น .. ฉันกำลังคิด ..

จะเกิดอะไรขึ้นถ้ามีAudioSystemคลาสบางประเภทและทั้งหมดนี้คือการสมัครรับกิจกรรมแบบสุ่มที่สนใจในคลาสอื่น ๆ ตัวอย่างเช่นCharacterคลาสอาจมีJumpedเหตุการณ์ (คงที่ด้วยฉันคิดว่า) ที่ยกขึ้นภายในCharacterชั้นเรียนในวิธีการ จากนั้นCharacterชั้นเรียนก็จะไม่รู้อะไรเกี่ยวกับเอฟเฟกต์เสียงเล็กน้อยที่เล่นเมื่อตัวละครกระโดด AudioSystemก็จะเป็นชั้นขนาดใหญ่ที่โปรแกรมเมอร์ที่จะล่าถอยไปที่จะขอขึ้นผลกระทบเสียงกับเหตุการณ์บางอย่างที่เกิดขึ้นในเกมที่ผ่านการใช้เหตุการณ์ที่เกิดขึ้นคง แล้วถ้ามันมีขนาดใหญ่เกินไปก็อาจจะแยกออกจากกันใน subclasses เช่นEffectsAudioSystem, BackgroundAudioSystem, AmbientAudioSystemและอื่น ๆ

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

ตกลงดังนั้นคำถามของฉันอาจคลุมเครือเล็กน้อย แต่สิ่งที่เสียงแบบนี้? ฉันไม่เคยได้ยินเกี่ยวกับระบบแบบนี้มาก่อนเลย ทั้งหมดนี้อยู่ในหัวของฉันตอนนี้โดยไม่ต้องมีการเข้ารหัสใด ๆ ดังนั้นบางทีมันอาจเป็นหนึ่งใน "ข้อตกลงที่ดีในทางทฤษฎี แต่ไม่ใช่ในทางปฏิบัติ" ระบบประเภทนี้จะทำงานกับเกมที่มีขนาดใหญ่กว่าหรือในที่สุดมันจะพังและกลายเป็นระเบียบมากกว่าเดิม


5
เสียงเหมือนไอเดียเสียง :) (ข้อสังเกตที่จริงจังมากขึ้น: การใช้ข้อความสำหรับการสื่อสารระหว่างระบบย่อย / คลาสแบบคู่โดยทั่วไปนั้นเป็นแนวคิดการออกแบบที่ดี)
bummzack

1
นี่เป็นวิธีการที่ทำได้คุณควรใส่การแสดงผลของคุณในคลาสที่แยกต่างหากเช่นกันถ้าคุณยังไม่ได้ (เช่นคุณไม่ควรมีฟังก์ชั่นการดึง () ในคลาสตัวละคร)
dreta

คำตอบ:


2

ข้อความเป็นนรกที่จะทำการแก้ไขและบำรุงรักษา ฟังดูดีในทางทฤษฎี แต่เมื่อนำไปใช้งานจริงมันจะยุ่งเหยิงกับข้อมูลที่ส่งซ้ำจำนวนมาก เอฟเฟกต์การกระโดดเสียงจะต้องใช้ข้อมูลมากขึ้นในตอนท้ายเช่นตำแหน่ง, ความเร็ว, วัสดุที่ตัวละครเปิดอยู่คุณตั้งชื่อรายการนั้นจะยาวที่สุด

ดังนั้นคุณจะต้องรวบรวมข้อมูลนี้และส่งไปยัง AudioManager ผ่านเหตุการณ์ / ข้อความเฉพาะที่มีข้อมูลที่คัดลอกมาหรือคุณจะส่งการอ้างอิงถึงตัวละครในข้อความดังนั้น AudioManager สามารถเข้าถึงข้อมูลได้ทั้ง ท้ายที่สุดยุ่งและตอนนี้ผู้จัดการเสียงต้องเลือกเสียงสำหรับวัสดุใต้ดิน ฯลฯ

ดังนั้นในตอนท้ายเหตุการณ์เฉพาะ (ซึ่งเป็นคลาสเฉพาะสำหรับข้อความนี้เท่านั้น) จะจับคู่คลาสเหล่านั้นลึกมากอีกครั้ง ไม่ชนะมากและในตอนท้ายคุณจะมีรายการ / ชั้นเรียนขนาดใหญ่ที่ยุ่งเหยิงซึ่งให้บริการเฉพาะจุดประสงค์ในการส่งข้อมูลที่มีอยู่แล้วและอาจล้าสมัยและอาจประสบปัญหาอื่น ๆ ของข้อมูลที่ซ้ำซ้อน .

ดังนั้นจะมีรายการขนาดใหญ่ของคลาสที่ไม่จำเป็นเพื่อรักษาซึ่งแนะนำการมีเพศสัมพันธ์อย่างลึกซึ้งระหว่างตัวละครและ AudioManager ยกเว้นตอนนี้มันจะกระจายไปทั่วซอร์สโค้ด ไม่เพียง แต่ในคลาส Character- และ AudioManager

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


1
ระบบส่งข้อความที่ออกแบบมาอย่างดีเป็นอย่างไร "เป็นอีกวิธีหนึ่งในการเชื่อมต่อที่ลึก" การส่งข้อความเป็นการเชื่อมต่อขั้นต่ำที่แน่นอนโดยไม่มีวัตถุที่ไม่เคยสื่อสาร วิธีที่คุณออกแบบมันอาจทำให้เกิดปัญหา แต่ถ้าระบบใช้เสียงสถานที่และพิมพ์มันจะแก้ปัญหาทั้งหมดของเขาและแนะนำสิ่งที่คุณแนะนำอาจไม่เกิดขึ้น ระบบเสียงไม่ควรคำนวณสิ่งที่จำเป็นต้องใช้กับเสียงมันควรตัดการตั้งค่าทั้งหมดออกไป en.wikipedia.org/wiki/Coupling_(computer_programming)
ClassicThunder

1
@ClassicThunder จุดในทางปฏิบัติวิธีนี้ไม่ได้ปรับขนาดได้เป็นอย่างดี มันทำงานได้ดีสำหรับแอพพลิเคชั่นที่เรียบง่ายและตราบใดที่คุณต้องการก็คือ PlaySoundEvent ทั่วไป แต่คำถามคือเกี่ยวกับ AudioManager ที่ฟังเหตุการณ์พิเศษของ OnJump () - ดังนั้นตัวละครสามารถกำจัดงานเสียงได้ อย่างไรก็ตามสิ่งนี้จะไม่เกิดขึ้นกับ PlaySoundEvent อย่างง่าย ๆ เนื่องจากตัวละครจะต้องเลือกเสียงและส่งไปยัง AudioManager ซึ่งจะทำให้จุดเดิมของการแนะนำ OnJumpEvent นั้นไม่ถูกต้องเพื่อกำจัดงานเสียง
Maik Semder

1
อย่างไรก็ตามเมื่อใช้ OnJumpEvent คุณสามารถเลือกเพิ่มการอ้างอิงไปยังตัวละครในเหตุการณ์หรือคัดลอกข้อมูลสำคัญทั้งหมดจากตัวละครไปยังเหตุการณ์ แน่นอนว่าคุณถูกต้องตัวหลังจะไม่แนะนำการมีเพศสัมพันธ์อย่างลึกซึ้ง แต่จะประสบปัญหาการทำสำเนาข้อมูลและออบเจ็กต์การส่งผ่านข้อมูลใหม่ที่ต้องได้รับการบำรุงรักษาเช่นเดียวกับเหตุการณ์ใหม่อื่น ๆ ทั้งหมด
Maik Semder

1
-1 สาเหตุในขณะที่ฉันยอมรับว่าการมีข้อความพิเศษ (OnJump) น่าจะเป็นความคิดที่ไม่ดีนี่เป็นเพียงความยาว 'ไม่นี่เป็นความคิดที่ไม่ดี' แทนที่จะเป็นข้อมูลที่มีประโยชน์เพื่อให้บุคคลสร้างเหตุการณ์ PlaySound ที่ใช้ชื่อ ของเอฟเฟกต์เสียงและตำแหน่ง 3D และ / หรือระดับเสียงที่เกิดขึ้นที่
James

@ James ขอบคุณสำหรับการป้อนข้อมูลฉันไม่ได้ตั้งใจจะพูดว่าใช้เหตุการณ์ PlaySound ฉันหมายถึงการพูดว่าเหตุการณ์เป็นสิ่งที่ดีสำหรับแอปพลิเคชันฐานข้อมูล GUI แต่ไม่เหมาะสำหรับเกมที่ซับซ้อน
Maik Semder

2

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

สิ่งที่คุณอธิบายก็คือสิ่งที่ฉันโยนให้เกม Global Jam ของเราเมื่อปีที่แล้ว ฉันต้องรับผิดชอบในการสร้างและแก้ไข SFX และผสมผสานเพลงที่ฉันและนักแต่งเพลงคนอื่นเขียนไว้ในเกมด้วยวิธีที่ไม่ได้ดูด

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

ตัวอย่าง

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

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

อย่างไรก็ตามนี่คือวิธีที่ระบบเสียงเกมของเราตอบสนองต่อข้อความต่างๆ:

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

  • ผู้เล่นถือสเปซบาร์เพื่อเร่งความเร็ว:เมื่อได้รับเสียงทุ้มแบบ "หวือหวา" นี้แล้วก็เล่นเสียงคำรามของเครื่องยนต์ต่ำพร้อม ๆ กันในเวลา 1.5 วินาที ระบบอนุภาคยังใช้สิ่งนี้เพื่อยิงตัวส่งสัญญาณ IIRC

  • ผู้เล่นปล่อยสเปซบาร์ออกไปเพื่อลดความเร็ว:ตอนนี้ผู้เล่นปล่อยสเปซบาร์ออกไประบบเสียงรู้ว่ามันต้องลดการวนลูปของเครื่องยนต์ลง หากฉันมีเวลามากขึ้นฉันจะชอบที่จะเลเยอร์เสียงอื่น ๆ มากกว่าที่เป็นประเภทของเสียงหอนเสียงแหลมลง

  • ผู้เล่นปะทะกับเหมืองอวกาศชั่วร้าย:เหมืองอวกาศไม่ดีดังนั้นไม่เพียง แต่จะมีผลกระทบทางเสียงโลหะรวมกับการระเบิด (ที่เพิ่งอบเป็นเสียงเดียว) แต่ยังมีเสียงไดโนเสาร์ที่สุ่มเลือกที่เล่น มีแนวโน้มที่จะเลือก "ร้องไห้" มากกว่าเสียงเมื่อสุขภาพของผู้เล่นต่ำลง

เกมที่สนุกแล้วกลายเป็นความสุขที่ได้เล่นเมื่อซาวด์แทร็กมีการใช้งานและมีชีวิตชีวาแม้จะมีพฤติกรรมที่เรียบง่ายเพียงเล็กน้อยตามที่ฉันได้อธิบายไว้ข้างต้น ใช่มีโลจิสติกส์บางอย่างที่ต้องจัดการเพื่อให้แน่ใจว่าข้อมูลที่ถูกต้องได้รับการส่งผ่าน แต่เฮ้ BFD มันจะไกลจากสิ่งที่ซับซ้อนที่สุดที่คุณต้องเขียนในขอบเขตขนาดใหญ่ของรหัสเกม

อันที่จริงแล้ว FMOD และ Wwise ทำงานอย่างนี้ พวกเขาไม่มีตัวแจกจ่ายข้อความกลาง แต่คุณโพสต์เหตุการณ์ได้อย่างมีประสิทธิภาพไปยังระบบกลางและพวกเขาตอบสนองโดยการเล่นเอฟเฟกต์เสียงที่ออกแบบไว้ล่วงหน้าโดยผู้วางระบบเสียงในเครื่องมือการเขียน คิดว่ามันเหมือนกับให้เกมของคุณเป็นดีเจสด เขานั่งและดูว่าเกิดอะไรขึ้นและกระตุ้นคลิปเสียงในเวลาที่เหมาะสมเพื่อให้สิ่งต่าง ๆ น่าสนใจรวมเข้าด้วยกันเพื่อให้เข้ากับสภาพแวดล้อมของเสียงที่มีมาก่อน

[แก้ไข] นอกจากนี้ฉันเห็นว่าคุณติดแท็ก C # นี้ XNA นี้หรือไม่และถ้าเป็นเช่นนั้นคุณใช้ XACT หรือไม่ หากคุณใช้ XNA คุณควรใช้ XACT


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

1
Btw เราทำงานร่วมกับ FMOD ที่สตูดิโอของฉันไม่มีข้อความ / ระบบเหตุการณ์คุณไม่ส่งกิจกรรมไปยัง FMOD คุณเพียงเรียก c-function หรือ c ++ method เพื่อเล่นอะไรบางอย่าง พวกเขาเพียงเรียกเสียง "เหตุการณ์" ของพวกเขาที่ไม่ได้ทำให้มันเป็นระบบกิจกรรมมันเป็นเพียงคำที่พวกเขาใช้แทนเสียง
Maik Semder

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

@MaikSemder วิธีการโทรไม่ได้จบลงในเว็บที่ยุ่งเหยิงของพวกเขาเอง? นอกจากนี้ฉันพยายามจดบันทึกความแตกต่างระหว่างระบบเหตุการณ์และ "เหตุการณ์" ที่ใช้โดย Wwise และ FMOD ความคิดที่ฉันกำลังทำอยู่คือตรรกะของเสียงที่ซับซ้อนไม่ได้อยู่ในคลาสของออบเจ็กต์เกมและสรุปตรรกะของเสียงออกมาเพื่อให้อินเทอร์เฟซคล้ายกับการส่งเหตุการณ์ทำให้ง่ายต่อการมีตรรกะของเสียงที่หลากหลาย ผมเห็นความแตกต่างระหว่างการทำงานเล็ก ๆ น้อย ๆและEventManager->dispatch("Sound:PlayerJump") soundSystem->playFMODEvent("/MyGame/Player/Jump")
michael.bartnett

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

0

ฉันเห็นด้วยกับ Maik Semder ว่าระบบส่งข้อความอาจทำงานเกินกำลัง (สำหรับตอนนี้)

จากสิ่งที่ฉันเข้าใจปัจจุบันชั้นเรียนของคุณดูเหมือน Bjorn "monolithic class" ที่เห็นได้ใน "A monolithic class" ที่นี่ที่นี่

ฉันขอแนะนำให้คุณอ่านบทความนั้นและถึงแม้ว่าระบบส่วนประกอบแบบเต็มจะเกินราคาสำหรับตอนนี้ถ้าคุณอ่าน "แยกส่วนที่เหลือ" ออกมาคุณควรให้วิธีที่ดีในการทำให้พฤติกรรมของคุณเป็นนามธรรม สารละลาย. มันจะช่วยให้คุณมีฐานที่ดีตั้งแต่ต้น

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