Skip to content

Commit

Permalink
feat!: Add kills and time to leaderboard UI
Browse files Browse the repository at this point in the history
  • Loading branch information
PraxTube committed Jan 10, 2024
1 parent 5cdfdcf commit 21ac16b
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 27 deletions.
1 change: 1 addition & 0 deletions src/ui/game_over.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ impl Plugin for GameOverPlugin {
OnEnter(GameState::GameOver),
(spawn_game_over_screen, reset_game_over_state),
)
.add_systems(OnExit(GameState::GameOver), despawn_game_over_screens)
.add_systems(OnExit(GameOverState::GameOver), despawn_game_over_screens)
.add_systems(OnExit(GameState::GameOver), despawn_game_over_background);
}
Expand Down
49 changes: 26 additions & 23 deletions src/ui/leaderboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,23 @@ use bevy::{
tasks::{block_on, AsyncComputeTaskPool, Task},
};

use crate::{player::score::PlayerScore, GameAssets, GameState};
use crate::{
player::{kill_counter::KillCounter, score::PlayerScore, speed_timer::SpeedTimer},
utils::format_time,
GameAssets, GameState,
};

use super::{game_over::GameOverState, text_field::SubmittedTextInput};

const HOST: &str = "rancic.org";
const PORT: &str = "3434";
const LEADERBOARD_COUNT: usize = 7;

struct LeaderboardEntry {
name: String,
score: String,
kills: String,
time: String,
}

