LoginSignup
1
0

More than 3 years have passed since last update.

Rustで書かれたゲームエンジンamethyst勉強記#5

Last updated at Posted at 2019-05-22

<< #4 エンティティの作成・削除  #6 アニメーション >>

ご注意!

この記事の内容は2019/06/17現在の最新版amethystクレート(v0.11.0)では仕様が変わっており動きません!随時更新していきますので、しばしお待ちください。
もし更新が待てなかったり直接尋ねたいことなどありましたらコメントにてお願いいたします。

はじめに

#3ではマウスからの入力を扱いました。今回は設定ファイルを用いたキーボード入力について扱っていきます。

bindings.ron

ronファイルについては過去の章を参照。Key()に与えるキーの種類についてはこちら。ちなみにKey()の部分をController()などに変えると別の入力を扱うこともできると思われます(=>リファレンス)。

(
  axes: {
    "x_axis": Emulated(pos: Key(Right), neg: Key(Left)),
    "y_axis": Emulated(pos: Key(Up), neg: Key(Down)),
  },
  actions: {},
)

"x_axis", "y_axis"はリストのキーになります。posはそのキーが押されているときに0.0~1.0を返し、neg0.0~-1.0を返します(キーボードなら0.0or1.0or-1.0)。両方を押していると合計で0.0になります。

main.rs

例によってインポートは省略しています。

// examples/06_animation/main.rs

struct ExampleState;

impl SimpleState for ExampleState {
    fn handle_event(
        &mut self,
        _: StateData<'_, GameData<'_, '_>>,
        event: StateEvent,
    ) -> SimpleTrans {
        if let StateEvent::Window(e) = event {
            if is_key_down(&e, VirtualKeyCode::Escape) {
                return Trans::Quit;
            }
        }
        Trans::None
    }
}

struct ExampleSystem;

impl<'s> System<'s> for ExampleSystem {
    type SystemData = Read<'s, InputHandler<String, String>>;

    fn run(&mut self, input: Self::SystemData) {
        let x_axis = input.axis_value("x_axis");
        let y_axis = input.axis_value("y_axis");
        match (x_axis, y_axis) {
            (Some(x_axis), Some(y_axis)) => {
                println!("x_axis: {}, y_axis: {}", x_axis, y_axis);
            }
            _ => {}
        }
    }
}

fn main() -> amethyst::Result<()> {
    // amethyst::start_logger(Default::default());

    let app_root = PathBuf::from(application_root_dir()).join("examples/05_keyboard_input/");

    let pipe = Pipeline::build().with_stage(
        Stage::with_backbuffer()
            .clear_target([1.0; 4], 1.0)
            .with_pass(DrawFlat2D::new())
    );
    let config = DisplayConfig::load(app_root.join("config.ron"));
    let render_bundle = RenderBundle::new(pipe, Some(config));

    let input_bundle = InputBundle::<String, String>::new()
        .with_bindings_from_file(app_root.join("bindings.ron"))?;

    let game_data = GameDataBuilder::new()
        .with_bundle(render_bundle)?
        .with_bundle(input_bundle)?
        .with(ExampleSystem, "example-system", &[]);

    Application::new(app_root, ExampleState, game_data)?.run();

    Ok(())
}

with_bindings_from_fileメソッドにより、いままで作成していたInputBundleに設定ファイルから情報を読み込ませています。
またExampleSystem内でキーボードの入力を受け取っています。

struct ExampleSystem;

impl<'s> System<'s> for ExampleSystem {
    type SystemData = Read<'s, InputHandler<String, String>>;

    fn run(&mut self, input: Self::SystemData) {
        let x_axis = input.axis_value("x_axis");
        let y_axis = input.axis_value("y_axis");
        match (x_axis, y_axis) {
            (Some(x_axis), Some(y_axis)) => {
                println!("x_axis: {}, y_axis: {}", x_axis, y_axis);
            }
            _ => {}
        }
    }
}

axis_valueにキーを与えることで、対応した軸の値を得ることができます。

おわりに

お疲れさまでした。cargo run --example 05で真っ白な画面が現れ、矢印キーを押して値が変化するのを確認出来たら完成です!

次の章ではアニメーションについて解説する予定です。
その次#7では、今までの知識を用いて簡単なゲームを作ってみようと思います。

バインディングのキーの型

ちなみに少々面倒ではありますが、キーはStringではなく自作のenumなんかを使えます。
serdeserde_deriveクレートを利用し以下のようにキーとなるものを用意します。

use serde::*;

#[derive(Hash, Eq, PartialEq, Clone, Serialize, Deserialize)]
enum Key {
    X_AXIS, Y_AXIS
}

こうすることで、bindings.ronは次のようにキーを設定できます。

(
  axes: {
    X_AXIS: Emulated(pos: Key(Right), neg: Key(Left)),
    Y_AXIS: Emulated(pos: Key(Up), neg: Key(Down)),
  },
  actions: {},
)

取得する際は次のようになります。Borrow<K>を必要とするため、参照を使っている点には注意。

let x_axis = input.axis_value(&Key::X_AXIS);
let y_axis = input.axis_value(&Key::Y_AXIS);

いつか使う機会があるかもですね。

それでは。

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