Cara yang baik untuk memainkan suara ketika sesuatu terjadi? Bagaimana ini terdengar?

10

Jadi saya berpikir tentang seberapa monolitik kelas saya mendapatkan banyak waktu. Misalnya, dalam metode Characterkelas Jump, seseorang mungkin memiliki referensi ke objek efek suara dan memainkannya. Dengan sendirinya itu baik-baik saja tetapi ketika fisika, animasi, tabrakan, dll diperhitungkan, metode Jump menjadi besar dan Characterkelas memiliki banyak ketergantungan pada banyak hal yang berbeda. Namun, ini mungkin baik-baik saja. Namun, bagaimana jika kita tidak lagi ingin suara dimainkan ketika karakter melompat? Sekarang, kita harus menemukan baris kode tertentu dalam kekacauan kode yang campur aduk Jumpdan berkomentar atau apa pun.

Jadi .. saya sedang berpikir ..

Bagaimana jika, sebaliknya, ada semacam AudioSystemkelas dan yang dilakukannya hanyalah berlangganan acara acak yang diminati di kelas lain. Sebagai contoh, Characterkelas mungkin memiliki Jumpedacara (statis juga, saya kira) yang dimunculkan dalam Characterkelas dalam metode ini. Kemudian, Characterkelas tidak akan tahu apa-apa tentang efek suara kecil yang dimainkan ketika karakter melompat. Itu AudioSystemhanya akan menjadi kelas besar yang programmer dapat mundur untuk menghubungkan efek suara dengan peristiwa-peristiwa tertentu yang terjadi dalam permainan melalui penggunaan peristiwa statis. Kemudian, jika mendapat terlalu besar itu bisa dipisahkan ke subclass seperti EffectsAudioSystem, BackgroundAudioSystem, AmbientAudioSystem, dan sebagainya.

Kemudian, dalam opsi untuk gim, seseorang dapat memiliki kotak centang untuk mengaktifkan atau menonaktifkan jenis suara ini dan semua yang perlu dilakukan hanyalah menonaktifkan satu sistem dengan bendera Boolean yang sederhana dan tunggal. Gagasan sistem ini juga dapat diperluas ke hal-hal seperti fisika, animasi, dll. Hingga titik di mana sebagian besar respons permainan yang dihasilkan dari tindakan pemain dihubungkan melalui sistem yang rumit dan terpisah ini.

Oke, jadi pertanyaan saya mungkin agak kabur, tetapi bagaimana hal ini terdengar? Saya belum pernah mendengar banyak pembicaraan tentang sistem semacam ini. Ini semua ada di kepala saya sekarang tanpa pengkodean dilakukan sejauh ini jadi mungkin itu salah satu dari mereka "baik dalam teori tetapi tidak dalam praktik" jenis transaksi. Apakah sistem semacam ini akan bekerja dengan gim yang lebih besar atau akankah akhirnya rusak dan menjadi lebih berantakan seperti spaghetti daripada sistem aslinya?

Richard Williams
sumber
5
Kedengarannya seperti ide yang bagus :) (Pada catatan yang lebih serius: Menggunakan pesan untuk komunikasi antara subsistem / kelas yang longgar secara umum adalah ide yang bagus untuk desain)
bummzack
1
ini adalah bagaimana hal itu dilakukan, Anda harus meletakkan rendering Anda di kelas yang terpisah juga, jika Anda belum melakukannya (seperti pada, Anda seharusnya tidak memiliki fungsi draw () di kelas Karakter).
dreta

Jawaban:

2

Pesan adalah neraka untuk di-debug dan dipelihara. Ini kedengarannya bagus secara teori, tetapi begitu dipraktekkan, itu menjadi berantakan dengan banyak data duplikat yang dikirim. Efek suara lompatan akan membutuhkan lebih banyak data di bagian akhir, misalnya posisi, kecepatan, bahan karakter aktif, apa saja, daftar akan panjang di bagian akhir.

Jadi Anda perlu mengumpulkan data ini dan mengirimkannya ke AudioManager melalui acara / pesan yang sangat spesifik dengan data yang disalin di dalamnya atau Anda akan mengirim referensi ke karakter dalam pesan, sehingga AudioManager dapat mengakses data, keduanya cara akhirnya berantakan, dan sekarang manajer audio harus memilih suara untuk material-underground dll.

