0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Rust×Bevyゲーム開発レシピ: Processingの様に図形を描画しよう

Posted at

Bevyを使った個人でゲーム開発を行なっている登尾(のぼりお)です。今回はProcessingを扱うように図形を描く方法をBevy上で実現させる方法を解説していきます。

スクリーンショット 2025-08-25 16.44.09.png

分かりやすく画面サイズを固定しよう

今回の例では分かりやすく画面サイズを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用のクレートを作ると面白そうだなと感じました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?