Latest commit e6bce74
use bevy::prelude::*; /// 用`[States]`来说明如何从`Menu`(菜单)状态切换到`InGame`(游戏中)状态 fn main() { App::new() .add_plugins(DefaultPlugins) .add_state(AppState::Menu) .add_system_set(SystemSet::on_enter(AppState::Menu).with_system(设置菜单)) .add_system_set(SystemSet::on_update(AppState::Menu).with_system(菜单)) .add_system_set(SystemSet::on_exit(AppState::Menu).with_system(清理菜单)) .add_system_set(SystemSet::on_enter(AppState::InGame).with_system(设置游戏)) .add_system_set( SystemSet::on_update(AppState::InGame) .with_system(移动) .with_system(修改颜色) ) .run(); } #[derive(Debug, Clone, Eq, PartialEq, Hash)] enum AppState { Menu, InGame, } struct MenuData { button_entity: Entity, } const NORMAL_BUTTON: Color = Color::rgb(0.15, 0.15, 0.15); const HOVERED_BUTTON: Color = Color::rgb(0.25, 0.25, 0.25); const PRESSED_BUTTON: Color = Color::rgb(0.35, 0.35, 0.35); fn 设置菜单( mut commands: Commands, asset_server: Res<AssetServer>, ) { // UI摄像机 commands.spawn_bundle(UiCameraBundle::default()); let button_entity = commands .spawn_bundle(ButtonBundle { style: Style { size: Size::new(Val::Px(150.0), Val::Px(65.0)), // 中心按钮 margin: Rect::all(Val::Auto), // 水平居中子文本 justify_content: JustifyContent::Center, // 竖直居中子文本 align_items: AlignItems::Center, ..Default::default() }, color: NORMAL_BUTTON.into(), ..Default::default() }) .with_children(|child_builder| { child_builder.spawn_bundle(TextBundle { text: Text::with_section( "play", TextStyle { font: asset_server.load("fonts/FiraSans-Bold.ttf"), font_size: 40.0, color: Color::rgb(0.9, 0.9, 0.9), }, Default::default(), ), ..Default::default() }); }) .id(); commands.insert_resource(MenuData { button_entity }); } fn 菜单( mut state: ResMut<State<AppState>>, mut interaction_query: Query< (&Interaction, &mut UiColor), (Changed<Interaction>, With<Button>), >, ) { for (interaction, mut color) in interaction_query.iter_mut() { match *interaction { Interaction::Clicked => { *color = PRESSED_BUTTON.into(); state.set(AppState::InGame).unwrap(); } Interaction::Hovered => { *color = HOVERED_BUTTON.into(); } Interaction::None => { *color = NORMAL_BUTTON.into(); } } } } fn 清理菜单( mut commands: Commands, menu_data: Res<MenuData>, ) { commands.entity(menu_data.button_entity).despawn_recursive(); } fn 设置游戏( mut commands: Commands, asset_server: Res<AssetServer>, ) { commands.spawn_bundle(OrthographicCameraBundle::new_2d()); commands.spawn_bundle(SpriteBundle { texture: asset_server.load("icon.png"), ..Default::default() }); } const SPEED: f32 = 100.0; fn 移动( time: Res<Time>, input: Res<Input<KeyCode>>, mut query: Query<&mut Transform, With<Sprite>>, ) { for mut transform in query.iter_mut() { let mut direction = Vec3::ZERO; if input.pressed(KeyCode::Left) { direction.x += -1.0; } if input.pressed(KeyCode::Right) { direction.x += 1.0; } if input.pressed(KeyCode::Up) { direction.y += 1.0; } if input.pressed(KeyCode::Down) { direction.y += -1.0; } if direction != Vec3::ZERO { transform.translation += direction.normalize() * SPEED * time.delta_seconds(); } } } fn 修改颜色( time: Res<Time>, mut query: Query<&mut Sprite>, ) { for mut sprite in query.iter_mut() { sprite .color .set_b((time.seconds_since_startup() * 0.5).sin() as f32 + 2.0); } }