今回のメモ
前回の内容はこちら。( https://odevnote.net/article/bevy_wasm_2d_basis ) BevyでWebAssembly出力の2Dゲームを作るにあたっての最低限の部分の構築をしました。
何もない青い画面(ブルスクじゃないよ)で終わった前回の内容をベースに
- 四角形のSprite を 表示させる(今回)
- アセットとして用意した画像の読み込みとSpriteへの反映 (次回)
- エンティティの画像マテリアルを切り替える(そのまた次回)
とそれぞれのメモを残していきます。
今回の内容は さらに次の内容に分かれます。
- Commands を mut な引数に持つシステムを定義する(関数定義)
- Commands のコンポーネントを一括生成(SpriteBundleとspawn_bundle(...))
- Assetsへのマテリアルの登録
なお、appディレクトリーを作り、適宜、モジュール分割を行っています。詳しくはGithub でディレクトリー構成を見ていただければ。 今回の内容であればエントリーポイントに直書きで良いと思いますが、今後メモしたいことの難易度とかがどうなるかわからないので。
Commands について
Bevy の ECS の仕組みでシステムをに担当しているのは関数です。
コンポーネントの生成などもシステムに登録される関数を通じて行われますが、 このとき Commands という構造体(trait?)に実装されている関数を使います。
それを使った関数を作っていきますが、まずは関数をシステムとして登録するところから。
actor.rs
pub fn spawn_actor(commands:mut Commands){
}
app.rs
//略(use)
pub fn run(){
let mut app=App::build();
//略(ウィンドウ・カメラ・デフォルトプラグインの設定)
//2Dキャラクターのセットアップ(の予定)
app.add_startup_system(actor::actor2D::spawn_actor.system())
app.run();
}
//略
spawn_actor 関数 の実装.1 Bundle生成
登録した actor::actor2d::spawn_actor 関数の中で 画像の追加をします。
actor2D.rs
use bevy::prelude::{*};
pub fn spawn_actor(mut commands:Commands){
commands.spawn_bundle(
SpriteBundle{
..Default::default()
}
);
}
ビルドして実行しても画面上には何も見えません。
次に設定するもの: SpriteコンポーネントとColorMaterialのHandle
画面上に絵を表示するにあたって SpriteBundle構造体 の中身を変更します。
SpriteBundle は いくつかのコンポーネントの集合体になっています。 Bundleはコンポーネントを束ねて一括して登録する仕組みらしいです。 ここでは次の2つのコンポーネント変数を設定します。
- sprite:Sprite型
- Handle>ColorMaterial<
Sprite コンポーネントのメンバー変数の値で画像の大きさや反転などの設定が可能です。 Handle<ColorMaterial>;
そして色やテクスチャーなどはColorMaterial型の変数を設定します。正しくはColorMaterialへの参照を保持する型です。
spawn_actor 関数 の実装.2 Spriteコンポーネントの値を設定
actor2D.rs
use bevy::prelude::{*};
pub fn spawn_actor(mut commands:Commands){
commands.spawn_bundle(
SpriteBundle{
sprite:Sprite{
resize_mode:SpriteResizeMode::Manual,
size:Vec2::new(32.,32.),
..Default::default()
},
}
);
}
SpriteBundleが内包するメンバー変数のうちSpriteコンポーネントの値を設定しました。 後の値はデフォルトのままです。
この時点でも特に何かが映るわけではありません。
spawn_actor 関数 の実装.3 ColorMaterial の 登録とハンドルの利用
画像の描画に使われるマテリアルは、ColorMaterialという型で表現されます。 実際にこれを直接扱うことは少なく、Handleというジェネリクス型を用いて参照を管理します。 また、Assetsのジェネリクス型で定義されたリソースを使うと、 アプリケーション内の特定のリソースをハンドルを通じて管理することができます。
- AssetsにColorMaterialを登録する
- 登録の関数の返り値がHandleとして帰ってくる
- そのHandleをSpriteBundleに設定する
の3点、内容を変更します。
actor2D.rs
use bevy::prelude::{*};
pub fn spawn_actor(mut commands:Commands,mut material_store:ResMut<Assets<ColorMaterial>>){
let material=ColorMaterial{
color:Color::RED,
..Default::default()
};
let handle=material_store.add(material);
commands.spawn_bundle(
SpriteBundle{
sprite:Sprite{
resize_mode:SpriteResizeMode::Manual,
size:Vec2::new(32.,32.),
..Default::default()
},
material:handle,
..Default::default()
}
);
}
実行すると次のようになります。
メモ:Component と Bundle と 他の言語のinterface
ECSの基本となるComponent。Bevyでは基本型をシンプルに内包するような型をいくつも定義します。 今回のBundleはそれをまとめてあつかえるようにしたものですが、
Component -> getterつきのinterface Bundle -> getterの実装としてシンプルなモデルクラス
定義後のデータとしての扱い方は違いますが、 Bevyを使うとこのような対応で済む印象だなあと思いました。 (抽象化という一点で同じだから当然なのかも・・・)