Rust – Bevyでノベルゲームを作る 枠の表示

Rust

前回の続きです

前回は単純な文字列を表示することができましたので、今回は枠を作ってそこに文字列を表示させるようにします。

黒い枠を100%100%で表示してみます。前回のテキストを表示の手前に実装を書きます。

use bevy::prelude::*;

fn main() {
    App::new()
    .add_plugins(DefaultPlugins)
    .add_startup_system(setup)
    .run();
}

fn setup(
    mut command: Commands,
    asset_server: Res<AssetServer>
){
    // フォントの取得
    let font = asset_server.load("fonts/FiraMono-Medium.ttf");
    // カメラの生成
    command.spawn_bundle(Camera2dBundle::default());
    // 枠の生成
    command.spawn_bundle(NodeBundle{
                style: Style {
                    size: Size::new(Val::Percent(100.0), Val::Percent(100.0)),
                    margin: UiRect::all(Val::Px(50.0)),
                    ..default()
                },
                color: Color::BLACK.into(),
                ..default()
    });
    // テキストの生成
    command.spawn_bundle(TextBundle::from_section(
        "Bevy | Rust",
        TextStyle {
            font: font.clone(), //取得したフォント
            font_size: 60.0,
            color: Color::rgb(0.9, 0.9, 0.9)
        })
        .with_style(Style{
            margin: UiRect::all(Val::Px(50.0)), // ウインドウの左下を起点に(50.0)のマージンを取る
            ..default()
        }),
    );
}

100%になっているのは高さだけで、横幅は100%になっていません。

と、コードを書きつつ、実行結果を見て思ったのはこれはHTMLとCSSにソックリだということです。今はNodeBundleという要素の横に、TextBundleという要素が横並びになっているような状態ではないでしょうか?

試しにTextBundleを消して実行すると、マージンを除けばだいたい100%で表示されました。

HTMLとCSSに似ていると書きましたが、これはWasmでWebAssemblyとして利用できるので当然だと思います。
実際にStyleはcssのflexboxシステムを利用していると書いてありました。

枠に対してテキストを子要素として登録することで、横並びの問題は解決できそうです。
とりあえずテキストの位置とかは気にしないでやってみます。

use bevy::prelude::*;

fn main() {
    App::new()
    .add_plugins(DefaultPlugins)
    .add_startup_system(setup)
    .run();
}

fn setup(
    mut command: Commands,
    asset_server: Res<AssetServer>
){
    // フォントの取得
    let font = asset_server.load("fonts/FiraMono-Medium.ttf");
    // カメラの生成
    command.spawn_bundle(Camera2dBundle::default());
    // 枠の生成
    command.spawn_bundle(NodeBundle{
                style: Style {
                    size: Size::new(Val::Percent(100.0), Val::Percent(100.0)),
                    margin: UiRect::all(Val::Px(50.0)),
                    ..default()
                },
                color: Color::BLACK.into(),
                ..default()
    })//;
    // テキストを子要素にする
    .with_children(|parent| {
            // クロージャでparentに対してspawnするように記載
            parent.spawn_bundle(TextBundle::from_section(
                "Bevy | Rust",
                TextStyle {
                    font: font.clone(), //取得したフォント
                    font_size: 60.0,
                    color: Color::rgb(0.9, 0.9, 0.9)
                })
                .with_style(Style{
                    margin: UiRect::all(Val::Px(50.0)), // ウインドウの左下を起点に(50.0)のマージンを取る
                    ..default()
                }),
            );

        }
    );
}

クロージャを利用してNodeBundleに対してTextBundleを追加しているようなイメージですね。

少しスタイルを変えてみます。

use bevy::prelude::*;

fn main() {
    App::new()
    .add_plugins(DefaultPlugins)
    .add_startup_system(setup)
    .run();
}

fn setup(
    mut command: Commands,
    asset_server: Res<AssetServer>
){
    // フォントの取得
    let font = asset_server.load("fonts/FiraMono-Medium.ttf");
    // カメラの生成
    command.spawn_bundle(Camera2dBundle::default());
    // 枠の生成
    command.spawn_bundle(NodeBundle{
                style: Style {
                    //高さは50%に指定
                    size: Size::new(Val::Percent(100.0), Val::Percent(50.0)),
                    //marginは0にしておく
                    margin: UiRect::all(Val::Px(0.0)),
                    // 追加位置を指定する(感覚cssと同じ)
                    align_items: AlignItems::FlexStart,
                    ..default()
                },
                color: Color::BLACK.into(),
                ..default()
    })
    .with_children(|parent| {
            parent.spawn_bundle(TextBundle::from_section(
                "Bevy | Rust",
                TextStyle {
                    font: font.clone(),
                    font_size: 60.0,
                    color: Color::rgb(0.9, 0.9, 0.9)
                })
                // 位置は親要素に依存させるため記載除去
                /*
                .with_style(Style{
                    margin: UiRect::all(Val::Px(50.0)), 
                    ..default()
                }),
                */
            );

        }
    );
}
  • align_items: AlignItems::FlexStart,
    • これが左下起点?

というわけでFlexEndにすると

// 追加位置を指定する(感覚cssと同じ)
align_items: AlignItems::FlexEnd,

イイ感じになりました。これでテキストに関しては親要素の左上起点にして表示されています。

この親要素と子要素という考え方は、UIとか作る際には重要になりそうです。

シリーズ記事

◆Rust – Bevyでノベルゲームを作る 文字の表示

◆Rust – Bevyでノベルゲームを作る 枠の表示

◆Rust – Bevyでノベルゲームを作る 次の文字を表示

◆Rust – Bevyでノベルゲームを作る キャラクターを表示する

コメント

タイトルとURLをコピーしました