Pada artikel ini saya akan berbicara tentang pengalaman pribadi saya dalam mengembangkan game kecil di Rust. Butuh sekitar 24 jam untuk membuat versi yang berfungsi (saya terutama bekerja di malam hari atau pada akhir pekan). Game ini masih jauh dari selesai, tapi saya pikir pengalaman itu akan berguna. Saya akan memberi tahu Anda apa yang saya pelajari dan beberapa pengamatan yang dilakukan saat membangun game dari awal.
Skillbox merekomendasikan: Kursus praktis dua tahun "Saya seorang Pengembang Web PRO . "
Kami mengingatkan Anda: untuk semua pembaca "Habr" - diskon 10.000 rubel saat mendaftar untuk kursus Skillbox apa pun menggunakan kode promo "Habr".
Kenapa berkarat?
Saya memilih bahasa ini karena saya mendengar banyak hal baik tentangnya dan saya melihat bahwa bahasa ini menjadi semakin populer di bidang pengembangan game. Sebelum menulis permainan, saya memiliki sedikit pengalaman mengembangkan aplikasi sederhana di Rust. Ini cukup untuk merasakan kebebasan tertentu saat menulis permainan.
Mengapa tepatnya gim dan jenis gim apa?
Membuat game itu menyenangkan! Saya ingin lebih banyak alasan, tetapi untuk proyek "rumah" saya memilih topik yang tidak terlalu terkait dengan pekerjaan saya yang biasa. Game seperti apa? Saya ingin melakukan sesuatu seperti simulator tenis yang menggabungkan Kota Skylines, Zoo Tycoon, Prison Architect dan tenis itu sendiri. Secara umum, ternyata permainan tentang akademi tenis, di mana orang-orang datang untuk bermain.
Pelatihan teknis
Saya ingin menggunakan Rust, tetapi saya tidak tahu persis bagaimana "dari awal" saya harus memulai. Saya tidak ingin menulis pixel shader dan menggunakan drag-n-drop, jadi saya mencari solusi yang paling fleksibel.
Menemukan sumber daya bermanfaat yang saya bagikan dengan Anda:
Saya menjelajahi beberapa mesin game Rust, akhirnya memilih Piston dan ggez. Saya menemukan mereka ketika mengerjakan proyek sebelumnya. Pada akhirnya, saya memilih ggez, karena sepertinya lebih cocok untuk mengimplementasikan game 2D kecil. Struktur modular Piston terlalu rumit untuk pengembang pemula (atau seseorang yang bekerja dengan Rust untuk pertama kalinya).
Struktur permainan
Saya menghabiskan sedikit waktu untuk memikirkan arsitektur proyek. Langkah pertama adalah membuat "tanah", orang-orang dan lapangan tenis. Orang-orang harus berkeliling pengadilan dan menunggu. Pemain harus memiliki keterampilan yang meningkat seiring waktu. Plus, harus ada editor yang memungkinkan Anda untuk menambah orang dan pengadilan baru, tetapi ini tidak lagi gratis.
Memikirkan segalanya, saya mulai bekerja.
Pembuatan game
Mulai: Lingkaran dan AbstraksiSaya mengambil contoh dari ggez dan mendapat lingkaran di layar. Luar biasa Sekarang beberapa abstraksi. Sepertinya saya senang mengabaikan gagasan tentang objek game. Setiap objek harus dirender dan diperbarui sebagaimana ditunjukkan di sini:
Sepotong kode ini memungkinkan saya untuk mendapatkan daftar objek yang sangat bagus yang dapat saya perbarui dan render dalam satu lingkaran yang sama baiknya.
mpl event::EventHandler for MainState { fn update(&mut self, context: &mut Context) -> GameResult<()> {
main.rs diperlukan karena mengandung semua baris kode. Saya menghabiskan sedikit waktu untuk memisahkan file dan mengoptimalkan struktur direktori. Begini caranya semuanya mulai terlihat setelah itu:
sumber daya -> ini adalah tempat semua aset (gambar)
src
- entitas
- game_object.rs
- circle.rs
- main.rs -> loop utamaOrang, lantai, dan gambarLangkah selanjutnya adalah membuat objek game Person dan memuat gambar. Semuanya harus didasarkan pada ubin berukuran 32 * 32.
Lapangan tenisSetelah mempelajari bagaimana tampilan lapangan tenis, saya memutuskan untuk membuatnya dari ubin 4 * 2. Awalnya, dimungkinkan untuk membuat gambar sebesar ini atau membuat 8 ubin terpisah. Tetapi kemudian saya menyadari bahwa hanya dua ubin unik yang diperlukan, dan itulah sebabnya.
Secara total, kami memiliki dua ubin: 1 dan 2.
Setiap bagian pengadilan terdiri dari ubin 1 atau ubin 2. Mereka dapat diatur seperti biasa atau terbalik 180 derajat.
Mode utama konstruksi (perakitan)Setelah saya berhasil mencapai rendering situs, orang, dan peta, saya menyadari bahwa mode pembangunan dasar juga diperlukan. Diimplementasikan seperti ini: ketika tombol ditekan, objek dipilih, dan klik menempatkannya di tempat yang tepat. Jadi, tombol 1 memungkinkan Anda memilih pengadilan, dan tombol 2 memungkinkan Anda memilih pemain.
Tapi Anda masih perlu mengingat apa yang kami maksud 1 dan 2, jadi saya menambahkan wireframe sehingga jelas objek mana yang dipilih. Ini tampilannya.
Pertanyaan tentang arsitektur dan refactoringSekarang saya memiliki beberapa objek permainan: orang, lapangan dan lantai. Tetapi agar wireframe berfungsi, Anda perlu memberi tahu setiap entitas objek apakah objek itu sendiri dalam mode demonstrasi, atau jika sebuah bingkai hanya digambar. Ini sangat tidak nyaman.
Sepertinya saya perlu memikirkan kembali arsitekturnya sehingga beberapa batasan terungkap:
- Kehadiran entitas yang menampilkan dan memperbarui itu sendiri adalah masalah, karena entitas ini tidak akan dapat "tahu" apa yang harus dirender - gambar dan gambar rangka;
- kurangnya alat untuk bertukar properti dan perilaku antara entitas individu (misalnya, properti is_build_mode atau perilaku rendering). Warisan dapat digunakan, meskipun tidak ada cara normal untuk mengimplementasikannya di Rust. Yang benar-benar saya butuhkan adalah tata letak;
- alat untuk interaksi entitas di antara mereka diperlukan untuk menugaskan orang ke pengadilan;
- entitas itu sendiri adalah campuran data dan logika, yang dengan cepat lepas kendali.
Saya melakukan riset lebih lanjut dan menemukan arsitektur ECS - Entity Component System , yang biasa digunakan dalam gim. Berikut adalah manfaat ECS:
- data dipisahkan dari logika;
- tata letak bukan warisan;
- arsitektur berorientasi data.
ECS ditandai oleh tiga konsep dasar:
- entitas - jenis objek yang dirujuk oleh pengidentifikasi (bisa berupa pemain, bola, atau yang lainnya);
- komponen - entitas terdiri dari mereka. Contohnya adalah komponen rendering, tata letak, dan lainnya. Ini adalah gudang data;
- sistem - mereka menggunakan objek dan komponen, ditambah lagi mengandung perilaku dan logika yang didasarkan pada data ini. Contohnya adalah sistem rendering yang beralih di atas semua entitas dengan komponen untuk rendering dan terlibat dalam rendering.
Setelah mempelajarinya menjadi jelas bahwa ECS memecahkan masalah seperti itu:
- menggunakan tata letak alih-alih warisan untuk sistem organisasi entitas;
- menyingkirkan hash kode karena sistem kontrol;
- menggunakan metode seperti is_build_mode untuk menyimpan logika wireframe di tempat yang sama - di sistem rendering.
Inilah yang terjadi setelah menerapkan ECS.
sumber daya -> ini adalah tempat semua aset (gambar)
src
- komponen
- position.rs
- person.rs
- tennis_court.rs
- floor.rs
- gambar rangka.rs
- mouse_tracked.rs
- sumber daya
- mouse.rs
- sistem
- rendering.rs
- constants.rs
- utils.rs
- world_factory.rs -> fungsi pabrik dunia
- main.rs -> loop utamaTetapkan orang ke pengadilan
ECS membuat hidup lebih mudah. Sekarang saya punya cara sistematis untuk menambahkan data ke entitas dan menambahkan logika berdasarkan data ini. Dan ini, pada gilirannya, memungkinkan untuk mengatur distribusi orang oleh pengadilan.
Apa yang saya lakukan:
- menambahkan data tentang pengadilan yang ditugaskan kepada Orang;
- menambahkan data tentang orang yang didistribusikan ke TennisCourt;
- menambahkan CourtChoosingSystem, yang memungkinkan Anda untuk menganalisis orang dan situs, menemukan pengadilan yang tersedia dan mendistribusikan pemain kepada mereka;
- menambahkan sistem PersonMovementSystem, yang mencari orang-orang yang ditugaskan ke pengadilan, dan jika mereka tidak ada di sana, itu mengirim orang-orang di mana diperlukan.
Untuk meringkas
Saya sangat menikmati mengerjakan game sederhana ini. Selain itu, saya senang saya menggunakan Rust untuk menulisnya, karena:
- Rust memberi Anda apa yang Anda butuhkan;
- ia memiliki dokumentasi yang sangat bagus, Rust sangat elegan;
- kekonstanan itu keren;
- Anda tidak perlu menggunakan kloning, menyalin, atau tindakan serupa lainnya, yang sering saya lakukan di C ++;
- Opsi sangat nyaman untuk bekerja, mereka juga menangani kesalahan dengan sempurna;
- jika proyek dapat dikompilasi, maka dalam 99% berhasil, dan persis seperti seharusnya. Menurut saya, pesan kesalahan kompiler adalah yang terbaik dari yang pernah saya lihat.
Pengembangan game di Rust baru saja dimulai. Tetapi sudah ada komunitas yang stabil dan cukup besar yang bekerja untuk membuka Rust bagi semua orang. Oleh karena itu, saya melihat masa depan bahasa dengan optimisme, menantikan hasil kerja kita bersama.
Skillbox merekomendasikan: