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