font_atlas_debug/
font_atlas_debug.rs1use bevy::{color::palettes::basic::YELLOW, prelude::*, text::FontAtlasSet};
5
6use chacha20::ChaCha8Rng;
7use rand::{RngExt, SeedableRng};
8
9fn main() {
10 App::new()
11 .init_resource::<State>()
12 .insert_resource(ClearColor(Color::BLACK))
13 .add_plugins(DefaultPlugins)
14 .add_systems(Startup, setup)
15 .add_systems(Update, (text_update_system, atlas_render_system))
16 .run();
17}
18
19#[derive(Resource)]
20struct State {
21 atlas_count: u32,
22 handle: Handle<Font>,
23 timer: Timer,
24}
25
26impl Default for State {
27 fn default() -> Self {
28 Self {
29 atlas_count: 0,
30 handle: Handle::default(),
31 timer: Timer::from_seconds(0.05, TimerMode::Repeating),
32 }
33 }
34}
35
36#[derive(Resource, Deref, DerefMut)]
37struct SeededRng(ChaCha8Rng);
38
39fn atlas_render_system(
40 mut commands: Commands,
41 mut state: ResMut<State>,
42 font_atlas_set: Res<FontAtlasSet>,
43 images: Res<Assets<Image>>,
44) {
45 if let Some(font_atlases) = font_atlas_set.values().next() {
46 let x_offset = state.atlas_count as f32;
47 if state.atlas_count == font_atlases.len() as u32 {
48 return;
49 }
50 let font_atlas = &font_atlases[state.atlas_count as usize];
51 let image = images.get(&font_atlas.texture).unwrap();
52 state.atlas_count += 1;
53 commands.spawn((
54 ImageNode::new(font_atlas.texture.clone()),
55 Node {
56 position_type: PositionType::Absolute,
57 top: Val::ZERO,
58 left: px(image.width() as f32 * x_offset),
59 ..default()
60 },
61 ));
62 }
63}
64
65fn text_update_system(
66 mut state: ResMut<State>,
67 time: Res<Time>,
68 mut query: Query<&mut Text>,
69 mut seeded_rng: ResMut<SeededRng>,
70) {
71 if !state.timer.tick(time.delta()).just_finished() {
72 return;
73 }
74
75 for mut text in &mut query {
76 let c = seeded_rng.random::<u8>() as char;
77 let string = &mut **text;
78 if !string.contains(c) {
79 string.push(c);
80 }
81 }
82}
83
84fn setup(mut commands: Commands, asset_server: Res<AssetServer>, mut state: ResMut<State>) {
85 state.handle = asset_server.load("fonts/FiraSans-Bold.ttf");
86 let font = FontSource::from(state.handle.clone());
87 commands.spawn(Camera2d);
88 commands
89 .spawn((
90 Node {
91 position_type: PositionType::Absolute,
92 bottom: Val::ZERO,
93 ..default()
94 },
95 BackgroundColor(Color::NONE),
96 ))
97 .with_children(|parent| {
98 parent.spawn((
99 Text::new("a"),
100 TextFont {
101 font,
102 font_size: FontSize::Px(50.0),
103 ..default()
104 },
105 TextColor(YELLOW.into()),
106 ));
107 });
108 commands.insert_resource(SeededRng(ChaCha8Rng::seed_from_u64(19878367467713)));
111}