今回もbevy engineの練習していきましょうね。住民税非課税世帯の給付金の申し込みは、10分でできた。 キャッシュカードと、マイナンバーカードの写真を送る必要があった。
目的
プロジェクトファイルを細かく分割して、管理をしやすくする。
①srcフォルダーの中で、main.rsを、systems.rs resources.rs components.rs events.rsに分けて同じように実行できるようにする。
②その後、srcフォルダーの中で、main.rsの他に、enemy star player scoreのフォルダーに階層わけし、それぞれのエンティティに関連する、コンポーネントやシステム、イベント、リソースをファイルで①のように分けて記述する。それぞれのフォルダーでプラグインを作成し、mainにプラグインを追加して、同様に動くようにする。
目的①に対する取り組み
①に対して
まず、メイン関数以外のシステムを、system.rsにカットアンドペーストし、をリソースのderive宣言やコンポーネント、イベントのderive宣言をそれぞれresources.ts components.rs events.rsにカットアンドペーストした。
その後、main.rs に以下の様な文を追加した。
また、
resources.rs components.rs events.rs の文頭に、
を宣言し、
systemsには、bevyの宣言の他に、
components や、events、resources.rsの読み込みを行った。
その後、出たエラーを消すために、systems.rs やresources.rsに足りないpub constをカットアンドペースト張り付けた。
この工程の意味を説明すると、main関数においてmodキーワード を使って、モジュールの定義をしました。モジュールの定義をすると、useキーワードでスコープ内に持ち込むことが出来ます。use はパスの指定をする必要があるのですが、crateは同じファイル内、つまりsrc内という意味で、そのあとから、1段階潜るのが、crate::の後の文であるという事である。この場合、拡張子は必要ないようだ。
検証

プレイヤー、スター、エネミー、スコア全て問題なく機能しているため、目的は達成できている。
目的への取り組み
次に、Star, Enemy, Player, Score毎にファイルを分けプログラムを管理する方法を試してみる。

まずは、コマンドプロンプトを利用して、フォルダーを作成した。
# enemyディレクトリ内にファイルを作成
mkdir enemy
New-Item -Path "enemy\component.rs" -ItemType File -Force
New-Item -Path "enemy\systems.rs" -ItemType File -Force
New-Item -Path "enemy\events.rs" -ItemType File -Force
New-Item -Path "enemy\main.rs" -ItemType File -Force
New-Item -Path "enemy\resources.rs" -ItemType File -Force
# starディレクトリ内にファイルを作成
mkdir star
New-Item -Path "star\component.rs" -ItemType File -Force
New-Item -Path "star\systems.rs" -ItemType File -Force
New-Item -Path "star\events.rs" -ItemType File -Force
New-Item -Path "star\main.rs" -ItemType File -Force
New-Item -Path "star\resources.rs" -ItemType File -Force
# scoreディレクトリ内にファイルを作成
mkdir score
New-Item -Path "score\component.rs" -ItemType File -Force
New-Item -Path "score\systems.rs" -ItemType File -Force
New-Item -Path "score\events.rs" -ItemType File -Force
New-Item -Path "score\main.rs" -ItemType File -Force
New-Item -Path "score\resources.rs" -ItemType File -Force
# playerディレクトリ内にファイルを作成
mkdir player
New-Item -Path "player\component.rs" -ItemType File -Force
New-Item -Path "player\systems.rs" -ItemType File -Force
New-Item -Path "player\events.rs" -ItemType File -Force
New-Item -Path "player\main.rs" -ItemType File -Force
New-Item -Path "player\resources.rs" -ItemType File -Force
このコードcd bevy-ball-game/srcにしたのち打ち込んで、作成した。

最終形はこのような形である。
参考動画が、crate::player::main.rsではなく、mod.rsになっていたので、直した。
まずは、crate::components.rsからコンポーネントの宣言を、各フォルダー内の、components.rsに移した。同様に、イベント、リソースについてもフォルダの分類ごとに入れた。GameOverイベントは、Playerフォルダーのイベントに入れた。
その後、それらの、crate::components.rs, events.rs, resources.rsを削除した。
crate::systems.rsの中身は、spawn_camera handle_gameover exit_gameシステムをcrate::main.rsに移動し、enemy_hit_playerと、player_hit_starをplayer::sytemsに移動した以外は、システムの名前についているものをそれぞれシステムに移動した。
そして、メイン関数にある、systems.rsに送った関数をそれぞれ、mod.rsにコピペした。
そして、このようにして、プラグインを作り、システムをまとめた。
main関数に残したspawn_camera, handle_game_over, exit_gameは、crate::systems.rsに残した。
様々なものが移動されたので、使われてないファイルなどを削除する。
enemyファイルとstarファイルのevent.rs、playerファイルのresources.rs、scoreファイルのevent.rs, component.rsを削除した。
最終的になファイルツリーは以上の画像のようになった。

また、crate::main.rsのメイン関数に、全てのプラグインを導入した。
これにより、原理上は全て動作するはずなので、あとは、インポートをしっかりやればいいだけである。
まず、crate::systemsの中で、crate::player::events::GameOverが参照できないというエラーが出た。
まず、useキーワードで先ほどのパスを打ち込む。
すると、eventsが見つからなかったとエラーが出る。基本的にはファイルの階層が下がると読み込めないので、player::mod.rsの中で、pub mod events;と打ち込んで、eventsを公開状態にした。
すると、読み込めるようになってエラーが解消された。
また、後の話になるが、resourcesの中にある要素が見つからなかったというエラーが消えないことがあった。その問題は、resourcesのコードがコピペは済んでいるものの、保存されていなかった。という状態であった。このような問題に注意しよう。
そのあとは、各フォルダーのインポートをやっていった。
これは、enemy::modの宣言である。
そして、
enemy::systemsには、このような宣言をした。
基本的には、enemy, score, starは依存関係が薄いので、そこから、やりました。
その場合は、基本的にファイルをpubにする必要はありません。score starは同様にやりました。ファイル内の要素を使いたいときは、super、外部の要素を使いたいときは、crateからパスを書いていきました。
player::systemsが結構必要なものを要求してきたので、それを頑張って、要求先の要素がある場所と同じ階層のmod.rsに、pub modやpub constとして公開していけば問題なく作成することが出来ました。
まとめると
- mod.rsやmain.rsで宣言した同じフォルダー内のファイルは、use::名前で呼び出せる。
- mod.rsやmain.rs以外の場所でファイルをスコープに入れたいときは、super::名前で呼び出す。
- 別の階層の中のファイルは、crate::パスで呼び出す。また、その階層の、mod.rsで、pub modを使って公開宣言をしておく。
- 複数要素を呼び出すときは::*;を忘れない。
- pub constを呼び出すときは、ファイル名から直接指定する。
- 依存先のファイルを保存することを忘れない。
検証

以上の画像は、プログラムをビルドしたのちに、エスケープキーを押した時のターミナルの画像である。
これにより、スコア記録(ScorePlugin)、敵とのヒット、(つまり、PlayerPluginとEnemyPlugin)が起動していることが分かる。

以上の画像は、プログラムをビルドして、約10秒後の画像である。プレイヤーの得点は約20画面上のスターは21個つまり、41個発生している。これは、10秒後にそんざいするスターの総数というのにふさわしい。
これであることから、star spawn over time関数が動作している事がわかる。また、カメラの初期設定も問題なく行われている。つまり、StarPluginとcrate::systemsも動作している。よってこの、プログラムの分割は正常に行われたと言える。
よって検証成功。