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_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",

View file

@ -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"

View file

@ -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<Input>,
keys: Res<ButtonInput<KeyCode>>,
// mouse: Res<ButtonInput<MouseButton>>,
@ -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();
}
}

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 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::<View>()
.init_state::<Game>();
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: ",

View file

@ -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,7 +39,9 @@ pub fn startup(mut commands: Commands) {
Label,
));
parent.spawn(NodeBundle {
parent.spawn((
Name::new("SomeFreakin'Square"),
NodeBundle {
style: Style {
width: Val::Px(200.0),
height: Val::Px(200.0),
@ -50,7 +54,8 @@ pub fn startup(mut commands: Commands) {
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 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<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 = 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::<TileBundle>::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 {
let texture: 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 = 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
});
// 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<Image> = 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),
};
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<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>>) {
for id in q.iter() {
commands.entity(id).despawn_recursive();

View file

@ -7,15 +7,6 @@ use bevy::sprite::MaterialMesh2dBundle;
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)]
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 {
crosshair.spawn((
Name::new("CrosshairMesh"),
MaterialMesh2dBundle {
mesh: mesh.into(),
transform: Transform::from_xyz(0., 20., 0.),
material,
..default()
});
},
));
});
});
}

View file

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