目次
その1 〜 序文
その2 〜 キャラの移動
その3−1 〜 コンポーネントの設計
その3−2 〜 システムの設計
その3−3 〜 メイン部分
【イマココ】その4−1 〜 剣を表示
その4−2 〜 アニメーションコンポーネント
その4-3 〜 アニメーションを動かす
その5-1~ あたり判定
その5-2~ やられアニメーション
その6 〜 これまでの振り返り
前回まで
前回、その3まででは、エンティティを管理する仕組みを実装し、プレイヤーキャラと敵キャラを動かすところまでやりました。
その4では、キャラをアニメーションさせる仕組みを実装して、
- 何も操作していないときは待機アニメーション
- スペースキーを押すと、攻撃アニメーション
が動くようにしてみましょう。
その4も長くなりそうなので、何回かに分けて投稿します。
今回つくったもの
上図の様になりました。
待機アニメーションとしては、円が一定間隔で縮小拡大を繰り返す様ににしました。
円のところから伸びている線は、剣です。
剣は、今のキャラの向きを表すと共に、攻撃すると左右に動きます。(こういうの見た事ある!)
ソースはこちら
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>)>
これでひとまず、剣が表示されていて、キャラの進行方向に表示される様になりました。
次回から、アニメーションの実装に入って行きます。