Bevyを使った個人でゲーム開発を行なっている登尾(のぼりお)です。今回はProcessingを扱うように図形を描く方法をBevy上で実現させる方法を解説していきます。
分かりやすく画面サイズを固定しよう
今回の例では分かりやすく画面サイズを400x400に固定します。
こうすることで、描画エリアが環境によって変わらず分かりやすくなります。
fn main() {
App::new()
.add_plugins(DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window {
resolution: (400.0, 400.0).into(),
resizable: false,
..default()
}),
..default()
}))
.add_systems(Startup, (setup_camera, draw))
.run();
}
もう一つわかりやすくするポイントとして、座標系をProcessingライクに寄せる関数を用意します。
// Canvas座標(左上0,0)→World座標変換
fn canvas_to_world(p: Vec2) -> Vec2 {
Vec2::new(p.x - 400.0 * 0.5, 400.0 * 0.5 - p.y)
}
線の描画
以下は左上から右下へ白線を引くコードになります。
let a_canvas = Vec2::new(50.0, 50.0);
let b_canvas = Vec2::new(350.0, 350.0);
let a = canvas_to_world(a_canvas);
let b = canvas_to_world(b_canvas);
let thickness = 4.0;
let delta = b - a;
let len = delta.length();
let angle = delta.to_angle();
let line_mesh = meshes.add(Rectangle {
half_size: Vec2::new(len * 0.5, thickness * 0.5),
});
commands.spawn((
Mesh2d(line_mesh),
MeshMaterial2d(materials.add(Color::WHITE)),
Transform {
translation: Vec3::new((a.x + b.x) * 0.5, (a.y + b.y) * 0.5, 0.0),
rotation: Quat::from_rotation_z(angle),
..default()
},
));
spawnする際に、Mesh2d、MeshMaterial2d、Transformを一緒に渡すことで、それぞれ図形の形、色、変形の情報を渡しています。
四角の描画
次は緑色の四角形の描画です。やや左上の位置に緑色の四角形を描画します。
let rect_pos = Vec2::new(100.0, 120.0);
let rect_size = Vec2::new(120.0, 80.0);
let rect_center = canvas_to_world(rect_pos + rect_size * 0.5);
let rect_mesh = meshes.add(Rectangle {
half_size: rect_size * 0.5,
});
commands.spawn((
Mesh2d(rect_mesh),
MeshMaterial2d(materials.add(Color::srgb_u8(0, 170, 0))),
Transform::from_xyz(rect_center.x, rect_center.y, 0.0),
));
円の描画
最後は円の描画です。青色で真ん中に円を描きます。
let circle_center_canvas = Vec2::new(200.0, 200.0);
let circle_center = canvas_to_world(circle_center_canvas);
let radius = 60.0;
let circle_mesh = meshes.add(Circle { radius });
commands.spawn((
Mesh2d(circle_mesh),
MeshMaterial2d(materials.add(Color::srgb_u8(30, 144, 255))),
Transform::from_xyz(circle_center.x, circle_center.y, 0.0)
));
おしまい
今回のコードもこれまで同様以下の個人リポジトリで公開しています。
cloneした後に、
% cargo run --example processing_like
で挙動を起動できます。
今回記事を書いて思ったのは、だいぶProcessingライクに書こうとすると結構考え方も含めて差異があるなという点でした。この辺はもう少し今後橋渡しとなる記事を書ければと思いますし、あるいはもう少しProcessingに寄せたBevy用のクレートを作ると面白そうだなと感じました。