Jadi pada akhirnya acara spesifik (yang merupakan kelas yang sangat spesifik untuk pesan ini) akan memasangkan kelas-kelas tersebut dengan sangat dalam. Tidak banyak yang menang dan pada akhirnya Anda akan memiliki daftar besar berantakan dari peristiwa / kelas yang sangat spesifik yang hanya melayani tujuan pengiriman data, yang sudah ada, dan mungkin sudah ketinggalan zaman dan akan menderita dari semua masalah lain dari data duplikat .

Jadi akan ada daftar besar kelas yang tidak perlu untuk dipelihara yang memperkenalkan penggabungan yang mendalam antara karakter dan AudioManager, kecuali sekarang ini tersebar di seluruh kode sumber. Tidak hanya di kelas Character dan AudioManager.

Masih merupakan ide bagus untuk memisahkan kode Anda, tetapi Pesan benar-benar hanyalah cara lain dari penggabungan dalam. Beberapa kode hanya harus digabungkan, gunakan cara paling langsung untuk memasangkannya, jangan over-engineer.

Maik Semder
sumber
1
Bagaimana sistem perpesanan yang dirancang dengan baik "hanyalah cara lain untuk menggabungkan"? Mengirim pesan adalah penggandaan minimum absolut tanpa objek tidak pernah berkomunikasi. Cara Anda mendesainnya dapat menyebabkan masalah tetapi jika sistem hanya mengambil suara, lokasi, dan mengetiknya memecahkan semua masalahnya dan memperkenalkan tidak ada yang Anda sarankan mungkin terjadi. Sistem audio seharusnya tidak menghitung suara apa yang dibutuhkan, sistem ini harus menghilangkan semua pengaturan dan sebaiknya masalah difusi. en.wikipedia.org/wiki/Coupling_(computer_programming)
ClassicThunder
1
@ClassicThunder intinya adalah dalam praktiknya pendekatan ini tidak skala dengan sangat baik. Ini berfungsi baik untuk aplikasi sederhana dan selama yang Anda butuhkan hanyalah PlaySoundEvent umum. Tetapi pertanyaannya adalah tentang AudioManager yang mendengarkan acara khusus OnJump () -, sehingga karakter tersebut dapat menghilangkan pekerjaan audio. Namun ini tidak akan menjadi kasus dengan PlaySoundEvent sederhana karena karakter harus memilih suara dan mengirimkannya ke AudioManager, yang membatalkan titik awal memperkenalkan OnJumpEvent untuk menyingkirkan pekerjaan audio.
Maik Semder
1
Saat menggunakan OnJumpEvent, Anda dapat memilih untuk menambahkan referensi ke karakter ke acara atau menyalin semua data penting dari karakter ke dalam acara tersebut. Tentu saja Anda benar, yang terakhir tidak akan memperkenalkan kopling yang dalam, tetapi itu akan menderita masalah duplikasi data dan objek data-passing baru yang harus dipertahankan, seperti untuk semua acara baru lainnya.
Maik Semder
1
-1 menyebabkan sementara saya setuju bahwa memiliki pesan yang begitu khusus (OnJump) kemungkinan merupakan ide yang buruk, ini hanya panjang 'Tidak ini adalah ide yang buruk' daripada informasi yang berguna untuk membuat orang membuat acara PlaySound yang mengambil nama efek suara dan posisi 3D dan / atau volume yang terjadi di.
James
@ James terima kasih atas masukannya, saya tidak bermaksud mengatakan menggunakan acara PlaySound, saya bermaksud mengatakan acara adalah abstraksi yang bagus untuk aplikasi basis data GUI, tetapi tidak praktis untuk permainan yang kompleks.
Maik Semder
2

Saya tidak berpikir sistem pesan lewat lebih dari rekayasa sama sekali. Bahkan itu bisa membuatnya secara dramatis lebih mudah untuk menyelesaikan sesuatu dalam fase semir. Kamu melakukannya dengan benar!

Apa yang Anda gambarkan adalah apa yang saya lemparkan bersama untuk permainan Global Game Jam kami tahun lalu. Saya bertanggung jawab untuk membuat dan mengedit SFX, dan mengintegrasikan musik yang saya dan komposer lain tulis ke dalam permainan dengan cara yang tidak payah.

