【问题标题】:How to detect a button click and a normal click in bevy如何在 bevy 中检测按钮点击和正常点击
【发布时间】:2023-02-25 04:14:46
【问题描述】:

我正在制作一款塔防游戏,但我在放置塔时遇到了问题。所以基本上我想做到这一点,以便当您单击其中一个按钮(每个按钮生成一个不同的塔)时,塔的资产/精灵应该跟随您的鼠标,并且当再次单击鼠标时它应该生成塔。

目前我的程序注册了按钮点击,但它进入了 2 个 ifs,所以当点击按钮时,它会自动在某处(甚至不在按钮下方)生成一座塔,而无需等待用户再次点击。所以 Interaction::Clicked 只检查按钮是否被点击,但不抓取鼠标点击事件,它只读取它,因此如果鼠标点击时间较长(人为点击),代码将进入第二个 if 并生成塔(我不知道为什么它会在下图中的位置生成它)。我怎样才能解决这个问题?图片:

Towers spawning in some random place. First button spawns them at around (200, 0, 0)

代码:

fn tower_button_interaction(
  mut commands: Commands,
  windows: Res<Windows>,
  mouse: Res<Input<MouseButton>>,
  assets: Res<GameAssets>,
  interaction: Query<(&Interaction, &TowerType), Changed<Interaction>>
) {
  let window = windows.get_primary().unwrap();
  for (interaction, tower_type) in &interaction {
    match interaction {
      Interaction::Clicked => {
        info!("Spawning: {tower_type} wizard");
    
        // Upon clicking the mouse, spawn the selected tower on the map
        if mouse.just_pressed(MouseButton::Left) {
          if let Some(position) = window.cursor_position() {
            spawn_tower(&mut commands, *tower_type, &assets, position.extend(0.));
          }
        }
      }
      Interaction::Hovered => {}
      Interaction::None => {}
    }
  }
}

我也尝试将 if mouse.just_pressed(MouseButton::Left) 更改为 if matches!(interaction, Interaction::Clicked),但同样的事情发生了。

【问题讨论】:

  • 是否有仅在您松开左键单击时才会触发的事件?
  • @MeetTitan mouse.just_released() 是一个函数

标签: rust game-engine bevy


【解决方案1】:

有一部分文档很好地涵盖了这一点。 https://docs.rs/bevy/latest/bevy/input/struct.Input.html#multiple-systems

如果多个系统正在检查 Input::just_pressed 或 Input::just_released 但只有一个系统应该做出反应,例如在触发状态更改的情况下,您应该考虑通过以下方式清除输入状态:

使用 Input::clear_just_pressed 或 Input::clear_just_released 代替。 在状态改变后立即调用 Input::clear 或 Input::reset。

如果您不希望其他系统接收该输入事件,那么您基本上想要清除输入。

对于你的例子:

if mouse.just_pressed(MouseButton::Left) {
  if let Some(position) = window.cursor_position() {
    spawn_tower(&mut commands, *tower_type, &assets, position.extend(0.));
    mouse.clear_just_pressed(MouseButton::Left); // <- New line here
  }
}

您还需要确保此系统在其他系统之前运行,以便它在其他系统检查之前阻止输入。有关订购系统结帐的完整指南Bevy Cheatbook: Explicit System Ordering

它会是这样的:

app
    .add_system(tower_button_interaction)
    .add_system(tower_placement_system.after(tower_button_interaction));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-11
    • 1970-01-01
    相关资源
    最近更新 更多