5个版本
0.2.0 | 2023年7月11日 |
---|---|
0.1.6 | 2023年7月11日 |
0.1.5 | 2022年12月4日 |
0.1.1 | 2022年11月18日 |
0.1.0 | 2022年11月18日 |
#1494 在 游戏开发
48 每月下载次数
77KB
1.5K SLoC
🏃♂️ Bevy Quickmenu
每个游戏都需要菜单。无论是设置、暂停屏幕还是用户进入游戏时的主菜单。
虽然Bevy UI允许构建菜单,但这是一个繁琐的过程,尤其是在需要嵌套菜单的情况下。更糟糕的是,如果你想让你的菜单可以通过键盘、手柄或鼠标访问,那么所需的努力就更大了。
Bevy Quickmenu提供所有这些功能。它是一种超轻量级的构建游戏菜单的方法,可以通过所有输入设备进行控制。它甚至提供了一个简单的方法来设置 hover
状态。所有内容都可以进行自定义。
- 为bevy提供的超简单菜单插件,基于Bevy UI构建
- 处理键盘、鼠标、手柄输入
- 支持简化的样式表中的鼠标悬停状态
- 许多自定义选项(请参阅 examples/custom.rs)
用法
添加到 Cargo.toml
[dependencies]
bevy_quickmenu = "0.1.5"
版本兼容性
Bevy版本 | Crate版本 |
---|---|
0.11.0 | 0.2.0 |
0.10.0 | 0.1.6 |
0.9.0 | 0.1.5 |
演示
快速示例
examples/basic.rs
:展示其工作原理的基本示例examples/settings.rs
:包括切换游戏状态和再次显示菜单在内的完整用户设置examples/custom.rs
:展示自定义选项
所需组件的解释
状态
一个泛型类型,用于托管菜单的状态(例如,哪些项目被选中等)。每当此状态发生变化时,菜单会自动重新绘制。
动作
(符合 ActionTrait
): 此枚举定义了用户可以执行的所有操作。例如 SoundOn
、SoundOff
等。当用户执行操作(通过选择相应的菜单项)时,将在您的 ActionTrait
实现上调用 handle
方法。 ActionTrait
有两个泛型类型:您的 State
以及您可以定义的 Event
。这允许您处理您的操作
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
enum Actions {
Close,
SoundOn,
SoundOff,
Control(usize, ControlDevice),
}
impl ActionTrait for Actions {
type State = CustomState;
type Event = MyEvent;
fn handle(&self, state: &mut CustomState, event_writer: &mut EventWriter<MyEvent>) {
match self {
Actions::Close => event_writer.send(MyEvent::CloseSettings),
Actions::SoundOn => state.sound_on = true,
Actions::SoundOff => state.sound_on = false,
Actions::Control(p, d) => {
state.controls.insert(*p, *d);
}
}
}
}
屏幕
(符合 ScreenTrait
)。您的菜单中的每个页面或屏幕都由此枚举定义。请注意,菜单屏幕是 不嵌套 的!相反,ScreenTrait
有一个 resolve
函数,允许您返回给定枚举的相应菜单定义
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
enum Screens {
Root,
Controls,
Sound,
Player(usize),
}
impl ScreenTrait for Screens {
type Action = Actions;
fn resolve(&self, state: &mut CustomState) -> Menu<Screens> {
match self {
Screens::Root => root_menu(state),
Screens::Controls => controls_menu(state),
Screens::Sound => sound_menu(state),
Screens::Player(p) => player_controls_menu(state, *p),
}
}
}
菜单
菜单只是一个返回要显示的 MenuItem
列表的功能。每个菜单都需要有一个独特的 ID。示例显示了 root
和 sound
菜单的定义。
fn root_menu(_state: &mut CustomState) -> Menu<Screens> {
Menu::new(
Id::new("root"),
vec![
MenuItem::headline("Settings"),
MenuItem::action("Back", Actions::Close).with_icon(MenuIcon::Back),
MenuItem::screen("Sound", Screens::Sound).with_icon(MenuIcon::Sound),
MenuItem::screen("Controls", Screens::Controls).with_icon(MenuIcon::Controls),
],
)
}
fn sound_menu(state: &mut CustomState) -> Menu<Screens> {
Menu::new(
Id::new("sound"),
vec![
MenuItem::label("Toggles sound and music"),
MenuItem::action("On", Actions::SoundOn).checked(state.sound_on),
MenuItem::action("Off", Actions::SoundOff).checked(!state.sound_on),
],
)
}
菜单项
为了给您提供 一些 灵活性,菜单项允许您返回五种不同的类型
MenuItem::label
:一个小文本标签,不能被选择MenuItem::headline
:一个大文本标签,不能被选择MenuItem::action
:当用户选择时执行的操作MenuItem::screen
:当用户选择此选项时,深入屏幕MenuItem::image
:单个图像(包括可选的Style
)
此外,菜单项可以具有一些预定义的图标或自定义图标
MenuItem::screen("Controls", Screens::Controls).with_icon(MenuIcon::Controls)
MenuItem::screen("Save", Screens::Save).with_icon(MenuIcon::Other(icons.save.clone()))
MenuItem
也可以是勾选或取消勾选的
MenuItem::action("On", Actions::SoundOn).checked(state.sound_on)
MenuItem::action("Off", Actions::SoundOff).checked(!state.sound_on)
显示菜单
以下是从示例中提供的注释设置函数
impl Plugin for SettingsPlugin {
fn build(&self, app: &mut App) {
app
// Register a event that can be called from your action handler
.add_event::<BasicEvent>()
// The plugin
.add_plugins(QuickMenuPlugin::<Screens>::new())
// Some systems
.add_startup_system(setup)
.add_system(event_reader);
}
}
fn setup(mut commands: Commands) {
commands.spawn(Camera3dBundle::default());
commands.insert_resource(MenuState::new(
BasicState::default(),
Screens::Root,
Some(StyleSheet::default()),
))
}
移除菜单
为了移除菜单,有 bevy_quickmenu::cleanup
函数。通常,最好与 Bevy Quickmenu 允许您注册的事件一起使用
#[derive(Debug)]
enum BasicEvent {
Close,
}
impl ActionTrait for Actions {
fn handle(&self, state: &mut BasicState, event_writer: &mut EventWriter<BasicEvent>) {
match self {
Actions::Close => event_writer.send(BasicEvent::Close),
}
}
}
fn event_reader(mut commands: Commands, mut event_reader: EventReader<BasicEvent>) {
for event in event_reader.iter() {
match event {
BasicEvent::Close => bevy_quickmenu::cleanup(&mut commands),
}
}
}
自定义屏幕的截图
依赖关系
~44–78MB
~1M SLoC