Apa yang hebat tentang pendekatan ini dari perspektif audio adalah memungkinkan Anda melakukan begitu banyak hal menarik dengan suara Anda. Jika Anda berpikir efek suara dalam permainan hanyalah file suara, volume, dan panning, maka Anda salah melakukannya.

Contoh

Untuk permainan kami, Anda adalah dinosaurus yang menerbangkan pesawat ruang angkasa yang berlari ke planet untuk mencetak poin. Kami bekerja di Flash, jadi infrastruktur berbasis data tidak diperlukan. AudioManager adalah kelas yang terdiri dari sekelompok metode statis yang satu-satunya tujuan adalah untuk mengontrol suara apa yang terjadi sebagai respons terhadap peristiwa permainan.

Jika saya menulisnya dalam C ++, maka akan membutuhkan sedikit waktu untuk abstrak semua perilaku yang mungkin terdengar. Persyaratan untuk pesan yang memberitahukan sistem bahwa suatu tindakan telah terjadi tidak akan terlalu rumit. Itu hanya perlu jenis pesan, objek asal atau objek yang terpengaruh, akses ke beberapa jenis konteks keadaan permainan, dan tidak banyak lagi. Protokol dapat tumbuh seiring dengan meningkatnya kebutuhan game. Tentu, jika Anda melakukan semua ini dalam implementasi dalam kode (seperti kode GGJ jelek kami), Anda memiliki masalah kelas monolitik yang lebih buruk. Tapi itu mudah dikurangi dengan membuat sistem berbasis data.

Bagaimanapun, inilah reaksi sistem audio gim kami terhadap berbagai pesan:

  • Pemain bertabrakan dengan planet: Ini akan memicu suara ledakan planet, cukup mendasar. kemudian segera setelah itu akan meminta penghitung kombo berjalan. Jika cukup tinggi itu akan menjadwalkan efek suara untuk dimainkan setengah detik kemudian dinosaurus melakukan raungan kemenangan. Juga di latar belakang nilai populasi planet acak dihitung (sekitar 600 hingga 3000 - Saya tidak tahu mengapa rentang itu dipilih, itu adalah beberapa mekanik gameplay yang ditinggalkan dan masih berbaring untuk saya gunakan untuk membuat audio menarik), dan jadi saya menggunakannya untuk mengukur volume suara jeritan jauh (warga planet yang mengalami nasib buruk).

  • Pemain memegang spacebar untuk akselerasi: Setelah menerima ini sedikit suara "whoosh" thruster dimainkan, tetapi juga secara bersamaan raungan mesin putaran rendah menggenjot produksinya lebih dari 1,5 detik. Sistem partikel juga menggunakan ini untuk menembakkan emitor IIRC

  • Player melepaskan spacebar untuk deselerasi: Sekarang setelah player melepas spacebar, sistem audio tahu ia harus meningkatkan putaran mesin kembali ke bawah. Jika saya memiliki lebih banyak waktu, saya akan suka untuk melapisi suara lain di atasnya yang merupakan jenis suara merengek.

  • Pemain bertabrakan dengan tambang luar angkasa yang jahat: Tambang luar angkasa itu buruk, jadi tidak hanya ada suara tumbukan logam yang dikombinasikan dengan ledakan (itu hanya dimasukkan ke dalam satu suara), tetapi ada juga suara dinosaurus yang dipilih secara acak dan cemas yang memainkannya. Itu lebih cenderung untuk memilih lebih banyak "menangis" seperti suara karena kesehatan pemain semakin rendah.

Gim yang sudah menyenangkan menjadi asyik dimainkan ketika soundtrack-nya aktif dan dinamis, bahkan dengan sedikit perilaku sederhana seperti yang saya jelaskan di atas. Ya, ada beberapa logistik untuk dikerjakan dengan memastikan data yang benar terlewati. Tapi hei, BFD. Ini akan jauh dari hal paling rumit yang harus Anda tulis dalam cakupan kode permainan yang lebih besar.

