From 9e49764d54976fbbd3e855f6abc944a23ad0d854 Mon Sep 17 00:00:00 2001 From: Daniel Thompson Date: Sun, 14 Jan 2024 23:10:30 +0000 Subject: [PATCH] Apply a "sin bin" penalty for leaving the track for too long. --- src/main.rs | 89 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 75 insertions(+), 14 deletions(-) diff --git a/src/main.rs b/src/main.rs index 6541b84..834b6c9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,8 @@ // SPDX-License-Identifier: GPL-3.0-or-later // Copyright (C) 2023-2024 Daniel Thompson +#![allow(clippy::type_complexity)] + use bevy::{ math::{vec2, vec3}, prelude::*, @@ -95,6 +97,7 @@ fn main() { .after(apply_velocity) .after(handle_keyboard) .after(handle_ai_players), + apply_time_penalties, ), ) .run(); @@ -103,8 +106,11 @@ fn main() { #[derive(Component, Debug)] struct Player; -#[derive(Component, Debug)] -struct Racer; +#[derive(Component, Debug, Default)] +struct Racer { + penalty: f32, + last_tile: Option, +} #[derive(Component, Default, Debug)] struct Track; @@ -158,8 +164,6 @@ impl GuidanceField { .get_layer(1) .unwrap_or(map.get_layer(0)?) .as_tile_layer()?; - dbg!(map.get_layer(1)); - dbg!(&layer); let w = layer.width()?; let h = layer.height()?; @@ -253,7 +257,7 @@ fn spawn_player( commands.spawn(( Player, - Racer, + Racer::default(), Angle(0.0), Velocity(Vec2::new(0.0, 20.0)), SpriteSheetBundle { @@ -278,7 +282,7 @@ fn spawn_ai_players( let atlas = TextureAtlas::from_grid(handle, Vec2::new(70., 121.), 1, 1, None, None); commands.spawn(( - Racer, + Racer::default(), Angle(PI / 12.0), Velocity(Vec2::new(0.0, 20.0)), SpriteSheetBundle { @@ -296,7 +300,7 @@ fn spawn_ai_players( asset_server.load("embedded://tdr2024/assets/kenney_racing-pack/PNG/Cars/car_yellow_3.png"); let atlas = TextureAtlas::from_grid(handle, Vec2::new(70., 121.), 1, 1, None, None); commands.spawn(( - Racer, + Racer::default(), Angle(PI / 12.0), Velocity(Vec2::new(0.0, 20.0)), SpriteSheetBundle { @@ -314,7 +318,7 @@ fn spawn_ai_players( asset_server.load("embedded://tdr2024/assets/kenney_racing-pack/PNG/Cars/car_green_4.png"); let atlas = TextureAtlas::from_grid(handle, Vec2::new(70., 121.), 1, 1, None, None); commands.spawn(( - Racer, + Racer::default(), Angle(PI / 12.0), Velocity(Vec2::new(0.0, 20.0)), SpriteSheetBundle { @@ -329,6 +333,39 @@ fn spawn_ai_players( )); } +fn apply_time_penalties( + mut query: Query<(&mut Transform, &mut Racer, &Player)>, + maps: Res>, +) { + let map = match maps.iter().next() { + Some(map) => &map.1.map, + None => return, + }; + + let layer = map + .get_layer(1) + .or(map.get_layer(0)) + .and_then(|layer| layer.as_tile_layer()) + .expect("Failed to lookup track layer"); + + for (t, mut r, _) in query.iter_mut() { + let x = (t.translation.x / map.tile_width as f32) + (map.width as f32 / 2.0); + let y = (-t.translation.y / map.tile_height as f32) + (map.height as f32 / 2.0); + + let on_track = layer.get_tile(x as i32, y as i32).is_some(); + if on_track { + let now = vec2(x, y); + if let Some(prev) = r.last_tile { + let delta = now.distance(prev).abs(); + if delta > 1.0 { + r.penalty += delta; + } + } + r.last_tile = Some(now); + } + } +} + fn apply_friction( mut query: Query<(&mut Velocity, &mut Transform)>, time: Res