use crate::prelude::*; /// Menu Plugin; empty struct for Plugin impl pub(crate) struct DicePlugin; impl Plugin for DicePlugin { fn build(&self, app: &mut App) { app.add_event::(); app.add_systems(Startup, init_dice_ui); app.add_systems(Startup, init_dice); app.add_systems( Update, button_emit_event::.run_if(any_component_changed::), ); app.add_systems(Update, draw_die.run_if(any_component_changed::)); app.add_systems(Update, roll_die.run_if(on_event::())); app.add_systems(Update, move_die.run_if(on_event::())); } } #[derive(Event, Clone)] enum DiceAction { Roll, } /// Create UI for the Dice game at startup fn init_dice_ui(mut commands: Commands) { commands .spawn((GameChoice::Dice, MenuState::Closed, Pickable::IGNORE)) .add(UiContainer) .with_children(|parent| { parent .spawn_empty() .add(UiTitle { text: "Dice" }) .add(UiStyle(Style { position_type: PositionType::Absolute, top: Val::Px(0.0), left: Val::Px(0.0), margin: UiRect::all(Val::Px(5.0)), border: UiRect::all(Val::Px(1.0)), ..default() })); parent .spawn((SetState(GameChoice::None), SetState(MenuState::Open))) .add(UiButton { label: "Menu" }) .add(UiStyle(Style { position_type: PositionType::Absolute, top: Val::Px(0.0), right: Val::Px(0.0), margin: UiRect::all(Val::Px(5.0)), padding: UiRect::all(Val::Px(5.0)), border: UiRect::all(Val::Px(1.0)), ..default() })); parent .spawn(EmitEvent(DiceAction::Roll)) .add(UiButton { label: "Roll" }) .add(UiStyle(Style { position_type: PositionType::Absolute, margin: UiRect::all(Val::Px(5.0)), padding: UiRect::all(Val::Px(5.0)), border: UiRect::all(Val::Px(1.0)), ..default() })); }); } fn init_dice( mut meshes: ResMut>, mut materials: ResMut>, mut commands: Commands, ) { [ ["a", "b", "c", "d", "e", "f"], ["g", "h", "i", "j", "k", "l"], ["m", "n", "o", "p", "q", "r"], ] .into_iter() .enumerate() .for_each(|(idx, set)| { commands .spawn(( GameChoice::Dice, MenuState::Closed, Die::new(set), PickableBundle { ..default() }, On::>::target_component_mut::(|m, transform| { transform.translation.x += m.delta.x; transform.translation.y -= m.delta.y; }), )) .insert(MaterialMesh2dBundle { mesh: meshes .add(Rectangle { half_size: Vec2::splat(32.0), }) .into(), material: materials.add(Color::PINK), ..default() }) .insert(Text2dBundle { text: Text::from_section( "", TextStyle { color: Color::BLACK, font_size: 32.0, ..default() }, ), ..default() }) .insert(Transform::from_xyz(idx as f32 * 100.0, 100.0, 0.0)); }); } fn draw_die(mut q: Query<(&Die, &mut Text), Changed>) { q.iter_mut().for_each(|(d, mut t)| { info!("Dice currently reads {:?}", d.get()); t.sections[0].value.replace_range(.., d.get()); }); } fn roll_die(mut r: EventReader, mut q: Query<&mut Die>, time: Res