Faktanya, FMOD dan Wwise bekerja seperti ini. Mereka tidak memiliki pengirim pesan pusat, tetapi Anda secara efektif memposting acara ke sistem pusat mereka dan mereka bereaksi dengan memainkan efek suara yang telah dirancang sebelumnya oleh pelaksana audio dalam alat penulisan. Anggap saja seperti memberi game Anda DJ live. Dia duduk dan menonton apa yang terjadi, dan memicu klip suara pada waktu yang tepat untuk membuat hal-hal menarik, mencampurnya sehingga cocok dengan lingkungan audio yang sudah ada sebelumnya.

[EDIT] Juga, saya melihat Anda telah menandai C # ini. Apakah XNA ini, dan jika demikian apakah Anda menggunakan XACT? Jika Anda menggunakan XNA, Anda harus menggunakan XACT.

michael.bartnett
sumber
1
Ini mungkin bekerja untuk proyek kecil, bahkan mungkin menyenangkan. Namun dalam yang besar Anda berakhir dengan sejumlah besar kelas pesan, yang perlu dipertahankan, sedangkan fungsi-panggilan sederhana akan memiliki efek yang sama. Itulah sebabnya sistem acara tidak skala dengan baik, semakin sulit untuk mengelola semakin besar proyek yang didapat.
Maik Semder
1
Tapi kami bekerja dengan FMOD di studio saya, tidak ada sistem pesan / acara, Anda tidak mengirim acara ke FMOD, Anda cukup memanggil fungsi-c atau metode c ++ untuk memainkan sesuatu. Mereka hanya menyebut suara mereka "peristiwa", yang tidak menjadikannya sistem peristiwa, itu hanya istilah yang mereka gunakan alih-alih suara.
Maik Semder
Tidak Memangnya kenapa? Anda cukup memanggil fungsi secara langsung alih-alih menggunakan acara untuk meneruskan parameter. Suatu peristiwa pada akhirnya tidak ada yang lain sebagai pemanggilan fungsi, hanya meneruskan parameter dalam objek acara, alih-alih meneruskannya secara langsung. Satu-satunya perbedaan adalah tipuan baru yang diperkenalkan oleh sistem acara, tetapi pada akhirnya itu adalah panggilan fungsi sederhana, hanya tidak perlu terlalu rumit.
Maik Semder
@MaikSemder Bagaimana panggilan metode tidak berakhir di web kusut nastiness mereka sendiri? Juga, saya mencoba mencatat perbedaan antara sistem acara dan "acara" yang digunakan oleh Wwise dan FMOD. Gagasan yang saya maksudkan adalah bahwa logika audio yang kompleks tidak termasuk dalam kelas objek game, dan mengabstraksi logika suara sedemikian rupa sehingga antarmuka mirip dengan pengiriman acara membuatnya lebih mudah untuk memiliki logika audio yang kaya. Saya benar - benar melihat sedikit perbedaan fungsional antara EventManager->dispatch("Sound:PlayerJump")dan soundSystem->playFMODEvent("/MyGame/Player/Jump").
michael.bartnett
2
Mungkin ada manfaat dari pengkodean yang lebih mudah, tetapi tidak gratis, ia datang dengan biaya kinerja, pemeliharaan, dan debugging yang lebih sulit. Maksud saya adalah, manfaatnya tidak sepadan untuk proyek-proyek besar. Anda berhadapan dengan lebih banyak objek daripada tanpa acara dan harus membayar harga untuk itu. Satu-satunya tempat yang saya pertimbangkan untuk menggunakan sistem pesan adalah untuk komunikasi antar utas untuk mencegah penguncian antar utas.
Maik Semder
0

Saya setuju dengan Maik Semder, bahwa sistem penyampaian pesan mungkin terlalu rekayasa (untuk saat ini).

Dari apa yang saya mengerti, kelas Anda saat ini terlihat seperti "kelas monolitik" Bjorn seperti yang dapat dilihat dalam "Kelas monolitik" di sini .

Saya sarankan Anda membaca artikel itu, dan, meskipun sistem komponen penuh akan berlebihan untuk saat ini, jika Anda membaca untuk "Membagi-bagi sisanya", itu akan memberi Anda cara yang baik untuk abstrak perilaku Anda dan akhirnya mungkin pindah ke yang lebih kompleks larutan. Ini akan memberi Anda dasar yang baik untuk memulai.

kaviar melambat
sumber