Bevy Input

205 阅读2分钟

mk370-combo-business-gallery-1.png

输入对于游戏逻辑是非常重要的,在Bevy中,支持以下的输入资源:

资源描述
Axis某些输入设备的位置数据
ButtonInput可按下抬起的输入
GamepadAxis游戏手柄的轴输入
GamepadButton代表游戏手柄的单个按钮,如同键盘按键
Gamepads已连接的游戏手柄集合
TouchInput触摸的输入事件
Touches触摸设备集合

键盘

处理键盘输入,我们会使用ButtonInput<T>资源,它拥有一组很方便的方法,我们可以用来检查相关的行为:

以下是修正了翻译错误后更准确的内容:

方法描述
pressed在按下和松开事件之间将返回 true
just_pressed在按下事件发生后的一帧内将返回 true
just_released在松开事件发生后的一帧内将返回 true

现在,我们可以检查某个按钮是否按下了:

fn key_pressed(input: Res<ButtonInput<KeyCode>>) {
    if input.just_pressed(KeyCode::Space) {
        info!("Jump");
    }
}

组合键

如果我们想检查某个组合键(例如Ctrl + Shift + C)是否按下,可以这样做:

fn key_combine_press(input: Res<ButtonInput<KeyCode>>) {
    let ctrl = input.any_pressed([KeyCode::ControlLeft, KeyCode::ControlRight]);
    let shift = input.any_pressed([KeyCode::ShiftLeft, KeyCode::ShiftRight]);
    if ctrl && shift && input.just_pressed(KeyCode::KeyC) {
        info!("All select");
    }
}

运行前请确保没有存在快捷键占用的情况。

鼠标

鼠标和键盘的处理方式完全相同,只是ButtonInput<T>的泛型变成了MouseButton

fn mouse_press(input: Res<ButtonInput<MouseButton>>) {
    if input.just_pressed(MouseButton::Left) {
        info!("Shoot");
    }
}

我们当然可以同时检测多种类型的数据:

fn keyboard_mouse_press(mouse: Res<ButtonInput<MouseButton>>, key: Res<ButtonInput<KeyCode>>) {
    if mouse.just_pressed(MouseButton::Left) && key.pressed(KeyCode::ControlLeft) {
        info!("Back");
    }
}

触摸事件

如果想检测屏幕的触摸事件(例如手机等移动设备),可以使用Touches

fn touch_system(touches: Res<Touches>) {
  for touch in touches.iter_just_pressed() {
    info!(
      "just pressed touch with id: {:?}, at: {:?}",
      touch.id(),
      touch.position()
    );
  }

  for touch in touches.iter_just_released() {
    info!(
      "just released touch with id: {:?}, at: {:?}",
      touch.id(),
      touch.position()
    );
  }

  for touch in touches.iter_just_canceled() {
    info!("canceled touch with id: {:?}", touch.id());
  }

  // you can also iterate all current touches and retrieve their state like this:
  for touch in touches.iter() {
    info!("active touch: {:?}", touch);
    info!("  just_pressed: {}", touches.just_pressed(touch.id()));
  }
}

窗口事件

与之前不一样的地方,鼠标移动事件是通过EventReader<CursorMoved>读取的,关于EventReader我们会后续讲解:

fn cursor_events(mut cursor_evr: EventReader<CursorMoved>) {
  for ev in cursor_evr.read() {
    println!(
      "New cursor position: X: {}, Y: {}, in Window ID: {:?}",
      ev.position.x, ev.position.y, ev.window
    );
  }
}

使用该方法,可以获取鼠标在窗口上的移动时间。