use bevy::{
color::palettes::css,
diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin},
prelude::*,
};
use bevy_asset_loader::prelude::*;
use bevy_pancam::*;
use bevy_smud::*;
use rand::prelude::*;
fn main() {
App::new()
.add_plugins((
DefaultPlugins,
LogDiagnosticsPlugin::default(),
FrameTimeDiagnosticsPlugin::default(),
SmudPlugin,
PanCamPlugin,
bevy_lospec::PalettePlugin,
))
.init_state::<GameState>()
.add_loading_state(
LoadingState::new(GameState::Loading)
.continue_to_state(GameState::Running)
.load_collection::<AssetHandles>(),
)
.add_systems(OnEnter(GameState::Running), setup)
.run();
}
#[derive(Clone, Eq, PartialEq, Debug, Hash, States, Default)]
enum GameState {
#[default]
Loading,
Running,
}
#[derive(Resource, AssetCollection)]
struct AssetHandles {
#[asset(path = "vinik24.json")]
palette: Handle<bevy_lospec::Palette>,
}
#[allow(dead_code)]
#[derive(Component)]
struct Index(usize);
fn setup(
mut commands: Commands,
assets: Res<AssetHandles>,
palettes: Res<Assets<bevy_lospec::Palette>>,
asset_server: Res<AssetServer>,
) {
let palette = palettes.get(&assets.palette).unwrap();
let mut rng = rand::rng();
let spacing = 800.0;
let w = 316;
let h = w;
info!("Adding {} shapes", w * h);
let clear_color = palette.lightest();
commands.insert_resource(ClearColor(clear_color));
let bevy_shape_shader = asset_server.load("bevy.wgsl");
for i in 0..w {
for j in 0..h {
let color = palette
.iter()
.filter(|c| *c != &clear_color)
.choose(&mut rng)
.copied()
.unwrap_or(css::PINK.into());
commands.spawn((
Transform::from_translation(Vec3::new(
i as f32 * spacing - w as f32 * spacing / 2.,
j as f32 * spacing - h as f32 * spacing / 2.,
0.,
)),
SmudShape {
color,
sdf: bevy_shape_shader.clone(),
bounds: Rectangle::from_length(590.),
..default()
},
Index(i + j * w),
));
}
}
commands.spawn((Camera2d, PanCam::default(), Msaa::Off));
}