Skip to content

Commit

Permalink
Add scrolling of game logs feature
Browse files Browse the repository at this point in the history
  • Loading branch information
donedgardo committed Jan 29, 2023
1 parent 9288c96 commit 3f1d707
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 62 deletions.
Binary file added assets/fonts/kongtext/kongtext.ttf
Binary file not shown.
17 changes: 17 additions & 0 deletions assets/fonts/kongtext/license.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Thanks for downloading one of codeman38's retro video game fonts, as seen on Memepool, BoingBoing, and all around the blogosphere.

So, you're wondering what the license is for these fonts? Pretty simple; it's based upon that used for Bitstream's Vera font set <http://www.gnome.org/fonts/>.

Basically, here are the key points summarized, in as little legalese as possible; I hate reading license agreements as much as you probably do:

With one specific exception, you have full permission to bundle these fonts in your own free or commercial projects-- and by projects, I'm referring to not just software but also electronic documents and print publications.

So what's the exception? Simple: you can't re-sell these fonts in a commercial font collection. I've seen too many font CDs for sale in stores that are just a repackaging of thousands of freeware fonts found on the internet, and in my mind, that's quite a bit like highway robbery. Note that this *only* applies to products that are font collections in and of themselves; you may freely bundle these fonts with an operating system, application program, or the like.

Feel free to modify these fonts and even to release the modified versions, as long as you change the original font names (to ensure consistency among people with the font installed) and as long as you give credit somewhere in the font file to codeman38 or zone38.net. I may even incorporate these changes into a later version of my fonts if you wish to send me the modifed fonts via e-mail.

Also, feel free to mirror these fonts on your own site, as long as you make it reasonably clear that these fonts are not your own work. I'm not asking for much; linking to zone38.net or even just mentioning the nickname codeman38 should be enough.

Well, that pretty much sums it up... so without further ado, install and enjoy these fonts from the golden age of video games.

