use bevy::math::vec2; use bevy::prelude::*; use bevy::render::render_resource::{Extent3d, TextureDimension, TextureFormat}; use bevy::render::texture::ImageSampler; use cubism::{Canvas, PixelBuffer, TextCanvas}; use rand::{Rng, SeedableRng}; // The buffer is 256x144 with this scale const SCALE: f32 = 7.5; const STREAK_SPEED: f32 = 1.0; const BUTTON_WIDTH: i32 = 160; const BUTTON_HEIGHT: i32 = 80; const BUTTON_OUTLINE_THICKNESS: i32 = 5; const CONTENT_OFFSET: i32 = 24; const STREAK_LENGTH: f32 = 20.0; const TRANSPARENT: Color = Color::rgba(0.0, 0.0, 0.0, 0.0); fn main() { App::new() .add_plugins(DefaultPlugins.set(WindowPlugin { window: WindowDescriptor { width: 1350., height: 750., ..default() }, ..default() })) .add_startup_system(setup) .add_system(render) .run(); } #[derive(Resource)] struct State { streaks: Vec, } impl Default for State { fn default() -> Self { let mut rng = rand::rngs::StdRng::seed_from_u64(1024); const N: usize = 64; let streaks = (0..N) .map(|_| Streak { x: rng.gen_range(0..BUTTON_WIDTH - STREAK_LENGTH as i32), y: rng.gen_range(0..BUTTON_HEIGHT - STREAK_LENGTH as i32), progress: rng.gen_range(0.0..1.0), }) .collect(); Self { streaks } } } #[derive(Clone)] struct Streak { x: i32, y: i32, progress: f32, } #[derive(Resource)] struct MinecraftFont(ab_glyph::FontArc); fn setup(mut commands: Commands, mut images: ResMut>, windows: Res) { commands.spawn(Camera2dBundle::default()); // We could also use assets, but this is simpler let font_data = include_bytes!("../fonts/Minecraft.ttf"); let font = ab_glyph::FontArc::try_from_slice(font_data).unwrap(); commands.insert_resource(MinecraftFont(font)); let window = windows.primary(); let width = window.width() as u32; let height = window.height() as u32; let ui_width = (width as f32 / SCALE) as u32; let ui_height = (height as f32 / SCALE) as u32; let ui_size = Extent3d { width: ui_width, height: ui_height, depth_or_array_layers: 1, }; let data = vec![0; (ui_width * ui_height) as usize * 4]; let mut ui_image = Image::new( ui_size, TextureDimension::D2, data, TextureFormat::Rgba8Unorm, ); ui_image.sampler_descriptor = ImageSampler::nearest(); let ui_image = images.add(ui_image); // This is the image we'll use as canvas. // Note that if you have multiple images, you'll want to mark this entity with some marker component // or save the entity id in some resource. commands.spawn(SpriteBundle { texture: ui_image, transform: Transform::from_xyz(0.0, 0.0, 1.0).with_scale(Vec3::ONE * SCALE), ..default() }); commands.insert_resource(State::default()); } fn render( time: Res