Skip to content

Commit

Permalink
you can choose a font for your text actor, now (#19)
Browse files Browse the repository at this point in the history
  • Loading branch information
CleanCut authored Dec 22, 2021
1 parent dee6236 commit 477fc16
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 18 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ is the user-defined struct passed to `rusty_engine::init!()`, or `()` if nothing

- `AudioManager::music_playing()` will return whether or not music is currently playing (accessible
through `EngineState:audio_manager`)
- Custom fonts may now be set on a `TextActor` at creation time.
`EngineState::add_text_actor_with_font` was added for a convenience. The font specified should be
a `.ttf` or `.otf` file stored in `assets/fonts`

- (meta) Improved CI times by using sccache together with GitHub Actions caching

Expand Down
37 changes: 23 additions & 14 deletions examples/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,32 @@ rusty_engine::init!(GameState);

fn main() {
let mut game = Game::new();
let fps = game.add_text_actor("fps", "FPS: ");
let fps = game.add_text_actor_with_font("fps", "FPS: ", "FiraMono-Medium.ttf");
fps.translation = Vec2::new(0.0, 250.0);
fps.font_size = 60.0;

let mut msg = game.add_text_actor("msg", "Changing text and font size after creation is supported, but requires\nre-rendering the text image each time, so use it sparingly!\n\nChanging the text's translation, rotation*, and scale* is fast,\n so feel free to do that a lot.");
let zoom_msg = game.add_text_actor(
"zoom_msg",
"Changing font size re-renders the text smoothly at a different size,\nbut using this technique for animation is both jittery (character kerning) and expensive.",
);
zoom_msg.font_size = 35.0;
zoom_msg.translation = Vec2::new(0.0, 150.0);

let font_msg = game.add_text_actor_with_font(
"font_msg",
"You can choose a font at creation time by providing the filename of a font stored in assets/fonts.\n\"FiraSans-Bold.ttf\" is the default. \"FiraMono-Medium.ttf\" is also included in the asset pack.",
"FiraMono-Medium.ttf",
);
font_msg.font_size = 20.0;
font_msg.translation.y = 0.0;

let msg = game.add_text_actor("msg", "Changing the text's translation, rotation*, and scale* is fast,\n so feel free to do that a lot.");
msg.font_size = 24.0;
msg.translation.y = -150.0;

let mut msg2 = game.add_text_actor("msg2", "*Changing rotation and scale will not work until Bevy 0.6 is released,\nbut changing the translation works great already!");
let msg2 = game.add_text_actor("msg2", "*Changing rotation and scale will not work until Bevy 0.6 is released,\nbut changing the translation works great already!");
msg2.font_size = 20.0;

let mut msg3 = game.add_text_actor(
"msg3",
"Changing font size re-renders the text smoothly at a different size,\nbut using this technique for animation is both jittery (character kerning) and expensive.",
);
msg3.font_size = 35.0;
msg3.translation = Vec2::new(0.0, 150.0);

let game_state = GameState {
timer: Timer::from_seconds(0.2, true),
};
Expand All @@ -39,10 +48,10 @@ fn game_logic(engine_state: &mut EngineState, game_state: &mut GameState) -> boo
}

let msg2 = engine_state.text_actors.get_mut("msg2").unwrap();
msg2.translation.x = 75.0 * (engine_state.time_since_startup_f64 * 0.5).sin() as f32;
msg2.translation.y = 75.0 * (engine_state.time_since_startup_f64 * 0.5).cos() as f32 - 200.0;
msg2.translation.x = 50.0 * (engine_state.time_since_startup_f64 * 0.5).sin() as f32;
msg2.translation.y = 50.0 * (engine_state.time_since_startup_f64 * 0.5).cos() as f32 - 275.0;

let msg3 = engine_state.text_actors.get_mut("msg3").unwrap();
msg3.font_size = 10.0 * (engine_state.time_since_startup_f64 * 0.5).cos() as f32 + 20.0;
let msg3 = engine_state.text_actors.get_mut("zoom_msg").unwrap();
msg3.font_size = 10.0 * (engine_state.time_since_startup_f64 * 0.5).cos() as f32 + 25.0;
true
}
39 changes: 36 additions & 3 deletions src/game.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@ pub struct EngineState {
/// SYNCED - The state of all actors this frame. To add an actor, use the
/// [`add_actor`](EngineState::add_actor) method. Modify & remove text actors as you like.
pub actors: HashMap<String, Actor>,
/// SYNCED - The state of all text actors this frame. To add a text actor, use the
/// [`add_text_actor`](EngineState::add_text_actor) method. Modify & remove text actors as you like.
/// SYNCED - The state of all text actors this frame. For convenience adding text actor, use the
/// [`add_text_actor`](EngineState::add_text_actor) or
/// [`add_text_actor_with_font`](EngineState::add_text_actor_with_font) methods. Modify & remove
/// text actors as you like.
pub text_actors: HashMap<String, TextActor>,
/// INFO - All the collision events that occurred this frame. For collisions to be generated
/// between actors, both actors must have [`Actor.collision`] set to `true`. Collision events
Expand Down Expand Up @@ -123,6 +125,36 @@ impl EngineState {
// Unwrap: Can't crash because we just inserted the actor
self.text_actors.get_mut(&label).unwrap()
}

#[must_use]
/// Add a [`TextActor`]. Use the `&mut TextActor` that is returned to set the translation,
/// rotation, etc. Use a unique label for each text actor. Attempting to add two text actors
/// with the same label will crash. The `font` paramater should be the filename of a font
/// located in the assets/fonts directory. The default font is "FiraSans-Bold.ttf".
pub fn add_text_actor_with_font<L, T, F>(
&mut self,
label: L,
text: T,
font: F,
) -> &mut TextActor
where
L: Into<String>,
T: Into<String>,
F: Into<String>,
{
let label = label.into();
let text = text.into();
let font = font.into();
let text_actor = TextActor {
label: label.clone(),
text,
font,
..Default::default()
};
self.text_actors.insert(label.clone(), text_actor);
// Unwrap: Can't crash because we just inserted the actor
self.text_actors.get_mut(&label).unwrap()
}
}

