WIP time trial: basic implementation
This commit is contained in:
parent
71259431eb
commit
afeba6b63d
BIN
assets/models/marker_race.glb
Normal file
BIN
assets/models/marker_race.glb
Normal file
Binary file not shown.
BIN
src/blender/marker_race.blend
Normal file
BIN
src/blender/marker_race.blend
Normal file
Binary file not shown.
101
src/game.rs
101
src/game.rs
|
@ -11,6 +11,7 @@
|
|||
// This module handles player input, and coordinates interplay between other modules
|
||||
|
||||
use crate::prelude::*;
|
||||
use actor::PlayerCamera;
|
||||
use bevy::color::palettes::css;
|
||||
use bevy::prelude::*;
|
||||
use bevy::scene::SceneInstance;
|
||||
|
@ -21,6 +22,7 @@ use std::collections::HashMap;
|
|||
pub const CHEAT_WARP_1: &str = "pizzeria";
|
||||
pub const CHEAT_WARP_2: &str = "busstopclippy2";
|
||||
pub const CHEAT_WARP_3: &str = "busstopclippy3";
|
||||
pub const RACE_TARGET_RADIUS: f64 = 5.0;
|
||||
|
||||
pub struct GamePlugin;
|
||||
impl Plugin for GamePlugin {
|
||||
|
@ -48,12 +50,14 @@ impl Plugin for GamePlugin {
|
|||
.run_if(on_event::<AchievementEvent>()),
|
||||
);
|
||||
app.add_systems(Update, check_achievements.run_if(game_running));
|
||||
app.add_systems(Update, handle_race.run_if(game_running));
|
||||
app.insert_resource(Id2Pos(HashMap::new()));
|
||||
app.insert_resource(Id2V(HashMap::new()));
|
||||
app.insert_resource(JupiterPos(DVec3::ZERO));
|
||||
app.insert_resource(var::AchievementTracker::default());
|
||||
app.insert_resource(var::Settings::default());
|
||||
app.insert_resource(var::GameVars::default());
|
||||
app.insert_resource(RaceState::default());
|
||||
app.insert_resource(AchievementCheckTimer(Timer::from_seconds(
|
||||
1.0,
|
||||
TimerMode::Repeating,
|
||||
|
@ -74,6 +78,16 @@ pub struct Id2V(pub HashMap<String, DVec3>);
|
|||
pub struct JupiterPos(pub DVec3);
|
||||
#[derive(Resource)]
|
||||
pub struct AchievementCheckTimer(pub Timer);
|
||||
#[derive(Resource, Default)]
|
||||
pub struct RaceState {
|
||||
pub initialized: bool,
|
||||
pub started: bool,
|
||||
pub start_countdown: f64,
|
||||
pub timeout: f64,
|
||||
pub score: u64,
|
||||
}
|
||||
#[derive(Component)]
|
||||
pub struct RaceTarget;
|
||||
|
||||
#[derive(Event)]
|
||||
pub enum AchievementEvent {
|
||||
|
@ -155,13 +169,35 @@ impl Cycle {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn setup(mut settings: ResMut<Settings>, prefs: ResMut<var::Preferences>) {
|
||||
pub fn setup(
|
||||
mut commands: Commands,
|
||||
mut settings: ResMut<Settings>,
|
||||
prefs: ResMut<var::Preferences>,
|
||||
asset_server: Res<AssetServer>,
|
||||
) {
|
||||
settings.hud_active = prefs.augmented_reality;
|
||||
settings.radio_mode = prefs.radio_station;
|
||||
settings.set_noise_cancellation_mode(prefs.noise_cancellation_mode);
|
||||
settings.third_person = prefs.third_person;
|
||||
settings.shadows_sun = prefs.shadows_sun;
|
||||
settings.ar_avatar = prefs.avatar;
|
||||
|
||||
// Setup Race
|
||||
let mut entitycmd = commands.spawn((
|
||||
RaceTarget,
|
||||
actor::OrbitsJupiter,
|
||||
bevy::pbr::NotShadowCaster,
|
||||
bevy::pbr::NotShadowReceiver,
|
||||
Position::default(),
|
||||
actor::WantsToLookAt(cmd::ID_SPECIAL_PLAYERCAM.to_string()),
|
||||
LinearVelocity::default(),
|
||||
SpatialBundle {
|
||||
transform: Transform::from_scale(Vec3::splat(RACE_TARGET_RADIUS as f32)),
|
||||
visibility: Visibility::Hidden,
|
||||
..default()
|
||||
},
|
||||
));
|
||||
load_asset("marker_race", &mut entitycmd, &*asset_server);
|
||||
}
|
||||
|
||||
pub fn handle_game_event(
|
||||
|
@ -678,3 +714,66 @@ fn handle_window_focus(
|
|||
*local_paused = paused;
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_race(
|
||||
mut commands: Commands,
|
||||
time: Res<Time>,
|
||||
mut log: ResMut<hud::Log>,
|
||||
mut settings: ResMut<Settings>,
|
||||
mut race: ResMut<RaceState>,
|
||||
mut ew_sfx: EventWriter<audio::PlaySfxEvent>,
|
||||
q_player: Query<(&Position, &LinearVelocity), With<PlayerCamera>>,
|
||||
mut q_racetarget: Query<
|
||||
(Entity, &mut Position, &mut LinearVelocity, &mut Visibility),
|
||||
(With<RaceTarget>, Without<PlayerCamera>),
|
||||
>,
|
||||
) {
|
||||
if !settings.race_active {
|
||||
return;
|
||||
}
|
||||
let (player_pos, player_v) = if let Ok(val) = q_player.get_single() {
|
||||
val
|
||||
} else {
|
||||
error!("No player found in handle_race!");
|
||||
return;
|
||||
};
|
||||
let (target_entity, mut target_pos, mut target_v, mut target_vis) =
|
||||
if let Ok(val) = q_racetarget.get_single_mut() {
|
||||
val
|
||||
} else {
|
||||
error!("No race target entity found in handle_race!");
|
||||
return;
|
||||
};
|
||||
|
||||
let mut spawn_target = false;
|
||||
|
||||
if !race.initialized {
|
||||
log.warning("Time Trial Race START!".to_string());
|
||||
ew_sfx.send(audio::PlaySfxEvent(audio::Sfx::Honk));
|
||||
race.score = 0;
|
||||
race.initialized = true;
|
||||
spawn_target = true;
|
||||
}
|
||||
|
||||
if player_pos.distance(target_pos.0) < RACE_TARGET_RADIUS {
|
||||
race.score += 1;
|
||||
spawn_target = true;
|
||||
}
|
||||
|
||||
if spawn_target {
|
||||
race.timeout = time.elapsed_seconds_f64() + 5.0;
|
||||
*target_pos = Position(player_pos.0 + DVec3::new(100.0, 0.0, 0.0));
|
||||
*target_v = *player_v;
|
||||
*target_vis = Visibility::Inherited;
|
||||
commands.entity(target_entity).insert(RigidBody::Kinematic);
|
||||
}
|
||||
|
||||
if race.timeout <= time.elapsed_seconds_f64() {
|
||||
log.warning(format!("GAME OVER! Final score: {}", race.score));
|
||||
ew_sfx.send(audio::PlaySfxEvent(audio::Sfx::PowerDown));
|
||||
race.initialized = false;
|
||||
settings.race_active = false;
|
||||
*target_vis = Visibility::Hidden;
|
||||
commands.entity(target_entity).remove::<RigidBody>();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,6 +67,7 @@ pub fn asset_name_to_path(name: &str) -> &'static str {
|
|||
"whale" => "models/whale.gltf#Scene0",
|
||||
"marker_satellites" => "models/marker_satellites.glb#Scene0",
|
||||
"marker_planets" => "models/marker_planets.glb#Scene0",
|
||||
"marker_race" => "models/marker_race.glb#Scene0",
|
||||
"point_of_interest" => "models/point_of_interest.glb#Scene0",
|
||||
"metis" => "models/metis.gltf#Scene0",
|
||||
"thebe" => "models/thebe.gltf#Scene0",
|
||||
|
|
Loading…
Reference in a new issue