[ codeman38 | [email protected] | http://www.zone38.net/ ]
21 changes: 1 addition & 20 deletions src/cursor_indicator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,11 @@ fn get_rotation_from_to(from: Vec2, to: Vec2) -> Quat {

#[cfg(test)]
mod indicator_cursor_test {
use bevy::math::DVec2;
use super::*;
use bevy::prelude::*;
use crate::camera::CameraPlugin;
use crate::player::{Player};
use crate::test_utils::{LoadTestPlugins, update};
use crate::test_utils::{create_test_windows, LoadTestPlugins, update};

#[test]
fn it_spawns_indicator_as_child_of_player() {
Expand Down Expand Up @@ -121,22 +120,4 @@ mod indicator_cursor_test {
app
}

fn create_test_windows() -> Windows {
let mut windows = Windows::default();
let mut test_window = Window::new(
Default::default(),
&Default::default(),
100,
100,
1.0,
None,
None,
);
test_window.update_cursor_physical_position_from_backend(
// position from bottom left of windows
Option::from(DVec2::new(0., 50.))
);
windows.add(test_window);
windows
}
}
116 changes: 75 additions & 41 deletions src/game_logs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,30 @@ impl Plugin for UIPlugin {
app
.add_event::<GameLogEvent>()
.add_startup_system(setup_ui)
.add_system(debug_event)
.add_system(game_log_events)
.add_system(mouse_scroll);
}
}

fn setup_ui(mut commands: Commands, asset_server: Res<AssetServer>) {
fn debug_event(
mut ev: EventWriter<GameLogEvent>,
keyboard_input: Res<Input<KeyCode>>,
) {
if keyboard_input.just_pressed(KeyCode::Space) {
let test_log = "Testing long text for helping me. Long Long long long long long long long long!";
ev.send(GameLogEvent(test_log.to_string()));
}
}

fn setup_ui(mut commands: Commands) {
commands.spawn(NodeBundle {
style: Style {
flex_direction: FlexDirection::Column,
align_self: AlignSelf::FlexEnd,
size: Size::new(
Val::Percent(100.),
Val::Percent(20.),
Val::Percent(35.),
Val::Percent(10.),
),
overflow: Overflow::Hidden,
..default()
Expand All @@ -39,50 +51,63 @@ fn setup_ui(mut commands: Commands, asset_server: Res<AssetServer>) {
..default()
},
ScrollingList::default(),
))
.with_children(|parent| {
));
});
}


fn game_log_events(
mut commands: Commands,
mut log_event_reader: EventReader<GameLogEvent>,
asset_server: Res<AssetServer>,
list_query: Query<(Entity, &Node), With<ScrollingList>>,
) {
for event in log_event_reader.iter() {
let log = event.0.clone() + "\n";
for (list, node) in list_query.iter() {
commands.entity(list).with_children(|parent| {
parent.spawn((
TextBundle::from_section(
"",
log.to_string(),
TextStyle {
font: asset_server.load("fonts/kongtext/kongtext.ttf"),
font_size: 12.0,
color: Color::WHITE,
},
),
).with_style(Style {
flex_shrink: 0.,
size: Size::new(
Val::Px(node.size().x),
Val::Undefined,
),
..default()
}),
GameLogs
));
});
});
}

fn game_log_events(
mut log_event_reader: EventReader<GameLogEvent>,
mut text_query: Query<&mut Text, With<GameLogs>>,
) {
for event in log_event_reader.iter() {
let log = event.0.clone() + "\n";
for mut text in text_query.iter_mut() {
text.sections[0].value += &*log;
}
}
}

fn mouse_scroll(
mut mouse_wheel_events: EventReader<MouseWheel>,
mut query_list: Query<(&mut ScrollingList, &mut Style, &Node)>,
mut query_list: Query<(&mut ScrollingList, &mut Style, &Children, &Node)>,
query_item: Query<&Node>,
) {
for mouse_wheel_event in mouse_wheel_events.iter() {
for (mut scrolling_list, mut style, uinode) in &mut query_list {
for (mut scrolling_list, mut style, children, uinode) in &mut query_list {
let items_height: f32 = children
.iter()
.map(|entity| query_item.get(*entity).unwrap().size().y)
.sum();
let panel_height = uinode.size().y;
let max_scroll = panel_height.max(0.);
let max_scroll = (items_height - panel_height).max(0.);
let dy = match mouse_wheel_event.unit {
MouseScrollUnit::Line => mouse_wheel_event.y * 20.,
MouseScrollUnit::Pixel => mouse_wheel_event.y,
};
scrolling_list.position += dy;
scrolling_list.position = scrolling_list.position.clamp(-max_scroll, 0.);
println!("{}", scrolling_list.position);
style.position.top = Val::Px(scrolling_list.position);
}
}
Expand All @@ -102,38 +127,47 @@ pub struct GameLogEvent(String);
#[cfg(test)]
mod log_test {
use bevy::input::InputPlugin;
use bevy::text::TextPlugin;
use bevy::ui::UiPlugin;
use super::*;
use crate::test_utils;
use crate::test_utils::update;

#[test]
fn it_shows_log_text() {
let mut app = App::new();
app.add_plugins(test_utils::LoadTestPlugins);
app.add_plugin(InputPlugin);
app.add_plugin(UIPlugin);

fn it_updates_log_text() {
let mut app = setup();
app.world.send_event(GameLogEvent("Hello World!".to_string()));
app.update();
let log_text = app.world
.query_filtered::<&Text, With<GameLogs>>().single(&app.world);
assert_eq!(log_text.sections[0].value, String::new());
assert_eq!(log_text.sections[0].value, "Hello World!\n".to_string());
}

#[test]
fn it_updates_log_text() {
fn it_scrolls_on_mouse_scroll() {
let mut app = setup();
app.world.send_event(GameLogEvent("Hello World!Long LOng Long \n Long \n Long \n LOng\n very long! \n Very Long \n Very LOng \n Very Long".to_string()));
update(&mut app, 2);
app.world.send_event(MouseWheel {
unit: MouseScrollUnit::Line,
x: 0.0,
y: -1.,
});
update(&mut app, 1);
let scroll_list_style = app.world
.query_filtered::<&Style, With<ScrollingList>>().single(&app.world);
assert_eq!(scroll_list_style.position.top, Val::Px(-20.));
}

fn setup() -> App {
let windows = test_utils::create_test_windows();
let mut app = App::new();
app.add_plugins(test_utils::LoadTestPlugins);
app.add_plugin(TextPlugin::default());
app.add_plugin(UiPlugin::default());
app.add_plugin(InputPlugin);
app.add_plugin(UIPlugin);

app.world.send_event(GameLogEvent("Hello World!".to_string()));
app.update();
let log_text = app.world
.query_filtered::<&Text, With<GameLogs>>().single(&app.world);
assert_eq!(log_text.sections[0].value, "Hello World!\n".to_string());
}

#[test]
fn it_scroll_to_the_bottom_as_new_text_comes_in() {
let testLog = "Testing long text for helping me.\nTesting long text for helping me. longer than expected.\nTesting long text for helping me.\nTesting long text for helping me.\nTesting long text for helping me.\nTesting long text for helping me.\nTesting long text for helping me.\nTesting long text for helping me.\n20!\nTesting long text for helping me.\nTesting long text for helping me.\nTesting long text for helping me.\nTesting long text for helping me.\nTesting long text for helping me.\nTesting long text for helping me.\nTesting long text for helping me.\nTesting long text for helping me.\nTesting long text for helping me.\nTesting long text for helping me.\nTesting long text for helping me.\nTesting long text for helping me.\nTesting long text for helping me.\nTesting long text for helping me.\nTesting long text for helping me.\n";
app.insert_resource(windows);
app
}
}
24 changes: 23 additions & 1 deletion src/test_utils.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use bevy::app::{PluginGroup, PluginGroupBuilder, ScheduleRunnerPlugin};
use bevy::core::CorePlugin;
use bevy::time::TimePlugin;
use bevy::prelude::{App, ImagePlugin, WindowPlugin};
use bevy::prelude::{App, HierarchyPlugin, ImagePlugin, TransformPlugin, Window, WindowPlugin, Windows};
use bevy::asset::AssetPlugin;
use bevy::render::RenderPlugin;
use bevy::core_pipeline::CorePipelinePlugin;
use bevy::sprite::SpritePlugin;
use bevy::math::DVec2;

pub struct LoadTestPlugins;

Expand All @@ -14,6 +15,8 @@ impl PluginGroup for LoadTestPlugins {
PluginGroupBuilder::start::<Self>()
.add(CorePlugin::default())
.add(TimePlugin::default())
.add(TransformPlugin::default())
.add(HierarchyPlugin::default())
.add(ScheduleRunnerPlugin::default())
.add(WindowPlugin::default())
.add(AssetPlugin::default())
Expand All @@ -30,5 +33,24 @@ pub fn update(app: &mut App, cycles: usize) {
}
}

pub fn create_test_windows() -> Windows {
let mut windows = Windows::default();
let mut test_window = Window::new(
Default::default(),
&Default::default(),
100,
100,
1.0,
None,
None,
);
test_window.update_cursor_physical_position_from_backend(
// position from bottom left of windows
Option::from(DVec2::new(0., 50.))
);
windows.add(test_window);
windows
}



0 comments on commit 3f1d707

Please sign in to comment.