// startup system - grab window settings, initialize all the starting actors
Expand Down Expand Up @@ -172,14 +204,15 @@ pub fn add_text_actors(
let transform = text_actor.bevy_transform();
let font_size = text_actor.font_size;
let text = text_actor.text.clone();
let font_path = format!("fonts/{}", text_actor.font);
commands
.spawn()
.insert(text_actor)
.insert_bundle(Text2dBundle {
text: Text::with_section(
text,
TextStyle {
font: asset_server.load("fonts/FiraSans-Bold.ttf"),
font: asset_server.load(font_path.as_str()),
font_size,
color: Color::WHITE,
},
Expand Down
8 changes: 7 additions & 1 deletion src/text_actor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,13 @@ pub struct TextActor {
pub label: String,
/// SYNCED: The actual text you want to display.
pub text: String,
/// CREATION: The font to use when creating this text actor. Should be a file name of an .otf or
/// .ttf font located within the assets/fonts folder. Defaults to "FiraSans-Bold.ttf" (included
/// in the default asset pack).
pub font: String,
/// SYNCED: The font size of the text you want to display. WARNING: As font sizes get larger,
/// the sprites we generate for them get slower to create. Very large sizes will crash.
/// the sprites we generate for them get slower to create. Very large sizes will crash. The
/// default font size is `30.0`.
pub font_size: f32,
/// SYNCED: Where you are in 2D game space. Positive x is right. Positive y is up. (0.0, 0.0) is the
/// center of the screen.
Expand All @@ -36,6 +41,7 @@ impl Default for TextActor {
Self {
label: String::default(),
text: String::default(),
font: "FiraSans-Bold.ttf".to_string(),
font_size: TEXT_ACTOR_DEFAULT_FONT_SIZE,
translation: Vec2::default(),
layer: TEXT_ACTOR_DEFAULT_LAYER,
Expand Down

0 comments on commit 477fc16

Please sign in to comment.