use super::*; /// A good starting place for creating a game building on top of the base Bevy app pub struct BaseGamePlugin { pub title: String, pub name: String, pub game_type: GameType, pub target_resolution: WindowResolution, } pub enum GameType { Three, Two, } impl Default for BaseGamePlugin { fn default() -> Self { BaseGamePlugin { title: "My Game".into(), name: "mygame".into(), game_type: GameType::Three, target_resolution: WindowResolution::default(), } } } impl Plugin for BaseGamePlugin { fn build(&self, app: &mut App) { app.add_plugins( DefaultPlugins .set(WindowPlugin { primary_window: Some(Window { fit_canvas_to_parent: true, resolution: self.target_resolution.clone(), ..default() }), ..default() }) .set(ImagePlugin::default_nearest()) .set(AssetPlugin { meta_check: AssetMetaCheck::Never, ..default() }), ) .add_plugins(DebuggingPlugin) .add_plugins(MeshPickingPlugin) .add_plugins(LoadingPlugin) .add_plugins(BaseUiPlugin) .add_plugins(ParallaxPlugin) // .add_systems(Update, scale_game.run_if(any_component_changed::)) .insert_resource(TargetResolution(self.target_resolution.clone())) .init_resource::(); match self.game_type { GameType::Two => app.add_systems(Startup, create_camera_2d), GameType::Three => app.add_systems(Startup, create_camera_3d), }; } } #[derive(Resource)] struct TargetResolution(WindowResolution); /// System to toggle the visibility of entities based on their state pub fn toggle_state_visibility( mut q: Query<(Entity, &mut Visibility, &S)>, curr: Res>, ) { q.iter_mut().for_each(|(e, mut v, s)| { if curr.get() == s { *v = Visibility::Inherited; } else { *v = Visibility::Hidden; } debug!("Changing visibility of {:?} to {:?}", e, *v); }); } pub fn create_camera_3d(mut commands: Commands) { // 3d camera info!("Spawning 3d camera"); commands.spawn(( Camera3d { ..default() }, Camera { ..default() }, AmbientLight::default(), )); } pub fn create_camera_2d(mut commands: Commands) { // 2d camera info!("Spawning 2d camera"); commands.spawn((Camera2d, Camera { ..default() })); } #[derive(Default, Resource)] pub struct Rand(pub RandomState); /// Scale the game based on the difference between the target and real resolution fn scale_game( mut window: Single<&mut Window>, target_resolution: Res, mut last_scale_factor: Local, ) { let current_resolution: Vec2 = window.resolution.size(); let scale_width = current_resolution.x.round() / target_resolution.0.width().round(); let scale_height = current_resolution.y.round() / target_resolution.0.height().round(); let scale_factor = f32::min(scale_width, scale_height); if window.resolution.scale_factor() != scale_factor { // Need to check the previously set scale factor because the system can flip-flop otherwise if scale_factor != *last_scale_factor { *last_scale_factor = window.resolution.scale_factor(); window.resolution.set_scale_factor(scale_factor); } } }