LoginSignup
6
1

More than 3 years have passed since last update.

Rust + Entity Component System で仕様変更に強いゲーム設計 その4−1 〜 剣を表示

Last updated at Posted at 2020-01-27

目次

その1 〜 序文
その2 〜 キャラの移動
その3−1 〜 コンポーネントの設計
その3−2 〜 システムの設計
その3−3 〜 メイン部分
【イマココ】その4−1 〜 剣を表示
その4−2 〜 アニメーションコンポーネント
その4-3 〜 アニメーションを動かす
その5-1~ あたり判定
その5-2~ やられアニメーション
その6 〜 これまでの振り返り

前回まで

前回、その3まででは、エンティティを管理する仕組みを実装し、プレイヤーキャラと敵キャラを動かすところまでやりました。
その4では、キャラをアニメーションさせる仕組みを実装して、

  • 何も操作していないときは待機アニメーション
  • スペースキーを押すと、攻撃アニメーション

が動くようにしてみましょう。
その4も長くなりそうなので、何回かに分けて投稿します。

今回つくったもの

game-step4.gif

上図の様になりました。
待機アニメーションとしては、円が一定間隔で縮小拡大を繰り返す様ににしました。
円のところから伸びている線は、剣です。
剣は、今のキャラの向きを表すと共に、攻撃すると左右に動きます。(こういうの見た事ある!)

ソースはこちら
https://github.com/mas-yo/rust-ecs-game/tree/step-4

スケール変化と剣の表示

円のスケール変化と、剣を表示するため、CharacterView コンポーネントに以下のメンバを追加します。

  • 現在向いている方向を示す direction
  • 武器の方向を示す weapon_direction
  • 円の半径に対するスケール値 radius_scale

pub(crate) struct CharacterView {
    pub position: Vector,
    pub direction: f32,     //追加
    pub radius: f32,
    pub radius_scale: f32,  //追加
    pub color: Color,
    pub weapon_direction: f32,  //追加
}

これを表示するための System は、

impl SystemProcess for System<Window, CContainer<CharacterView>> {
    fn process(window: &mut Self::Update, views: &Self::Refer) {
        views.iter().for_each(|(_, view)| {

            //半径にスケールをかける
            window.draw(
                &Circle::new(
                    (view.position.x, view.position.y),
                    view.radius * view.radius_scale,
                ),
                Col(view.color),
            );

            //現在の向き+武器の向きの方向に線を引く
            let dir = view.direction + view.weapon_direction;
            let line_end = (
                view.position.x + dir.cos() * view.radius * 1.8f32,
                view.position.y + dir.sin() * view.radius * 1.8f32,
            );
            window.draw(
                &Line::new((view.position.x, view.position.y), line_end),
                Col(view.color),
            );
        });
    }
}

これで表示の準備が整いました。

ひとまず、現在の進行方向がCharacterView::directionが反映されるようにします。

impl SystemProcess
    for System<CContainer<CharacterView>, (&CContainer<Position>, &CContainer<Velocity>)>
{
    fn process(views: &mut Self::Update, pos_vel: &Self::Refer) {
        views
            .iter_mut()
            .zip_entity2(pos_vel.0, pos_vel.1)
            .for_each(|(view, pos, vel)| {
                view.position.x = pos.x;
                view.position.y = pos.y;
                if vel.x != 0f32 || vel.y != 0f32 {
                    view.direction = vel.y.atan2(vel.x);
                }
            });
    }
}

CharacterViewの更新処理は、前回までPositionだけに依存する形になっていました。
今回はdirectionの更新のために、Velocityも参照するようにしました。

変更前
impl SystemProcess for System<CContainer<CharacterView>, CContainer<Position>>
変更後
impl SystemProcess
    for System<CContainer<CharacterView>, (&CContainer<Position>, &CContainer<Velocity>)>

これでひとまず、剣が表示されていて、キャラの進行方向に表示される様になりました。

次回から、アニメーションの実装に入って行きます。

6
1
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
6
1