diff --git a/CHANGELOG.md b/CHANGELOG.md index 36edae7..602bd74 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,13 +24,15 @@ run. Return `false` to abort running any later functions during the frame. `fn somename(engine_state: &mut EngineState, game_state: &mut GameState) -> bool`, where `GameState` is the user-defined struct passed to `rusty_engine::init!()`, or `()` if nothing was passed in. - `.play_sfx()` now takes a volume level from `0.0` to `1.0` as a second argument, e.g. `.play_sfx(SfxPreset::Congratulations, 1.0)` +- `TextActor` has been renamed to `Text` to eliminate the confusing "actor" terminology. +`TextActor::text` is now `Text::value` for similar reasons. ### Other Changes - `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 +- Custom fonts may now be set on a `Text` at creation time. +`EngineState::add_text_with_font` was added for a convenience. The font specified should be a `.ttf` or `.otf` file stored in `assets/fonts` - Custom sounds may now be played via `AudioManager::play_music` and `AudioManager::play_sfx` by specifying a path to a sound file relative to `assets/audio`. diff --git a/examples/collision.rs b/examples/collision.rs index a3d50da..b0a1fe2 100644 --- a/examples/collision.rs +++ b/examples/collision.rs @@ -7,7 +7,7 @@ const ROTATION_SPEED: f32 = 3.0; fn main() { let mut game = Game::new(); - let msg2 = game.add_text_actor( + let msg2 = game.add_text( "instructions", "Move the car around with your mouse. Rotate it by holding left/right mouse buttons. Scale it with the mousewheel.", ); @@ -33,8 +33,8 @@ fn main() { } } - let mut text_actor = game.add_text_actor("collision text", ""); - text_actor.translation = Vec2::new(0.0, -200.0); + let mut text = game.add_text("collision text", ""); + text.translation = Vec2::new(0.0, -200.0); game.add_logic(logic); game.run(()); @@ -43,14 +43,14 @@ fn main() { fn logic(engine_state: &mut EngineState, _: &mut ()) -> bool { // If a collision event happened last frame, print it out and play a sound for event in engine_state.collision_events.drain(..) { - let text_actor = engine_state.text_actors.get_mut("collision text").unwrap(); + let text = engine_state.texts.get_mut("collision text").unwrap(); match event.state { CollisionState::Begin => { - text_actor.text = format!("{:?}", event.pair); + text.value = format!("{:?}", event.pair); engine_state.audio_manager.play_sfx(SfxPreset::Switch1, 1.0) } CollisionState::End => { - text_actor.text = "".into(); + text.value = "".into(); engine_state.audio_manager.play_sfx(SfxPreset::Switch2, 1.0) } } diff --git a/examples/keyboard_events.rs b/examples/keyboard_events.rs index f9612ba..ff057e3 100644 --- a/examples/keyboard_events.rs +++ b/examples/keyboard_events.rs @@ -11,7 +11,7 @@ fn main() { race_car.scale = 1.0; let instructions = "Discrete Movement with Keyboard Events\n==============================\nChange translation (move): w a s d / arrows\nChange Rotation: z c\nChange Scale: + -"; - let text = game.add_text_actor("instructions", instructions); + let text = game.add_text("instructions", instructions); text.translation.y = 250.0; game.add_logic(logic); diff --git a/examples/keyboard_state.rs b/examples/keyboard_state.rs index 5b50117..eac5e2f 100644 --- a/examples/keyboard_state.rs +++ b/examples/keyboard_state.rs @@ -13,7 +13,7 @@ fn main() { race_car.scale = 1.0; let instructions = "Smooth movement with KeyboardState Example\n====================================\nChange translation (move): w a s d / arrows\nChange Rotation: z c\nChange Scale: + -"; - let text = game.add_text_actor("instructions", instructions); + let text = game.add_text("instructions", instructions); text.translation.y = 250.0; game.add_logic(logic); diff --git a/examples/mouse_events.rs b/examples/mouse_events.rs index 955a415..6777d73 100644 --- a/examples/mouse_events.rs +++ b/examples/mouse_events.rs @@ -21,11 +21,11 @@ fn main() { anchor.translation = ORIGIN_LOCATION.into(); anchor.layer = 0.0; - let msg = game.add_text_actor("relative message", "Relative Mouse Motion Indicator"); + let msg = game.add_text("relative message", "Relative Mouse Motion Indicator"); msg.translation.y = -300.0; msg.font_size = 20.0; - let msg2 = game.add_text_actor( + let msg2 = game.add_text( "instructions", "Discrete Movement with Mouse Events\n==============================\nMove the car around with your mouse.\nRotate it by clicking left/right mouse buttons.\nScale it with the mousewheel.", ); diff --git a/examples/mouse_state.rs b/examples/mouse_state.rs index 1bd82e5..9ff1ba6 100644 --- a/examples/mouse_state.rs +++ b/examples/mouse_state.rs @@ -22,11 +22,11 @@ fn main() { anchor.translation = ORIGIN_LOCATION.into(); anchor.layer = 0.0; - let msg = game.add_text_actor("relative message", "Relative Mouse Motion Indicator"); + let msg = game.add_text("relative message", "Relative Mouse Motion Indicator"); msg.translation.y = -300.0; msg.font_size = 20.0; - let msg2 = game.add_text_actor( + let msg2 = game.add_text( "instructions", "Smooth Movement with Mouse State\n==============================\nMove the car around with your mouse.\nRotate it by holding left/right mouse buttons.\nScale it with the mousewheel.", ); diff --git a/examples/music.rs b/examples/music.rs index 8e981fc..8165c8d 100644 --- a/examples/music.rs +++ b/examples/music.rs @@ -7,13 +7,13 @@ rusty_engine::init!(); fn main() { let mut game = Game::new(); - let msg = game.add_text_actor( + let msg = game.add_text( "msg", "You can play looping music presets that are included in the asset pack. For example:", ); msg.translation.y = 50.0; - let msg2 = game.add_text_actor_with_font( + let msg2 = game.add_text_with_font( "msg2", "engine_state.audio_manager.play_music(MusicPreset::Classy8Bit, 1.0);", "FiraMono-Medium.ttf", diff --git a/examples/music_sampler.rs b/examples/music_sampler.rs index 7f8d15f..ecabc4c 100644 --- a/examples/music_sampler.rs +++ b/examples/music_sampler.rs @@ -8,7 +8,7 @@ rusty_engine::init!(GameState); fn main() { let mut game = Game::new(); - let msg = game.add_text_actor( + let msg = game.add_text( "msg", "Press any key to advance to the next music selection.\n\nIf you are not running with \"--release\", it may take several seconds for each song to load!", ); @@ -36,8 +36,8 @@ fn logic(engine_state: &mut EngineState, game_state: &mut GameState) -> bool { .nth(game_state.music_index) .unwrap(); engine_state.audio_manager.play_music(music_preset, 1.0); - // And make a text actor saying what song we're playing - let note1 = engine_state.add_text_actor("note1", format!("Looping: {:?}", music_preset)); + // And make text saying what song we're playing + let note1 = engine_state.add_text("note1", format!("Looping: {:?}", music_preset)); note1.font_size = 75.0; } true diff --git a/examples/scenarios/car_shoot.rs b/examples/scenarios/car_shoot.rs index 73e9cd5..9475c49 100644 --- a/examples/scenarios/car_shoot.rs +++ b/examples/scenarios/car_shoot.rs @@ -43,7 +43,7 @@ fn main() { for i in 0..25 { game_state.cars_left.push(i); } - let cars_left = game.add_text_actor("cars left", "Cars left: 25"); + let cars_left = game.add_text("cars left", "Cars left: 25"); cars_left.translation = Vec2::new(540.0, -320.0); game.add_logic(game_logic); @@ -119,8 +119,8 @@ fn game_logic(engine_state: &mut EngineState, game_state: &mut GameState) -> boo game_state.spawn_timer = Timer::from_seconds(thread_rng().gen_range(0.1..1.25), false); // Get the next car if let Some(i) = game_state.cars_left.pop() { - let cars_left = engine_state.text_actors.get_mut("cars left").unwrap(); - cars_left.text = format!("Cars left: {}", i); + let cars_left = engine_state.texts.get_mut("cars left").unwrap(); + cars_left.value = format!("Cars left: {}", i); let label = format!("car{}", i); let car_choices = vec![ RacingCarBlack, diff --git a/examples/scenarios/extreme_drivers_ed.rs b/examples/scenarios/extreme_drivers_ed.rs index 85a14f9..adf36d8 100644 --- a/examples/scenarios/extreme_drivers_ed.rs +++ b/examples/scenarios/extreme_drivers_ed.rs @@ -806,7 +806,7 @@ fn main() { game.audio_manager.play_music(MusicPreset::Classy8Bit, 0.5); // Stuff used to keep and display score - let score_text = game.add_text_actor("score_text", "Score: 0"); + let score_text = game.add_text("score_text", "Score: 0"); score_text.translation = Vec2::new(-10.0, 82.0); score_text.font_size = 24.0; @@ -833,7 +833,7 @@ const TURN_RATE: f32 = 3.0; const ACCELERATION_RATE: f32 = 100.0; fn logic(engine_state: &mut EngineState, game_state: &mut GameState) -> bool { - let score_text = engine_state.text_actors.get_mut("score_text").unwrap(); + let score_text = engine_state.texts.get_mut("score_text").unwrap(); // if game_state.won { // for actor in game_state.actors.values_mut() { @@ -917,7 +917,7 @@ fn logic(engine_state: &mut EngineState, game_state: &mut GameState) -> bool { .audio_manager .play_sfx(SfxPreset::Confirmation1, 1.0); game_state.score += 1; - score_text.text = format!("Score: {}", game_state.score); + score_text.value = format!("Score: {}", game_state.score); if game_state.score >= game_state.win_amount { game_state.won = true; } @@ -926,7 +926,7 @@ fn logic(engine_state: &mut EngineState, game_state: &mut GameState) -> bool { // Crash! game_state.crashed = true; - //game_state.add_text_actor("crashed", "You crashed. You fail. :-("); + //game_state.add_text("crashed", "You crashed. You fail. :-("); engine_state.audio_manager.play_sfx(SfxPreset::Jingle3, 1.0); engine_state.audio_manager.stop_music(); } @@ -935,7 +935,7 @@ fn logic(engine_state: &mut EngineState, game_state: &mut GameState) -> bool { engine_state .audio_manager .play_sfx(SfxPreset::Congratulations, 1.0); - let mut you_win = engine_state.add_text_actor("you win", "You Win!"); + let mut you_win = engine_state.add_text("you win", "You Win!"); you_win.font_size = 120.0; you_win.translation.y = -50.0; } diff --git a/examples/scenarios/road_race.rs b/examples/scenarios/road_race.rs index 4b6d12f..b61b295 100644 --- a/examples/scenarios/road_race.rs +++ b/examples/scenarios/road_race.rs @@ -52,7 +52,7 @@ fn main() { } // Create the health message - let health_message = game.add_text_actor("health_message", "Health: 5"); + let health_message = game.add_text("health_message", "Health: 5"); health_message.translation = Vec2::new(550.0, 320.0); game.add_logic(game_ends); @@ -117,7 +117,7 @@ fn game_logic(engine_state: &mut EngineState, game_state: &mut GameState) -> boo } // Deal with collisions - let health_message = engine_state.text_actors.get_mut("health_message").unwrap(); + let health_message = engine_state.texts.get_mut("health_message").unwrap(); for event in engine_state.collision_events.drain(..) { // We don't care if obstacles collide with each other or collisions end if !event.pair.either_contains("player1") || event.state.is_end() { @@ -125,12 +125,12 @@ fn game_logic(engine_state: &mut EngineState, game_state: &mut GameState) -> boo } if game_state.health_amount > 0 { game_state.health_amount -= 1; - health_message.text = format!("Health: {}", game_state.health_amount); + health_message.value = format!("Health: {}", game_state.health_amount); engine_state.audio_manager.play_sfx(SfxPreset::Impact3, 0.5); } } if game_state.health_amount == 0 { - let game_over = engine_state.add_text_actor("game over", "Game Over"); + let game_over = engine_state.add_text("game over", "Game Over"); game_over.font_size = 128.0; engine_state.audio_manager.stop_music(); engine_state.audio_manager.play_sfx(SfxPreset::Jingle3, 0.5); diff --git a/examples/sfx.rs b/examples/sfx.rs index 16933ce..7352e98 100644 --- a/examples/sfx.rs +++ b/examples/sfx.rs @@ -7,13 +7,13 @@ rusty_engine::init!(); fn main() { let mut game = Game::new(); - let msg = game.add_text_actor( + let msg = game.add_text( "msg", "You can play sound effect presets that are included in the asset pack. For example:", ); msg.translation.y = 50.0; - let msg2 = game.add_text_actor_with_font( + let msg2 = game.add_text_with_font( "msg2", "engine_state.audio_manager.play_sfx(SfxPreset::Jingle1, 1.0);", "FiraMono-Medium.ttf", diff --git a/examples/sfx_sampler.rs b/examples/sfx_sampler.rs index 1c3f5a2..6b7c68a 100644 --- a/examples/sfx_sampler.rs +++ b/examples/sfx_sampler.rs @@ -22,11 +22,11 @@ fn main() { game_state.end_timer = Timer::from_seconds((SfxPreset::variant_iter().len() as f32) * 2.0 + 1.0, false); - let mut msg = game.add_text_actor("msg", "Playing sound effects!"); + let mut msg = game.add_text("msg", "Playing sound effects!"); msg.translation = Vec2::new(0.0, 100.0); msg.font_size = 60.0; - let mut sfx_label = game.add_text_actor("sfx_label", ""); + let mut sfx_label = game.add_text("sfx_label", ""); sfx_label.translation = Vec2::new(0.0, -100.0); sfx_label.font_size = 90.0; @@ -43,8 +43,8 @@ fn logic(engine_state: &mut EngineState, game_state: &mut GameState) -> bool { let sfx = SfxPreset::variant_iter().nth(i).unwrap(); engine_state.audio_manager.play_sfx(sfx, 1.0); // Update the text to show which sound effect we are playing - let sfx_label = engine_state.text_actors.get_mut("sfx_label").unwrap(); - sfx_label.text = format!("{:?}", sfx); + let sfx_label = engine_state.texts.get_mut("sfx_label").unwrap(); + sfx_label.value = format!("{:?}", sfx); } } @@ -54,8 +54,8 @@ fn logic(engine_state: &mut EngineState, game_state: &mut GameState) -> bool { .tick(engine_state.delta) .just_finished() { - let sfx_label = engine_state.text_actors.get_mut("sfx_label").unwrap(); - sfx_label.text = "That's all! Press Esc to quit.".into(); + let sfx_label = engine_state.texts.get_mut("sfx_label").unwrap(); + sfx_label.value = "That's all! Press Esc to quit.".into(); } true } diff --git a/examples/sound.rs b/examples/sound.rs index 0147925..afd385a 100644 --- a/examples/sound.rs +++ b/examples/sound.rs @@ -7,13 +7,13 @@ rusty_engine::init!(); fn main() { let mut game = Game::new(); - let msg = game.add_text_actor( + let msg = game.add_text( "msg", "You can add your own sound files to the assets/audio directory (or its\nsubdirectories) and play them by relative path. For example:", ); msg.translation.y = 100.0; - let msg2 = game.add_text_actor_with_font( + let msg2 = game.add_text_with_font( "msg2", "engine_state.audio_manager.play_sfx(\"sfx/congratulations.ogg\", 1.0);", "FiraMono-Medium.ttf", diff --git a/examples/sprite.rs b/examples/sprite.rs index d8b3af7..1ff0237 100644 --- a/examples/sprite.rs +++ b/examples/sprite.rs @@ -17,9 +17,9 @@ fn main() { let mut actor = game.add_actor(&actor_string, actor_preset); actor.translation = Vec2::new(x as f32, (-y) as f32); - let mut text_actor = game.add_text_actor(&actor_string, &actor_string); - text_actor.translation = Vec2::new(x as f32, (-y - 75) as f32); - text_actor.font_size = 22.0; + let mut text = game.add_text(&actor_string, &actor_string); + text.translation = Vec2::new(x as f32, (-y - 75) as f32); + text.font_size = 22.0; } } diff --git a/examples/text.rs b/examples/text.rs index 7f9ce80..7867f15 100644 --- a/examples/text.rs +++ b/examples/text.rs @@ -8,18 +8,18 @@ rusty_engine::init!(GameState); fn main() { let mut game = Game::new(); - let fps = game.add_text_actor_with_font("fps", "FPS: ", "FiraMono-Medium.ttf"); + let fps = game.add_text_with_font("fps", "FPS: ", "FiraMono-Medium.ttf"); fps.translation = Vec2::new(0.0, 250.0); fps.font_size = 60.0; - let zoom_msg = game.add_text_actor( + let zoom_msg = game.add_text( "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( + let font_msg = game.add_text_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", @@ -27,11 +27,11 @@ fn main() { 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."); + let msg = game.add_text("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 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("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 game_state = GameState { @@ -43,15 +43,15 @@ fn main() { fn game_logic(engine_state: &mut EngineState, game_state: &mut GameState) -> bool { if game_state.timer.tick(engine_state.delta).just_finished() { - let mut fps = engine_state.text_actors.get_mut("fps").unwrap(); - fps.text = format!("FPS: {:.1}", 1.0 / engine_state.delta_f32); + let mut fps = engine_state.texts.get_mut("fps").unwrap(); + fps.value = format!("FPS: {:.1}", 1.0 / engine_state.delta_f32); } - let msg2 = engine_state.text_actors.get_mut("msg2").unwrap(); + let msg2 = engine_state.texts.get_mut("msg2").unwrap(); 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("zoom_msg").unwrap(); + let msg3 = engine_state.texts.get_mut("zoom_msg").unwrap(); msg3.font_size = 10.0 * (engine_state.time_since_startup_f64 * 0.5).cos() as f32 + 25.0; true } diff --git a/examples/transform.rs b/examples/transform.rs index 0c815d8..00a1ea8 100644 --- a/examples/transform.rs +++ b/examples/transform.rs @@ -1,4 +1,3 @@ -// use rusty_engine::prelude::*; rusty_engine::init!(); diff --git a/examples/window.rs b/examples/window.rs index d19730f..8090c69 100644 --- a/examples/window.rs +++ b/examples/window.rs @@ -20,7 +20,7 @@ fn main() { cursor_visible: false, ..Default::default() // for the rest of the options, see https://docs.rs/bevy/0.5.0/bevy/window/struct.WindowDescriptor.html }); - let _ = game.add_text_actor( + let _ = game.add_text( "message", "This is a heavily-customized window.\nYou may resize it a little bit.\nPress Esc to exit.", ); diff --git a/scenarios/road_race.md b/scenarios/road_race.md index d5546dd..73d34be 100644 --- a/scenarios/road_race.md +++ b/scenarios/road_race.md @@ -204,9 +204,9 @@ if actor.label.starts_with("obstacle") { The race car is currently invincible. Before we can fix that, the car needs to have health to lose! 1. In `main()`, insert a `"health_amount"` key into the `u8_map` with the value `5`. This is where we will store the amount of health for the player. -1. Then add a `TextActor` using the `add_text_actor()` method with the label `"health_message"` and the text `"Health: 5"`. - * Set the text actor's `translation` to `Vec2::new(550.0, 320.0)` - * `TextActor`s are very similar to `Actor`s, only instead of a sprite and collisions, `TextActor`s have text to render and a font size to adjust. Both of them have a `label` to retrieve them by and a `translation` for placement. +1. Then add a `Text` using the `add_text()` method with the label `"health_message"` and the text `"Health: 5"`. + * Set the text's `translation` to `Vec2::new(550.0, 320.0)` + * `Text`s are very similar to `Actor`s, only instead of a sprite and collisions, `Text`s have text to render and a font size to adjust. Both of them have a `label` to retrieve them by and a `translation`, `rotation`, and `scale` fields. ```rust // in main() @@ -215,12 +215,12 @@ The race car is currently invincible. Before we can fix that, the car needs to h game.game_state_mut() .u8_map .insert("health_amount".into(), 5); -let health_message = game.add_text_actor("health_message", "Health: 5"); +let health_message = game.add_text("health_message", "Health: 5"); health_message.translation = Vec2::new(550.0, 320.0); ``` Now we can actually lose health! At **_the top_** of the `game_logic()` function we are going to handle the case when we've _already_ lost by effectively pausing the game: -1. Get a mutable reference to the health message text actor we created above. +1. Get a mutable reference to the health message text we created above. * `let health_amount = game_state.u8_map.get_mut("health_amount").unwrap();` 1. If `*health_amount` is zero, then return from the function. * This effectively halts the game, and whatever is on the screen will just sit there. @@ -237,7 +237,7 @@ if *health_amount == 0 { Now we need to actually handle the health. At **_the bottom_** of the `game_logic()` function we'll finally deal with collisions: 1. Get a mutable reference to the health message we created - * `let health_message = game_state.text_actors.get_mut("health_message").unwrap();` + * `let health_message = game_state.texts.get_mut("health_message").unwrap();` 1. Loop through all the `collision_events`. 1. Ignore events (by doing a `continue` in the for loop) that contain "player1" in the collision pair or where the event state is the ending of a collision. * `if !event.pair.either_contains("player1") || event.state.is_end() { continue; }` @@ -249,7 +249,7 @@ Now we need to actually handle the health. At **_the bottom_** of the `game_log ```rust // Deal with collisions -let health_message = game_state.text_actors.get_mut("health_message").unwrap(); +let health_message = game_state.texts.get_mut("health_message").unwrap(); for event in game_state.collision_events.drain(..) { // We don't care if obstacles collide with each other or collisions end if !event.pair.either_contains("player1") || event.state.is_end() { @@ -276,15 +276,15 @@ if player1.translation.y < -360.0 || player1.translation.y > 360.0 { Finally, at the very end of the `game_logic()` function we can do a bit of cleanup if we just lost. 1. If `*health_amount` is `0` - 1. Create a text actor, and set its text to `"Game Over"` - 1. Using the mutable reference from creating the text actor, set its `font_size` to `128.0` (if this crashes on your system, reduce the font size to a smaller number) + 1. Create a text, and set its text to `"Game Over"` + 1. Using the mutable reference from creating the text, set its `font_size` to `128.0` (if this crashes on your system, reduce the font size to a smaller number) 1. Use the `audio_manager` to stop the music. 1. Use the `audio_manager` to play `SfxPreset::Jingle3` at full volume (it's a sad sound) 1. Try it! ```rust if *health_amount == 0 { - let game_over = game_state.add_text_actor("game over", "Game Over"); + let game_over = game_state.add_text("game over", "Game Over"); game_over.font_size = 128.0; game_state.audio_manager.stop_music(); game_state.audio_manager.play_sfx(SfxPreset::Jingle3, 1.0); diff --git a/src/game.rs b/src/game.rs index 06e6788..328dd85 100644 --- a/src/game.rs +++ b/src/game.rs @@ -3,12 +3,16 @@ use crate::{ audio::AudioManager, mouse::{CursorMoved, MouseButtonInput, MouseMotion, MouseWheel}, prelude::{CollisionEvent, KeyboardInput, KeyboardState, MouseState}, - text_actor::TextActor, + text::Text, }; -use bevy::{prelude::*, utils::HashMap}; -use std::time::Duration; - +use bevy::prelude::{ + info, AssetServer, Assets, Color, ColorMaterial, Commands, HorizontalAlign, Res, ResMut, + SpriteBundle, Text as BevyText, Text2dBundle, TextAlignment, TextStyle, Vec2, VerticalAlign, + Windows, +}; +use bevy::utils::HashMap; pub use bevy::window::{WindowDescriptor, WindowMode, WindowResizeConstraints}; +use std::time::Duration; /// EngineState is the primary way that you will interact with Rusty Engine. Every frame this struct /// is provided to the "logic" function (or closure) that you provided to [`Game::run`]. The @@ -29,13 +33,13 @@ pub use bevy::window::{WindowDescriptor, WindowMode, WindowResizeConstraints}; #[derive(Default, Debug)] 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. + /// [`add_actor`](EngineState::add_actor) method. Modify & remove actors as you like. pub actors: HashMap, - /// 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, + /// SYNCED - The state of all texts this frame. For convenience adding a text, use the + /// [`add_text`](EngineState::add_text) or + /// [`add_text_with_font`](EngineState::add_text_with_font) methods. Modify & remove + /// text as you like. + pub texts: HashMap, /// 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 /// are generated when two actors' colliders begin or end overlapping in 2D space. @@ -62,11 +66,11 @@ pub struct EngineState { /// finally released, a single released event is emitted. pub keyboard_state: KeyboardState, /// INFO - The delta time (time between frames) for the current frame as a [`Duration`], perfect - /// for use with [`Timer`]s + /// for use with [`Timer`](crate::prelude::Timer)s pub keyboard_events: Vec, /// INFO - The current state of all the keys on the keyboard. Use this to control movement in /// your games! A [`KeyboardState`] has helper methods you should use to query the state of - /// specific [`KeyCode`]s. + /// specific [`KeyCode`](crate::prelude::KeyCode)s. pub delta: Duration, /// INFO - The delta time (time between frames) for the current frame as an [`f32`], perfect for /// use in math with other `f32`'s. A cheap and quick way to approximate smooth movement @@ -106,37 +110,32 @@ impl EngineState { } #[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. - pub fn add_text_actor(&mut self, label: T, text: S) -> &mut TextActor + /// Add a [`Text`]. Use the `&mut Text` that is returned to set the translation, rotation, etc. + /// Use a unique label for each text. Attempting to add two texts with the same label will + /// crash. + pub fn add_text(&mut self, label: T, text: S) -> &mut Text where T: Into, S: Into, { let label = label.into(); let text = text.into(); - let text_actor = TextActor { + let curr_text = Text { label: label.clone(), - text, + value: text, ..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() + self.texts.insert(label.clone(), curr_text); + // Unwrap: Can't crash because we just inserted the text + self.texts.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 + /// Add a [`Text`] with a specific font. Use the `&mut Text` that is returned to set the + /// translation, rotation, etc. Use a unique label for each text. Attempting to add two texts + /// with the same label will crash. The `font` parameter 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( - &mut self, - label: L, - text: T, - font: F, - ) -> &mut TextActor + pub fn add_text_with_font(&mut self, label: L, text: T, font: F) -> &mut Text where L: Into, T: Into, @@ -145,15 +144,15 @@ impl EngineState { let label = label.into(); let text = text.into(); let font = font.into(); - let text_actor = TextActor { + let curr_text = Text { label: label.clone(), - text, + value: text, font, ..Default::default() }; - self.text_actors.insert(label.clone(), text_actor); + self.texts.insert(label.clone(), curr_text); // Unwrap: Can't crash because we just inserted the actor - self.text_actors.get_mut(&label).unwrap() + self.texts.get_mut(&label).unwrap() } } @@ -171,7 +170,7 @@ pub fn setup( engine_state.screen_dimensions = Vec2::new(window.width(), window.height()); info!("Window dimensions: {}", engine_state.screen_dimensions); add_actors(&mut commands, &asset_server, materials, &mut engine_state); - add_text_actors(&mut commands, &asset_server, &mut engine_state); + add_texts(&mut commands, &asset_server, &mut engine_state); } // helper function: Add Bevy components for all the actors in engine_state.actors @@ -193,37 +192,35 @@ pub fn add_actors( } } -// helper function: Add Bevy components for all the actors in engine_state.text_actors +/// Bevy system which adds any needed Bevy components to correspond to the texts in +/// `engine_state.texts` #[doc(hidden)] -pub fn add_text_actors( +pub fn add_texts( commands: &mut Commands, asset_server: &Res, engine_state: &mut EngineState, ) { - for (_, text_actor) in engine_state.text_actors.drain() { - 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(font_path.as_str()), - font_size, - color: Color::WHITE, - }, - TextAlignment { - vertical: VerticalAlign::Center, - horizontal: HorizontalAlign::Center, - }, - ), - transform, - ..Default::default() - }); + for (_, text) in engine_state.texts.drain() { + let transform = text.bevy_transform(); + let font_size = text.font_size; + let text_string = text.value.clone(); + let font_path = format!("fonts/{}", text.font); + commands.spawn().insert(text).insert_bundle(Text2dBundle { + text: BevyText::with_section( + text_string, + TextStyle { + font: asset_server.load(font_path.as_str()), + font_size, + color: Color::WHITE, + }, + TextAlignment { + vertical: VerticalAlign::Center, + horizontal: HorizontalAlign::Center, + }, + ), + transform, + ..Default::default() + }); } } @@ -300,9 +297,31 @@ use rusty_engine::{ AudioManagerPlugin, CollisionEvent, KeyboardInput, KeyboardPlugin, KeyboardState, MouseState, PhysicsPlugin, }, - text_actor::TextActor, + text::Text, }; -use bevy::{app::AppExit, input::system::exit_on_esc_system, prelude::*, utils::HashMap}; +use bevy::{app::AppExit, input::system::exit_on_esc_system, + prelude::{ + Text as BevyText, + Query, + Commands, + DefaultPlugins, + AssetServer, + ColorMaterial, + Color, + OrthographicCameraBundle, + Assets, + Res, + ResMut, + AppBuilder, + EventReader, + EventWriter, + QuerySet, + Entity, + Transform, + App, + IntoSystem, + ParallelSystemDescriptorCoercion + }, utils::HashMap}; use bevy_kira_audio::*; use std::{sync::Mutex, time::Duration, ops::{Deref, DerefMut}}; @@ -405,13 +424,11 @@ fn game_logic_sync( time: Res