Saya telah mengerjakan RPG 2d untuk sementara waktu sekarang, dan saya menyadari bahwa saya telah membuat beberapa keputusan desain yang buruk. Ada beberapa hal yang membuat saya bermasalah, jadi saya bertanya-tanya desain seperti apa yang digunakan orang lain untuk mengatasinya, atau akan digunakan.
Untuk sedikit latar belakang, saya mulai mengerjakannya di waktu senggang saya musim panas lalu. Saya awalnya membuat game dalam C #, tetapi sekitar 3 bulan yang lalu, memutuskan untuk beralih ke C ++. Saya ingin mendapatkan pegangan yang baik pada C ++ karena sudah lama sejak saya menggunakannya dengan berat, dan menemukan proyek yang menarik seperti ini akan menjadi motivator yang baik. Saya telah menggunakan boost library secara luas dan telah menggunakan SFML untuk grafik dan FMOD untuk audio.
Saya memiliki sedikit kode yang ditulis, tetapi saya mempertimbangkan untuk menghapusnya dan memulai kembali.
Inilah bidang utama yang menjadi perhatian saya dan saya ingin mendapatkan beberapa pendapat tentang cara yang tepat orang lain menyelesaikannya atau akan menyelesaikannya.
1. Dependensi Siklikal Ketika saya melakukan permainan dalam C #, saya tidak benar-benar perlu khawatir tentang ini karena itu bukan masalah di sana. Pindah ke C ++, ini telah menjadi masalah yang cukup besar dan membuat saya berpikir saya mungkin telah merancang hal-hal yang salah. Saya tidak dapat membayangkan bagaimana cara memisahkan kelas saya dan masih membiarkan mereka melakukan apa yang saya inginkan. Berikut adalah beberapa contoh rantai ketergantungan:
Saya memiliki kelas efek status. Kelas memiliki sejumlah metode (Terapkan / Tidak Berlaku, Centang, dll.) Untuk menerapkan efeknya terhadap karakter. Contohnya,
virtual void TickCharacter(Character::BaseCharacter* character, Battles::BattleField *field, int ticks = 1);
Fungsi ini akan dipanggil setiap kali karakter yang ditimbulkan oleh efek status berubah. Ini akan digunakan untuk mengimplementasikan efek seperti Regen, Poison, dll. Namun, itu juga memperkenalkan dependensi pada kelas BaseCharacter dan kelas BattleField. Secara alami, kelas BaseCharacter perlu melacak efek status apa yang saat ini aktif padanya sehingga itu merupakan ketergantungan siklus. Battlefield perlu melacak pihak-pihak yang bertikai, dan kelas partai memiliki daftar Karakter BaseChak yang memperkenalkan ketergantungan siklus lainnya.
2 - Acara
Dalam C # I menggunakan banyak delegasi untuk mengaitkan peristiwa dengan karakter, medan perang dll. (Misalnya, ada delegasi untuk kapan kesehatan karakter berubah, ketika stat berubah, ketika efek status ditambahkan / dihapus, dll. .) dan medan perang / komponen grafis akan menghubungkan ke delegasi tersebut untuk menegakkan efeknya. Di C ++, saya melakukan sesuatu yang serupa. Jelas tidak ada yang setara langsung dengan delegasi C #, jadi alih-alih saya membuat sesuatu seperti ini:
typedef boost::function<void(BaseCharacter*, int oldvalue, int newvalue)> StatChangeFunction;
dan di kelas karakter saya
std::map<std::string, StatChangeFunction> StatChangeEventHandlers;
setiap kali stat karakter berubah, saya akan beralih dan memanggil setiap StatChangeFunction di peta. Sementara itu berhasil, saya khawatir ini adalah pendekatan yang buruk untuk melakukan sesuatu.
3 - Grafik
Ini hal besar. Ini tidak terkait dengan perpustakaan grafis yang saya gunakan, tetapi lebih merupakan hal konseptual. Dalam C #, saya menambahkan grafik dengan banyak kelas saya yang saya tahu adalah ide yang buruk. Ingin melakukannya terpisah kali ini saya mencoba pendekatan yang berbeda.
Untuk mengimplementasikan grafik saya, saya membayangkan semua grafik yang terkait dalam game sebagai serangkaian layar. Yaitu ada layar judul, layar status karakter, layar peta, layar persediaan, layar pertempuran, layar GUI pertempuran, dan pada dasarnya saya bisa menumpuk layar ini di atas satu sama lain yang diperlukan untuk membuat grafik permainan. Apa pun layar aktif yang memiliki input game.
Saya merancang manajer layar yang akan mendorong dan memunculkan layar berdasarkan input pengguna.
Misalnya, jika Anda berada di layar peta (pengendali input / visualizer untuk Peta Ubin) dan menekan tombol mulai, itu akan mengeluarkan panggilan ke manajer layar untuk menekan layar Menu Utama di atas layar peta dan menandai peta layar untuk tidak ditarik / diperbarui. Pemain akan menavigasi di sekitar menu, yang akan mengeluarkan lebih banyak perintah ke manajer layar yang sesuai untuk mendorong layar baru ke tumpukan layar, lalu pop mereka ketika pengguna mengubah layar / membatalkan. Akhirnya ketika pemain keluar dari menu utama, saya mematikannya dan kembali ke layar peta, berkomentar itu akan ditarik / diperbarui dan pergi dari sana.
Layar pertempuran akan lebih kompleks. Saya memiliki layar untuk bertindak sebagai latar belakang, layar untuk memvisualisasikan masing-masing pihak dalam pertempuran, dan layar untuk memvisualisasikan UI untuk pertempuran. UI akan terhubung ke peristiwa karakter dan menggunakannya untuk menentukan kapan harus memperbarui / menggambar ulang komponen UI. Akhirnya, setiap serangan yang memiliki skrip animasi yang tersedia akan memanggil lapisan tambahan untuk menghidupkannya sendiri sebelum keluar dari tumpukan layar. Dalam hal ini, setiap layer secara konsisten ditandai sebagai drawable dan updatable dan saya mendapatkan setumpuk layar yang menangani grafik pertempuran saya.
Meskipun saya belum bisa membuat pengelola layar bekerja dengan sempurna, saya pikir saya bisa melakukannya dengan beberapa waktu. Pertanyaan saya tentang itu, apakah ini pendekatan yang berharga sama sekali? Jika itu desain yang buruk, saya ingin tahu sekarang sebelum saya menginvestasikan terlalu banyak waktu untuk membuat semua layar yang saya butuhkan. Bagaimana Anda membangun grafik untuk gim Anda?