font_atlas_debug/
font_atlas_debug.rs1use bevy::{color::palettes::basic::YELLOW, prelude::*, text::FontAtlasSets};
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_sets: Res<FontAtlasSets>,
42 images: Res<Assets<Image>>,
43) {
44 if let Some(set) = font_atlas_sets.get(&state.handle)
45 && let Some((_size, font_atlases)) = set.iter().next()
46 {
47 let x_offset = state.atlas_count as f32;
48 if state.atlas_count == font_atlases.len() as u32 {
49 return;
50 }
51 let font_atlas = &font_atlases[state.atlas_count as usize];
52 let image = images.get(&font_atlas.texture).unwrap();
53 state.atlas_count += 1;
54 commands.spawn((
55 ImageNode::new(font_atlas.texture.clone()),
56 Node {
57 position_type: PositionType::Absolute,
58 top: Val::ZERO,
59 left: px(image.width() as f32 * x_offset),
60 ..default()
61 },
62 ));
63 }
64}
65
66fn text_update_system(
67 mut state: ResMut<State>,
68 time: Res<Time>,
69 mut query: Query<&mut Text>,
70 mut seeded_rng: ResMut<SeededRng>,
71) {
72 if !state.timer.tick(time.delta()).just_finished() {
73 return;
74 }
75
76 for mut text in &mut query {
77 let c = seeded_rng.random::<u8>() as char;
78 let string = &mut **text;
79 if !string.contains(c) {
80 string.push(c);
81 }
82 }
83}
84
85fn setup(mut commands: Commands, asset_server: Res<AssetServer>, mut state: ResMut<State>) {
86 let font_handle = asset_server.load("fonts/FiraSans-Bold.ttf");
87 state.handle = font_handle.clone();
88 commands.spawn(Camera2d);
89 commands
90 .spawn((
91 Node {
92 position_type: PositionType::Absolute,
93 bottom: Val::ZERO,
94 ..default()
95 },
96 BackgroundColor(Color::NONE),
97 ))
98 .with_children(|parent| {
99 parent.spawn((
100 Text::new("a"),
101 TextFont {
102 font: font_handle,
103 font_size: 50.0,
104 ..default()
105 },
106 TextColor(YELLOW.into()),
107 ));
108 });
109 commands.insert_resource(SeededRng(ChaCha8Rng::seed_from_u64(19878367467713)));
112}