<< [#4 エンティティの作成・削除](https://qiita.com/9laceef/items/04e6221ff62fa3fe1b25) [#6 アニメーション](https://qiita.com/9laceef/items/3d1ad9f60344643f642e) >>
ご注意!
この記事の内容は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
を返し、neg
は0.0~-1.0
を返します(キーボードなら0.0
or1.0
or-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なんかを使えます。
serde
とserde_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);
いつか使う機会があるかもですね。
それでは。