diff --git a/Cargo.lock b/Cargo.lock index a1da89d..250a328 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -327,15 +327,12 @@ dependencies = [ "bevy_asset", "bevy_color", "bevy_core", - "bevy_core_pipeline", "bevy_ecs", "bevy_egui", "bevy_hierarchy", "bevy_log", "bevy_math", - "bevy_pbr", "bevy_reflect", - "bevy_render", "bevy_state", "bevy_time", "bevy_utils", @@ -650,7 +647,6 @@ dependencies = [ "bevy_ecs", "bevy_gizmos_macros", "bevy_math", - "bevy_pbr", "bevy_reflect", "bevy_render", "bevy_sprite", @@ -2270,7 +2266,9 @@ dependencies = [ "bevy", "bevy-inspector-egui", "bevy_ecs_tilemap", + "bevy_egui", "bevy_framepace", + "egui", "rand", "rand_pcg", "rand_seeder", diff --git a/Cargo.toml b/Cargo.toml index 744f970..5726c47 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,6 @@ bevy = { version = "0.14.0", default-features = false, features = [ "bevy_text", # for writing characters to the screen "bevy_ui", "bevy_winit", - "bevy_pbr", "multi_threaded", # go faster "png", "x11", # run on non-wayland linuxes too @@ -36,9 +35,11 @@ bevy = { version = "0.14.0", default-features = false, features = [ # "bevy_dev_tools", # possibly-useful development tools # "detailed_trace", # probably useful troubleshooting information during runtime ] } -bevy-inspector-egui = "0.25.1" +bevy-inspector-egui = { version = "0.25.1", default_features = false } bevy_ecs_tilemap = "0.14.0" +bevy_egui = "0.28.0" bevy_framepace = "0.17.1" +egui = "0.28.1" rand = "0.8.5" rand_pcg = "0.3.1" rand_seeder = "0.3.0" diff --git a/src/input.rs b/src/input.rs index a2a385e..5d22d8e 100644 --- a/src/input.rs +++ b/src/input.rs @@ -1,8 +1,4 @@ -use bevy::{ - color::palettes::css::{GREEN, RED}, - prelude::*, - window::PrimaryWindow, -}; +use bevy::{prelude::*, window::PrimaryWindow}; #[derive(Resource, Default, Debug, Clone, PartialEq)] pub struct Input { @@ -13,7 +9,7 @@ pub struct Input { } pub fn process_input( - mut gizmos: Gizmos, + mut _gizmos: Gizmos, mut input: ResMut, keys: Res>, // mouse: Res>, @@ -52,7 +48,9 @@ pub fn process_input( // x increases as thing moves right // y increases as thing moves up - // with this in mind, to convert mouse coordinates to world coordinates for comparing against our logical window center, we take the absolute of the difference in height + // with this in mind, to convert mouse coordinates to world coordinates + // for comparing against our logical window center, we take the absolute of the + // difference in height // gizmos.line(Vec3::ZERO, Vec3::X * 100., GREEN); if let Ok(window) = window.get_single() { @@ -61,6 +59,9 @@ pub fn process_input( let center = size / 2.; let modified_target = target.with_y(size.y - target.y) - center; // gizmos.line(Vec2::ZERO.extend(0.), modified_target.extend(0.), RED); + + // the angle of the resulting vector should be the angle from the + // center of the screen to the mouse input.angle = modified_target.to_angle(); } } diff --git a/src/inspector.rs b/src/inspector.rs new file mode 100644 index 0000000..5dec1f7 --- /dev/null +++ b/src/inspector.rs @@ -0,0 +1,46 @@ +use bevy::window::PrimaryWindow; +use bevy_inspector_egui::bevy_inspector; + +use crate::prelude::*; + +#[derive(Component)] +pub struct HideFromInspector; + +pub struct InspectorPlugin; +impl Plugin for InspectorPlugin { + fn build(&self, app: &mut App) { + app.add_plugins(( + bevy_egui::EguiPlugin, + bevy_inspector_egui::DefaultInspectorConfigPlugin, + )); + app.add_systems(Update, inspector_ui); + } +} + +fn inspector_ui(world: &mut World) { + let Ok(egui_context) = world + .query_filtered::<&mut bevy_egui::EguiContext, With>() + .get_single(world) + else { + return; + }; + let mut egui_context = egui_context.clone(); + + egui::Window::new("World").show(egui_context.get_mut(), |ui| { + egui::ScrollArea::vertical().show(ui, |ui| { + egui::CollapsingHeader::new("Entities") + .default_open(true) + .show(ui, |ui| { + bevy_inspector::ui_for_world_entities_filtered::>( + world, ui, false, + ); + }); + egui::CollapsingHeader::new("Resources").show(ui, |ui| { + bevy_inspector_egui::bevy_inspector::ui_for_resources(world, ui); + }); + egui::CollapsingHeader::new("Assets").show(ui, |ui| { + bevy_inspector_egui::bevy_inspector::ui_for_all_assets(world, ui); + }); + }); + }); +} diff --git a/src/main.rs b/src/main.rs index b494d66..1cd9aeb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ mod camera; mod game; mod input; +mod inspector; mod main_menu; mod map; mod movement; @@ -63,7 +64,7 @@ fn main() -> AppExit { .set(ImagePlugin::default_nearest()), bevy::diagnostic::FrameTimeDiagnosticsPlugin, bevy_framepace::FramepacePlugin, - // bevy_inspector_egui::quick::WorldInspectorPlugin::new(), + inspector::InspectorPlugin, TilemapPlugin, )); @@ -78,11 +79,6 @@ fn main() -> AppExit { .init_state::() .init_state::(); - app.insert_resource(AmbientLight { - color: Color::srgb(1., 1., 1.), - brightness: 1., - }); - app.configure_sets( Update, ( @@ -116,6 +112,7 @@ fn main() -> AppExit { input::process_input, (update,).after(input::process_input), ( + // map::update, player::control, player::meow_on_r, player::player_debug_info, @@ -151,6 +148,7 @@ fn startup(mut commands: Commands) { let font_size = 48.; commands.spawn(( FpsText, + Name::new("FpsText"), TextBundle::from_sections([ TextSection::new( "FPS: ", diff --git a/src/main_menu.rs b/src/main_menu.rs index c2730c0..dd94655 100644 --- a/src/main_menu.rs +++ b/src/main_menu.rs @@ -7,6 +7,7 @@ pub fn startup(mut commands: Commands) { commands .spawn(( MainMenu, + Name::new("MenuRoot"), NodeBundle { style: Style { width: Val::Percent(100.0), @@ -20,6 +21,7 @@ pub fn startup(mut commands: Commands) { .with_children(|parent| { // text parent.spawn(( + Name::new("Text"), TextBundle::from_section( "Text Example\nPress ENTER to play", TextStyle { @@ -37,20 +39,23 @@ pub fn startup(mut commands: Commands) { Label, )); - parent.spawn(NodeBundle { - style: Style { - width: Val::Px(200.0), - height: Val::Px(200.0), - position_type: PositionType::Absolute, - left: Val::Px(210.), - bottom: Val::Px(10.), - border: UiRect::all(Val::Px(20.)), + parent.spawn(( + Name::new("SomeFreakin'Square"), + NodeBundle { + style: Style { + width: Val::Px(200.0), + height: Val::Px(200.0), + position_type: PositionType::Absolute, + left: Val::Px(210.), + bottom: Val::Px(10.), + border: UiRect::all(Val::Px(20.)), + ..default() + }, + border_color: Color::srgb(0., 1., 0.).into(), + background_color: Color::srgb(0.4, 0.4, 1.).into(), ..default() }, - border_color: Color::srgb(0., 1., 0.).into(), - background_color: Color::srgb(0.4, 0.4, 1.).into(), - ..default() - }); + )); }); } diff --git a/src/map.rs b/src/map.rs index d5dedfc..e2fa50d 100644 --- a/src/map.rs +++ b/src/map.rs @@ -1,5 +1,9 @@ -use crate::prelude::*; -use bevy_ecs_tilemap::prelude::*; +use crate::{inspector::HideFromInspector, prelude::*}; +// use bevy::{ +// ecs::world::CommandQueue, +// tasks::{AsyncComputeTaskPool, Task}, +// }; +// use bevy_ecs_tilemap::prelude::*; use rand::prelude::*; use rand_pcg::Pcg64; use rand_seeder::Seeder; @@ -7,74 +11,131 @@ use rand_seeder::Seeder; #[derive(Component, Debug)] pub struct Tilemap; -pub fn spawn(mut commands: Commands, assets: Res) { +// #[derive(Component)] +// struct MapGen(Task); + +/// This worked but had performance issues, so I decided to go with bevy_ecs_tilemap +pub fn spawn_raw_tiles(mut commands: Commands, assets: Res) { // let task_pool = AsyncComputeTaskPool::get(); // let task = task_pool.spawn(async move {}); - let mut rng: Pcg64 = Seeder::from("stripy zebra").make_rng(); - let size = TilemapSize { x: 1024, y: 1024 }; - let tilemap_entity = commands.spawn_empty().id(); - let mut tile_storage = TileStorage::empty(size); - let mut batch = Vec::::with_capacity(size.x as usize * size.y as usize); - for x in 0..size.x { - for y in 0..size.y { - let tile_pos = TilePos { x, y }; - let texture_index = TileTextureIndex(if rng.gen_range(0..1000) > 925 { - rng.gen_range(0..(16 * 8)) - } else { - 0 - }); - // let texture_index = TileTextureIndex(0); - // let tile_entity = commands - // .spawn(TileBundle { - // position: tile_pos, - // tilemap_id: TilemapId(tilemap_entity), - // texture_index, - // ..Default::default() - // }) - // .id(); - // let tile_entity = commands - batch.push(TileBundle { - position: tile_pos, - tilemap_id: TilemapId(tilemap_entity), - texture_index, - ..Default::default() - }); - // .id(); - // tile_storage.set(&tile_pos, tile_entity); - } - } - - commands.spawn_batch(batch); - - // for tb in batch { - // tile_storage.set(&tile_pos, tile_entity); - // } - - let texture_handle: Handle = assets.load("img/Tileset Grass.png"); - - let tile_size = TilemapTileSize { x: 16.0, y: 16.0 }; - let grid_size = tile_size.into(); - let map_type = TilemapType::default(); - - let texture = TilemapTexture::Single(texture_handle); - - commands.entity(tilemap_entity).insert(( - Tilemap, - TilemapBundle { - grid_size, - map_type, - size, - storage: tile_storage, - texture, - tile_size, - transform: get_tilemap_center_transform(&size, &grid_size, &map_type, f32::MIN), - ..default() - }, - )); + let texture: Handle = assets.load("img/Tileset Grass.png"); + let mut rng: Pcg64 = Seeder::from("default_seed").make_rng(); + let map_size = UVec2::new(1024, 1024); + let tile_size = UVec2 { x: 16, y: 16 }; + commands + .spawn(( + Tilemap, + Name::new("Tilemap"), + SpatialBundle { + transform: Transform::from_xyz(0., 0., f32::MIN), + ..default() + }, + )) + .with_children(|tilemap| { + let layout = assets.add(TextureAtlasLayout::from_grid( + tile_size, + 16, + 16, + Some(UVec2 { x: 0, y: 0 }), + Some(UVec2 { x: 0, y: 0 }), + )); + let u_center = (map_size * tile_size) / 2; + let center = Vec2::new(u_center.x as f32, u_center.y as f32); + for x in 0..map_size.x { + for y in 0..map_size.y { + let u_pos = UVec2::new(x, y) * tile_size; + let pos = Vec2::new(u_pos.x as f32, u_pos.y as f32) - center; + let index = if rng.gen_range(0..1000) > 925 { + rng.gen_range(0..(16 * 8)) + } else { + 0 + }; + tilemap.spawn(( + HideFromInspector, + SpriteBundle { + texture: texture.clone(), + transform: Transform::from_xyz(pos.x as f32, pos.y as f32, 0.), + ..default() + }, + TextureAtlas { + layout: layout.clone(), + index, + ..default() + }, + )); + } + } + }); } +// pub fn spawn_in_background(mut commands: Commands, assets: Res) { +// let pool = AsyncComputeTaskPool::get(); +// let tilemap_entity = commands.spawn(Name::new("TilemapEntity")).id(); +// let texture_handle: Handle = assets.load("img/Tileset Grass.png"); +// let mut rng: Pcg64 = Seeder::from("default_seed").make_rng(); +// let map_size = UVec2::new(1024, 1024); +// let tile_size = Vec2 { x: 16.0, y: 16.0 }; +// // tiletypes? +// let task = pool.spawn(async move { +// let mut queue = CommandQueue::default(); +// for x in 0..map_size.x { +// for y in 0..map_size.y { +// let pos = Vec2::new(x as f32, y as f32) * tile_size; +// let texture_index = TileTextureIndex(if rng.gen_range(0..1000) > 925 { +// rng.gen_range(0..(16 * 8)) +// } else { +// 0 +// }); +// queue.push(move |world: &mut World| { +// let tile_entity = world +// .spawn(( +// HideFromInspector, +// TileBundle { +// position: tile_pos, +// tilemap_id: TilemapId(tilemap_entity), +// texture_index, +// ..Default::default() +// }, +// )) +// .id(); +// tile_storage_ref.set(&tile_pos, tile_entity); +// }); +// } +// } + +// queue.push(move |world: &mut World| { +// world.spawn(( +// Tilemap, +// Name::new("Tilemap"), +// TilemapBundle { +// grid_size, +// map_type, +// size, +// storage, +// texture, +// tile_size, +// transform: get_tilemap_center_transform(&size, &grid_size, &map_type, f32::MIN), +// ..default() +// }, +// )); +// }); + +// queue +// }); + +// commands.entity(tilemap_entity).insert(MapGen(task)); +// } + +// fn handle_tasks(mut commands: Commands, mut tasks: Query<&mut MapGen>) { +// for mut task in &mut tasks { +// if let Some(mut queue) = block_on(future::poll_once(&mut task.0)) { +// commands.append(&mut queue); +// } +// } +// } + pub fn exit(mut commands: Commands, q: Query>) { for id in q.iter() { commands.entity(id).despawn_recursive(); diff --git a/src/player.rs b/src/player.rs index 3298250..3e76deb 100644 --- a/src/player.rs +++ b/src/player.rs @@ -7,15 +7,6 @@ use bevy::sprite::MaterialMesh2dBundle; const PLAYER_SPEED: f32 = 500.; -// #[derive(Resource, Default)] -// pub struct Layout(Handle); - -// #[derive(Resource)] -// pub struct CrosshairMaterial(Handle); - -// #[derive(Resource)] -// pub struct CrosshairMesh(Mesh2dHandle); - #[derive(Component, Debug)] pub struct Player; @@ -86,23 +77,27 @@ pub fn startup( text.transform.scale.x = 0.25; text.transform.scale.y = 0.25; text.transform.translation.z = 500.0; - text.transform.translation.y = 24.; - player.spawn(text); + text.transform.translation.y = 32.; + player.spawn((Name::new("PlayerName"), text)); player .spawn(( Crosshair, + Name::new("Crosshair"), TransformBundle { local: transform, ..default() }, )) .with_children(|crosshair| { - crosshair.spawn(MaterialMesh2dBundle { - mesh: mesh.into(), - transform: Transform::from_xyz(0., 20., 0.), - material, - ..default() - }); + crosshair.spawn(( + Name::new("CrosshairMesh"), + MaterialMesh2dBundle { + mesh: mesh.into(), + transform: Transform::from_xyz(0., 20., 0.), + material, + ..default() + }, + )); }); }); } diff --git a/src/statue.rs b/src/statue.rs index 828e587..f2a5306 100644 --- a/src/statue.rs +++ b/src/statue.rs @@ -51,7 +51,7 @@ pub fn spawn_statue( }, ..default() }; - commands.spawn(bundle); + commands.spawn((Name::new("Statue"), bundle)); } }