#[derive(Resource, Deref, DerefMut)]
Expand Down Expand Up @@ -87,8 +94,8 @@ fn spawn_score_row(

let name = spawn_text(commands, font.clone(), &leaderboard_data[i].name, 0);
let score = spawn_text(commands, font.clone(), &leaderboard_data[i].score, 1);
let kill = spawn_text(commands, font.clone(), "-", 2);
let time = spawn_text(commands, font.clone(), "-", 3);
let kill = spawn_text(commands, font.clone(), &leaderboard_data[i].kills, 2);
let time = spawn_text(commands, font.clone(), &leaderboard_data[i].time, 3);

spawn_row(commands, &[name, score, kill, time])
}
Expand All @@ -101,7 +108,7 @@ fn spawn_leaderboard(
let header = spawn_header(&mut commands, assets.font.clone());

let mut score_rows = Vec::new();
for i in 0..10 {
for i in 0..LEADERBOARD_COUNT {
score_rows.push(spawn_score_row(
&mut commands,
assets.font.clone(),
Expand Down Expand Up @@ -151,25 +158,20 @@ fn send_get_request(mut commands: Commands) {
\r\n",
HOST
);
let error_str = String::from("ERROR");

if let Ok(mut stream) = TcpStream::connect(format!("{}:{}", HOST, PORT)) {
if let Err(e) = stream.write_all(request.as_bytes()) {
error!("Failed to send request: {}", e);
return error_str;
return format!("Failed to send request: {}", e);
}

let mut response = String::new();
if let Err(e) = stream.read_to_string(&mut response) {
error!("Failed to read response: {}", e);
return error_str;
return format!("Failed to read response: {}", e);
}

return response;
} else {
error!("Failed to connect to the server");
}
error_str
"Failed to connect to the server".to_string()
});
commands.spawn(FetchData(task));
}
Expand Down Expand Up @@ -222,13 +224,15 @@ fn string_to_leaderboard(s: &str) -> LeaderboardData {
return LeaderboardData(Vec::new());
}

let rows: Vec<&str> = s.split(";").collect();
let rows: Vec<&str> = s.split(';').collect();
let mut result = Vec::new();
for row in rows {
let values: Vec<&str> = row.split(",").collect();
let values: Vec<&str> = row.split(',').collect();
result.push(LeaderboardEntry {
name: values[0].to_string(),
score: values[1].to_string(),
kills: values[2].to_string(),
time: format_time(values[3].parse().unwrap_or_default()),
});
}
LeaderboardData(result)
Expand All @@ -237,17 +241,20 @@ fn string_to_leaderboard(s: &str) -> LeaderboardData {
fn send_post_request(
mut commands: Commands,
player_score: Res<PlayerScore>,
kill_counter: Res<KillCounter>,
speed_timer: Res<SpeedTimer>,
mut ev_submitted_text_input: EventReader<SubmittedTextInput>,
) {
let thread_pool = AsyncComputeTaskPool::get();

for ev in ev_submitted_text_input.read() {
let name = ev.0.clone();
let score = player_score.score();
let kills = kill_counter.kills();
let time = speed_timer.elapsed;

let task = thread_pool.spawn(async move {
let error_str = String::from("ERROR");
let data_to_send = format!("{},{}", name, score);
let data_to_send = format!("{},{},{},{}", name, score, kills, time);

let request = format!(
"POST / HTTP/1.1\r\n\
Expand All @@ -264,22 +271,18 @@ fn send_post_request(

if let Ok(mut stream) = TcpStream::connect(format!("{}:{}", HOST, PORT)) {
if let Err(e) = stream.write_all(request.as_bytes()) {
error!("Failed to send request: {}", e);
return error_str;
return format!("Failed to send request: {}", e);
}

let mut response = String::new();
if let Err(e) = stream.read_to_string(&mut response) {
error!("Failed to read response: {}", e);
return error_str;
return format!("Failed to read response: {}", e);
}

println!("Response:\n{}", response);
return response;
} else {
error!("Failed to connect to the server");
}
return error_str;
"Failed to connect to the server".to_string()
});
commands.spawn(PostData(task));
}
Expand Down
8 changes: 6 additions & 2 deletions src/ui/text_field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,14 +155,14 @@ fn update_buffer_text(

fn update_cursor_text(
mut timer: ResMut<TypingCursorTimer>,
mut query: Query<&mut Text, With<TypingCursor>>,
mut q_cursor: Query<&mut Text, With<TypingCursor>>,
time: Res<Time>,
) {
if !timer.0.tick(time.delta()).just_finished() {
return;
}

for mut target in query.iter_mut() {
for mut target in q_cursor.iter_mut() {
if target.sections[0].style.color != Color::NONE {
target.sections[0].style.color = Color::NONE;
} else {
Expand All @@ -176,10 +176,14 @@ fn push_chars(
mut submitted_text_input: EventWriter<SubmittedTextInput>,
mut keyboard_input_events: EventReader<KeyboardInput>,
keys: Res<Input<KeyCode>>,
q_input_field: Query<With<InputField>>,
) {
let control_active = keys.pressed(KeyCode::ControlLeft);

for ev in keyboard_input_events.read() {
if q_input_field.is_empty() {
continue;
}
// We run this in the loop so that the events get consumed.
// Otherwise we might run into the issue of added it to the buffer
// when spawning the text field.
Expand Down
7 changes: 7 additions & 0 deletions src/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,10 @@ fn reset_rotations(
}
}
}

pub fn format_time(seconds: f32) -> String {
let minutes = (seconds / 60.0) as u32;
let seconds = (seconds % 60.0) as u32;

format!("{:02}:{:02}", minutes, seconds)
}
22 changes: 20 additions & 2 deletions src/world/restart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,19 @@ fn reset_resources(
*player_score = PlayerScore::default();
}

fn initiate_restart(mut next_state: ResMut<NextState<GameState>>, player_input: Res<PlayerInput>) {
fn initiate_restart_from_game_over(
mut next_state: ResMut<NextState<GameState>>,
player_input: Res<PlayerInput>,
) {
if player_input.escape {
next_state.set(GameState::Restart);
}
}

fn initiate_restart_from_leaderboard(
mut next_state: ResMut<NextState<GameState>>,
player_input: Res<PlayerInput>,
) {
if player_input.restart {
next_state.set(GameState::Restart);
}
Expand All @@ -52,7 +64,13 @@ impl Plugin for RestartPlugin {
.add_systems(OnEnter(GameState::Restart), (reset_resources,))
.add_systems(
Update,
(initiate_restart,).run_if(
(initiate_restart_from_game_over,).run_if(
in_state(GameState::GameOver).and_then(in_state(GameOverState::GameOver)),
),
)
.add_systems(
Update,
(initiate_restart_from_leaderboard,).run_if(
in_state(GameState::GameOver).and_then(in_state(GameOverState::Leaderboard)),
),
)
Expand Down

0 comments on commit 21ac16b

Please sign in to comment.