use std::collections::BTreeMap;
use bevy::prelude::*;
use bevy_flowfield_tiles_plugin::prelude::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, (setup,))
.run();
}
fn setup(mut cmds: Commands) {
let path = env!("CARGO_MANIFEST_DIR").to_string() + "/assets/sector_costfields.ron";
let flowfield_tiles = FlowFieldTiles::from_ron((0.0, 0.0), (30.0, 30.0), 1.0, 0.5, &path);
let costfields = flowfield_tiles.get_sector_cost_fields();
let read_costfields = costfields.read().unwrap();
let portals = flowfield_tiles.get_portals();
let read_portals = portals.read().unwrap();
let source_sector = SectorID::new(2, 0);
let source_cell = FieldCell::new(7, 3);
let goal_sector = SectorID::new(0, 2);
let goal_cell = FieldCell::new(0, 7);
let mut intfields: BTreeMap<SectorID, IntegrationField> = BTreeMap::new();
if let Some(route) = read_portals.find_path(
&source_sector,
&source_cell,
&goal_sector,
&goal_cell,
&read_costfields,
) {
for step in route.iter() {
let sector = step.get_sector();
let costfield = &read_costfields.get_scaled_costs().get(sector).unwrap();
let mut intfield = IntegrationField::init(costfield, step);
intfield.build(costfield);
intfields.insert(*sector, intfield);
}
} else {
panic!("Failed to find route");
}
drop(read_portals);
cmds.spawn(Camera2d);
cmds.spawn((
Node {
width: Val::Percent(100.0),
height: Val::Percent(100.0),
display: Display::Grid,
grid_auto_flow: GridAutoFlow::Column,
grid_template_columns: vec![
GridTrack::px(300.0),
GridTrack::px(300.0),
GridTrack::px(300.0),
],
grid_template_rows: vec![
GridTrack::px(300.0),
GridTrack::px(300.0),
GridTrack::px(300.0),
],
..Default::default()
},
BackgroundColor(Color::NONE),
))
.with_children(|p| {
let sectors = read_costfields.get_scaled_costs().keys();
for sector in sectors {
p.spawn((
Node {
width: Val::Px(300.0),
height: Val::Px(300.0),
flex_direction: FlexDirection::Row,
flex_wrap: FlexWrap::Wrap,
..Default::default()
},
BackgroundColor(Color::WHITE),
))
.with_children(|p| {
if let Some(intfield) = intfields.get(sector) {
for value in intfield.get() {
p.spawn((
Node {
width: Val::Percent(10.0),
height: Val::Percent(10.0),
justify_content: JustifyContent::Center,
align_items: AlignItems::Center,
..Default::default()
},
BackgroundColor(get_colour(*value)),
))
.with_children(|p| {
p.spawn((
Text::new((value & INT_FILTER_BITS_COST).to_string()),
TextFont {
font: FontSource::Monospace,
font_size: FontSize::Px(10.0),
..default()
},
TextColor(Color::BLACK),
));
});
}
} else {
for _ in 0..(FIELD_RESOLUTION * FIELD_RESOLUTION) {
p.spawn(Node {
width: Val::Percent(10.0),
height: Val::Percent(10.0),
justify_content: JustifyContent::Center,
align_items: AlignItems::Center,
..Default::default()
});
}
}
});
}
});
drop(read_costfields);
}
fn get_colour(value: u32) -> Color {
if value & INT_BITS_LOS == INT_BITS_LOS {
return Color::WHITE;
}
let cost = value & INT_FILTER_BITS_COST;
match cost {
0 => Color::WHITE,
1 => Color::srgb(1.0, 0.95, 0.68),
65535 => Color::srgb(0.5, 0.5, 0.5),
_ => Color::srgb(
1.0,
0.95 * 0.9_f32.powf(cost as f32),
0.68 * 0.9_f32.powf(cost as f32),
),
}
}