Inspector work to filter tiles, some experiments with rolling my own tiles system

This commit is contained in:
Daniel Flanagan 2024-08-02 16:32:28 -05:00
parent ebce25c379
commit 43d7d3b4e9
9 changed files with 218 additions and 113 deletions

6
Cargo.lock generated
View file

@ -327,15 +327,12 @@ dependencies = [
"bevy_asset", "bevy_asset",
"bevy_color", "bevy_color",
"bevy_core", "bevy_core",
"bevy_core_pipeline",
"bevy_ecs", "bevy_ecs",
"bevy_egui", "bevy_egui",
"bevy_hierarchy", "bevy_hierarchy",
"bevy_log", "bevy_log",
"bevy_math", "bevy_math",
"bevy_pbr",
"bevy_reflect", "bevy_reflect",
"bevy_render",
"bevy_state", "bevy_state",
"bevy_time", "bevy_time",
"bevy_utils", "bevy_utils",
@ -650,7 +647,6 @@ dependencies = [
"bevy_ecs", "bevy_ecs",
"bevy_gizmos_macros", "bevy_gizmos_macros",
"bevy_math", "bevy_math",
"bevy_pbr",
"bevy_reflect", "bevy_reflect",
"bevy_render", "bevy_render",
"bevy_sprite", "bevy_sprite",
@ -2270,7 +2266,9 @@ dependencies = [
"bevy", "bevy",
"bevy-inspector-egui", "bevy-inspector-egui",
"bevy_ecs_tilemap", "bevy_ecs_tilemap",
"bevy_egui",
"bevy_framepace", "bevy_framepace",
"egui",
"rand", "rand",
"rand_pcg", "rand_pcg",
"rand_seeder", "rand_seeder",

View file

@ -15,7 +15,6 @@ bevy = { version = "0.14.0", default-features = false, features = [
"bevy_text", # for writing characters to the screen "bevy_text", # for writing characters to the screen
"bevy_ui", "bevy_ui",
"bevy_winit", "bevy_winit",
"bevy_pbr",
"multi_threaded", # go faster "multi_threaded", # go faster
"png", "png",
"x11", # run on non-wayland linuxes too "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 # "bevy_dev_tools", # possibly-useful development tools
# "detailed_trace", # probably useful troubleshooting information during runtime # "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_ecs_tilemap = "0.14.0"
bevy_egui = "0.28.0"
bevy_framepace = "0.17.1" bevy_framepace = "0.17.1"
egui = "0.28.1"
rand = "0.8.5" rand = "0.8.5"
rand_pcg = "0.3.1" rand_pcg = "0.3.1"
rand_seeder = "0.3.0" rand_seeder = "0.3.0"

View file

@ -1,8 +1,4 @@
use bevy::{ use bevy::{prelude::*, window::PrimaryWindow};
color::palettes::css::{GREEN, RED},
prelude::*,
window::PrimaryWindow,
};
#[derive(Resource, Default, Debug, Clone, PartialEq)] #[derive(Resource, Default, Debug, Clone, PartialEq)]
pub struct Input { pub struct Input {
@ -13,7 +9,7 @@ pub struct Input {
} }
pub fn process_input( pub fn process_input(
mut gizmos: Gizmos, mut _gizmos: Gizmos,
mut input: ResMut<Input>, mut input: ResMut<Input>,
keys: Res<ButtonInput<KeyCode>>, keys: Res<ButtonInput<KeyCode>>,
// mouse: Res<ButtonInput<MouseButton>>, // mouse: Res<ButtonInput<MouseButton>>,
@ -52,7 +48,9 @@ pub fn process_input(
// x increases as thing moves right // x increases as thing moves right
// y increases as thing moves up // 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); // gizmos.line(Vec3::ZERO, Vec3::X * 100., GREEN);
if let Ok(window) = window.get_single() { if let Ok(window) = window.get_single() {
@ -61,6 +59,9 @@ pub fn process_input(
let center = size / 2.; let center = size / 2.;
let modified_target = target.with_y(size.y - target.y) - center; let modified_target = target.with_y(size.y - target.y) - center;
// gizmos.line(Vec2::ZERO.extend(0.), modified_target.extend(0.), RED); // 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(); input.angle = modified_target.to_angle();
} }
} }

46
src/inspector.rs Normal file
View file

@ -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<PrimaryWindow>>()
.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::<Without<HideFromInspector>>(
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);
});
});
});
}

View file

@ -1,6 +1,7 @@
mod camera; mod camera;
mod game; mod game;
mod input; mod input;
mod inspector;
mod main_menu; mod main_menu;
mod map; mod map;
mod movement; mod movement;
@ -63,7 +64,7 @@ fn main() -> AppExit {
.set(ImagePlugin::default_nearest()), .set(ImagePlugin::default_nearest()),
bevy::diagnostic::FrameTimeDiagnosticsPlugin, bevy::diagnostic::FrameTimeDiagnosticsPlugin,
bevy_framepace::FramepacePlugin, bevy_framepace::FramepacePlugin,
// bevy_inspector_egui::quick::WorldInspectorPlugin::new(), inspector::InspectorPlugin,
TilemapPlugin, TilemapPlugin,
)); ));
@ -78,11 +79,6 @@ fn main() -> AppExit {
.init_state::<View>() .init_state::<View>()
.init_state::<Game>(); .init_state::<Game>();
app.insert_resource(AmbientLight {
color: Color::srgb(1., 1., 1.),
brightness: 1.,
});
app.configure_sets( app.configure_sets(
Update, Update,
( (
@ -116,6 +112,7 @@ fn main() -> AppExit {
input::process_input, input::process_input,
(update,).after(input::process_input), (update,).after(input::process_input),
( (
// map::update,
player::control, player::control,
player::meow_on_r, player::meow_on_r,
player::player_debug_info, player::player_debug_info,
@ -151,6 +148,7 @@ fn startup(mut commands: Commands) {
let font_size = 48.; let font_size = 48.;
commands.spawn(( commands.spawn((
FpsText, FpsText,
Name::new("FpsText"),
TextBundle::from_sections([ TextBundle::from_sections([
TextSection::new( TextSection::new(
"FPS: ", "FPS: ",

View file

@ -7,6 +7,7 @@ pub fn startup(mut commands: Commands) {
commands commands
.spawn(( .spawn((
MainMenu, MainMenu,
Name::new("MenuRoot"),
NodeBundle { NodeBundle {
style: Style { style: Style {
width: Val::Percent(100.0), width: Val::Percent(100.0),
@ -20,6 +21,7 @@ pub fn startup(mut commands: Commands) {
.with_children(|parent| { .with_children(|parent| {
// text // text
parent.spawn(( parent.spawn((
Name::new("Text"),
TextBundle::from_section( TextBundle::from_section(
"Text Example\nPress ENTER to play", "Text Example\nPress ENTER to play",
TextStyle { TextStyle {
@ -37,20 +39,23 @@ pub fn startup(mut commands: Commands) {
Label, Label,
)); ));
parent.spawn(NodeBundle { parent.spawn((
style: Style { Name::new("SomeFreakin'Square"),
width: Val::Px(200.0), NodeBundle {
height: Val::Px(200.0), style: Style {
position_type: PositionType::Absolute, width: Val::Px(200.0),
left: Val::Px(210.), height: Val::Px(200.0),
bottom: Val::Px(10.), position_type: PositionType::Absolute,
border: UiRect::all(Val::Px(20.)), 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() ..default()
}, },
border_color: Color::srgb(0., 1., 0.).into(), ));
background_color: Color::srgb(0.4, 0.4, 1.).into(),
..default()
});
}); });
} }

View file

@ -1,5 +1,9 @@
use crate::prelude::*; use crate::{inspector::HideFromInspector, prelude::*};
use bevy_ecs_tilemap::prelude::*; // use bevy::{
// ecs::world::CommandQueue,
// tasks::{AsyncComputeTaskPool, Task},
// };
// use bevy_ecs_tilemap::prelude::*;
use rand::prelude::*; use rand::prelude::*;
use rand_pcg::Pcg64; use rand_pcg::Pcg64;
use rand_seeder::Seeder; use rand_seeder::Seeder;
@ -7,74 +11,131 @@ use rand_seeder::Seeder;
#[derive(Component, Debug)] #[derive(Component, Debug)]
pub struct Tilemap; pub struct Tilemap;
pub fn spawn(mut commands: Commands, assets: Res<AssetServer>) { // #[derive(Component)]
// struct MapGen(Task<CommandQueue>);
/// 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<AssetServer>) {
// let task_pool = AsyncComputeTaskPool::get(); // let task_pool = AsyncComputeTaskPool::get();
// let task = task_pool.spawn(async move {}); // let task = task_pool.spawn(async move {});
let mut rng: Pcg64 = Seeder::from("stripy zebra").make_rng(); let texture: Handle<Image> = assets.load("img/Tileset Grass.png");
let size = TilemapSize { x: 1024, y: 1024 }; let mut rng: Pcg64 = Seeder::from("default_seed").make_rng();
let tilemap_entity = commands.spawn_empty().id(); let map_size = UVec2::new(1024, 1024);
let mut tile_storage = TileStorage::empty(size); let tile_size = UVec2 { x: 16, y: 16 };
let mut batch = Vec::<TileBundle>::with_capacity(size.x as usize * size.y as usize); commands
for x in 0..size.x { .spawn((
for y in 0..size.y { Tilemap,
let tile_pos = TilePos { x, y }; Name::new("Tilemap"),
let texture_index = TileTextureIndex(if rng.gen_range(0..1000) > 925 { SpatialBundle {
rng.gen_range(0..(16 * 8)) transform: Transform::from_xyz(0., 0., f32::MIN),
} else { ..default()
0 },
}); ))
// let texture_index = TileTextureIndex(0); .with_children(|tilemap| {
// let tile_entity = commands let layout = assets.add(TextureAtlasLayout::from_grid(
// .spawn(TileBundle { tile_size,
// position: tile_pos, 16,
// tilemap_id: TilemapId(tilemap_entity), 16,
// texture_index, Some(UVec2 { x: 0, y: 0 }),
// ..Default::default() Some(UVec2 { x: 0, y: 0 }),
// }) ));
// .id(); let u_center = (map_size * tile_size) / 2;
// let tile_entity = commands let center = Vec2::new(u_center.x as f32, u_center.y as f32);
batch.push(TileBundle { for x in 0..map_size.x {
position: tile_pos, for y in 0..map_size.y {
tilemap_id: TilemapId(tilemap_entity), let u_pos = UVec2::new(x, y) * tile_size;
texture_index, let pos = Vec2::new(u_pos.x as f32, u_pos.y as f32) - center;
..Default::default() let index = if rng.gen_range(0..1000) > 925 {
}); rng.gen_range(0..(16 * 8))
// .id(); } else {
// tile_storage.set(&tile_pos, tile_entity); 0
} };
} tilemap.spawn((
HideFromInspector,
commands.spawn_batch(batch); SpriteBundle {
texture: texture.clone(),
// for tb in batch { transform: Transform::from_xyz(pos.x as f32, pos.y as f32, 0.),
// tile_storage.set(&tile_pos, tile_entity); ..default()
// } },
TextureAtlas {
let texture_handle: Handle<Image> = assets.load("img/Tileset Grass.png"); layout: layout.clone(),
index,
let tile_size = TilemapTileSize { x: 16.0, y: 16.0 }; ..default()
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()
},
));
} }
// pub fn spawn_in_background(mut commands: Commands, assets: Res<AssetServer>) {
// let pool = AsyncComputeTaskPool::get();
// let tilemap_entity = commands.spawn(Name::new("TilemapEntity")).id();
// let texture_handle: Handle<Image> = 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<Entity, With<Tilemap>>) { pub fn exit(mut commands: Commands, q: Query<Entity, With<Tilemap>>) {
for id in q.iter() { for id in q.iter() {
commands.entity(id).despawn_recursive(); commands.entity(id).despawn_recursive();

View file

@ -7,15 +7,6 @@ use bevy::sprite::MaterialMesh2dBundle;
const PLAYER_SPEED: f32 = 500.; const PLAYER_SPEED: f32 = 500.;
// #[derive(Resource, Default)]
// pub struct Layout(Handle<TextureAtlasLayout>);
// #[derive(Resource)]
// pub struct CrosshairMaterial(Handle<ColorMaterial>);
// #[derive(Resource)]
// pub struct CrosshairMesh(Mesh2dHandle);
#[derive(Component, Debug)] #[derive(Component, Debug)]
pub struct Player; pub struct Player;
@ -86,23 +77,27 @@ pub fn startup(
text.transform.scale.x = 0.25; text.transform.scale.x = 0.25;
text.transform.scale.y = 0.25; text.transform.scale.y = 0.25;
text.transform.translation.z = 500.0; text.transform.translation.z = 500.0;
text.transform.translation.y = 24.; text.transform.translation.y = 32.;
player.spawn(text); player.spawn((Name::new("PlayerName"), text));
player player
.spawn(( .spawn((
Crosshair, Crosshair,
Name::new("Crosshair"),
TransformBundle { TransformBundle {
local: transform, local: transform,
..default() ..default()
}, },
)) ))
.with_children(|crosshair| { .with_children(|crosshair| {
crosshair.spawn(MaterialMesh2dBundle { crosshair.spawn((
mesh: mesh.into(), Name::new("CrosshairMesh"),
transform: Transform::from_xyz(0., 20., 0.), MaterialMesh2dBundle {
material, mesh: mesh.into(),
..default() transform: Transform::from_xyz(0., 20., 0.),
}); material,
..default()
},
));
}); });
}); });
} }

View file

@ -51,7 +51,7 @@ pub fn spawn_statue(
}, },
..default() ..default()
}; };
commands.spawn(bundle); commands.spawn((Name::new("Statue"), bundle));
} }
} }