24時間のRustゲーム:個人的な開発経験

画像






この記事では、Rustで小さなゲームを開発した私の個人的な経験についてお話します。 作業バージョンを作成するのに約24時間かかりました(主に夕方または週末に作業しました)。 ゲームはまだ終わっていませんが、この経験は役に立つと思います。 私が学んだことと、ゲームをゼロから構築するときに行われた観察のいくつかについて説明します。



Skillboxの推奨事項: 2年間の実践コース「私はPRO Web開発者です。



「Habr」の読者には、「Habr」プロモーションコードを使用してSkillboxコースに登録すると10,000ルーブルの割引があります。


なぜ錆びたのですか?



この言語を選んだ理由は、この言語について多くの良いことを聞いたからであり、ゲーム開発の分野でますます人気が高まっていることがわかります。 ゲームを書く前は、Rustで簡単なアプリケーションを開発した経験はほとんどありませんでした。 これは、ゲームの作成中に特定の自由を感じるのにちょうど十分でした。



なぜまさにゲームであり、どのようなゲームなのか?



ゲームを作るのは楽しいです! もっと理由はありますが、「ホーム」プロジェクトでは、通常の仕事にあまり関係のないトピックを選択します。 どんなゲーム? Cities Skylines、Zoo Tycoon、Prison Architect、テニス自体を組み合わせたテニスシミュレーターのようなものを作りたかったのです。 一般的には、人々が遊びに来るテニスアカデミーに関するゲームでした。



技術研修



Rustを使用したかったのですが、「ゼロから」開始する方法が正確にはわかりませんでした。 ピクセルシェーダーを作成してドラッグアンドドロップを使用したくなかったため、最も柔軟なソリューションを探していました。



私があなたと共有する有用なリソースを見つけました:





私はいくつかのRustゲームエンジンを調査し、最終的にはPistonとggezを選択しました。 前のプロジェクトに取り組んでいるときに出会った。 結局、私はggezを選択しました。小さな2Dゲームを実装するのにより適しているように思えたからです。 ピストンのモジュール構造は、初心者の開発者(またはRustを初めて使用する人)には複雑すぎます。



ゲーム構造



プロジェクトのアーキテクチャについて少し考えました。 最初のステップは、「土地」、人々、テニスコートを作ることです。 人々は裁判所を動き回って待たなければなりません。 プレイヤーは時間とともに向上するスキルを持っている必要があります。 さらに、新しい人や裁判所を追加できるエディタが必要ですが、これはもはや無料ではありません。



すべてを考えて、私は仕事に取り掛かりました。



ゲーム作成



開始:サークルと抽象化



私はggezから例を取り、画面上に円を得ました。 すごい 今、いくつかの抽象化。 ゲームオブジェクトの概念を無視するのは良いことだと思いました。 以下に示すように、各オブジェクトをレンダリングおよび更新する必要があります。



// the game object trait trait GameObject { fn update(&mut self, _ctx: &mut Context) -> GameResult<()>; fn draw(&mut self, ctx: &mut Context) -> GameResult<()>; } // a specific game object - Circle struct Circle { position: Point2, } impl Circle { fn new(position: Point2) -> Circle { Circle { position } } } impl GameObject for Circle { fn update(&mut self, _ctx: &mut Context) -> GameResult<()> { Ok(()) } fn draw(&mut self, ctx: &mut Context) -> GameResult<()> { let circle = graphics::Mesh::new_circle(ctx, graphics::DrawMode::Fill, self.position, 100.0, 2.0)?; graphics::draw(ctx, &circle, na::Point2::new(0.0, 0.0), 0.0)?; Ok(()) } }
      
      





このコードのおかげで、オブジェクトの優れたリストを取得でき、同様に優れたループで更新およびレンダリングできます。



 mpl event::EventHandler for MainState { fn update(&mut self, context: &mut Context) -> GameResult<()> { // Update all objects for object in self.objects.iter_mut() { object.update(context)?; } Ok(()) } fn draw(&mut self, context: &mut Context) -> GameResult<()> { graphics::clear(context); // Draw all objects for object in self.objects.iter_mut() { object.draw(context)?; } graphics::present(context); Ok(()) } }
      
      





main.rsにはすべてのコード行が含まれているため、必要です。 ファイルを分離し、ディレクトリ構造を最適化するために少し時間を費やしました。 以下は、それがどのように見え始めたのかです。



リソース->これはすべてのアセットが存在する場所です(画像)

src

-エンティティ

-game_object.rs

-circle.rs

-main.rs->メインループ



人、フロア、画像



次のステップは、Personゲームオブジェクトを作成し、画像をロードすることです。 すべてが32 * 32タイルに基づいている必要があります。







テニスコート



テニスコートがどのように見えるかを研究したので、私はそれらを4 * 2タイルで作ることにしました。 最初は、このサイズの画像を作成するか、8つの個別のタイルを作成することができました。 しかし、その後、2つの一意のタイルのみが必要であることに気付きました。



合計で、1と2の2つのタイルがあります。



コートの各セクションは、タイル1またはタイル2で構成されています。通常のように配置するか、180度逆さまにすることができます。







建設のメインモード(アセンブリ)



サイト、人、およびマップのレンダリングを達成した後、基本的なビルドモードも必要であることに気付きました。 次のように実装されました。ボタンが押されると、オブジェクトが選択され、クリックすると適切な場所に配置されます。 そのため、ボタン1ではコートを選択でき、ボタン2ではプレーヤーを選択できます。



ただし、1と2の意味を覚えておく必要があるので、ワイヤフレームを追加して、選択されているオブジェクトを明確にします。 外観は次のとおりです。









アーキテクチャとリファクタリングに関する質問



今、私はいくつかのゲームオブジェクトを持っています:人、コート、フロアです。 ただし、ワイヤフレームが機能するためには、オブジェクト自体がデモンストレーションモードにあるのか、単にフレームが描画されているのかをオブジェクトの各エンティティに伝える必要があります。 これはあまり便利ではありません。



いくつかの制限が明らかになるように、アーキテクチャを再考する必要があるように思えました。





さらに調査を行って、ゲームで一般的に使用されているECSアーキテクチャ、Entity Component Systemを発見しました。 ECSの利点は次のとおりです。



  • データはロジックから分離されています。
  • 継承ではなくレイアウト。
  • データ指向アーキテクチャ。


ECSには3つの基本概念があります。





勉強した後、ECSがそのような問題を解決することが明らかになりました:





ECSの実装後に何が起こったのかを次に示します。



リソース->これはすべてのアセットが存在する場所です(画像)

src

-コンポーネント

-position.rs

-person.rs

-tennis_court.rs

-floor.rs

-wireframe.rs

-mouse_tracked.rs

-リソース

-mouse.rs

-システム

-rendering.rs

-constants.rs

-utils.rs

-world_factory.rs->ワールドファクトリ関数

-main.rs->メインループ



裁判所に人を割り当てる



ECSは生活を楽にしました。 これで、エンティティにデータを追加し、このデータに基づいてロジックを追加する体系的な方法ができました。 そして、これにより、裁判所による人々の分布を整理することが可能になりました。



私がしたこと:











まとめると



このシンプルなゲームでの作業は本当に楽しかったです。 さらに、Rustを使用して作成したことを嬉しく思います。





Rustでのゲーム開発はまだ始まったばかりです。 しかし、Rustをすべての人に公開するために取り組んでいる安定したかなり大きなコミュニティが既に存在します。 したがって、私は言語の将来を楽観的に見て、共通の仕事の結果を楽しみにしています。



Skillboxの推奨事項:








All Articles