generalize player into actor
This commit is contained in:
parent
cef6e5cce7
commit
f9e76921ec
124
src/actor.rs
Normal file
124
src/actor.rs
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
#[allow(unused)] pub const OXYGEN_USE_KG_PER_S: f32 = 1e-5;
|
||||||
|
#[allow(unused)] pub const OXY_S: f32 = OXYGEN_USE_KG_PER_S;
|
||||||
|
#[allow(unused)] pub const OXY_M: f32 = OXYGEN_USE_KG_PER_S * 60.0;
|
||||||
|
#[allow(unused)] pub const OXY_H: f32 = OXYGEN_USE_KG_PER_S * 60.0 * 60.0;
|
||||||
|
#[allow(unused)] pub const OXY_D: f32 = OXYGEN_USE_KG_PER_S * 60.0 * 60.0 * 24.0;
|
||||||
|
|
||||||
|
pub struct ActorPlugin;
|
||||||
|
impl Plugin for ActorPlugin {
|
||||||
|
fn build(&self, app: &mut App) {
|
||||||
|
app.add_systems(FixedUpdate, update);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
pub struct Actor {
|
||||||
|
pub hp: f32,
|
||||||
|
pub m: f32, // mass
|
||||||
|
pub pos: Vec3, // position
|
||||||
|
pub v: Vec3, // velocity
|
||||||
|
// TODO: rotation
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Actor {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
hp: 100.0,
|
||||||
|
m: 100.0,
|
||||||
|
pos: Vec3::ZERO,
|
||||||
|
v: Vec3::ZERO,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
pub struct LifeForm {
|
||||||
|
pub adrenaline: f32,
|
||||||
|
pub adrenaline_baseline: f32,
|
||||||
|
pub adrenaline_jolt: f32,
|
||||||
|
}
|
||||||
|
impl Default for LifeForm { fn default() -> Self { Self {
|
||||||
|
adrenaline: 0.3,
|
||||||
|
adrenaline_baseline: 0.3,
|
||||||
|
adrenaline_jolt: 0.0,
|
||||||
|
}}}
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
pub struct Suit {
|
||||||
|
pub oxygen: f32,
|
||||||
|
pub power: f32,
|
||||||
|
pub oxygen_max: f32,
|
||||||
|
pub power_max: f32,
|
||||||
|
}
|
||||||
|
impl Default for Suit { fn default() -> Self { SUIT_SIMPLE } }
|
||||||
|
|
||||||
|
const SUIT_SIMPLE: Suit = Suit {
|
||||||
|
power: 1e5,
|
||||||
|
power_max: 1e5,
|
||||||
|
oxygen: OXY_D,
|
||||||
|
oxygen_max: OXY_D,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn update(
|
||||||
|
time: Res<Time>,
|
||||||
|
mut query: Query<(&mut LifeForm, &mut Suit)>,
|
||||||
|
) {
|
||||||
|
let d = time.delta_seconds();
|
||||||
|
for (mut lifeform, mut suit) in query.iter_mut() {
|
||||||
|
if lifeform.adrenaline_jolt.abs() > 1e-3 {
|
||||||
|
lifeform.adrenaline_jolt *= 0.99;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lifeform.adrenaline_jolt = 0.0
|
||||||
|
}
|
||||||
|
lifeform.adrenaline = (lifeform.adrenaline - 0.0001 + lifeform.adrenaline_jolt * 0.01).clamp(0.0, 1.0);
|
||||||
|
suit.oxygen = (suit.oxygen - OXY_S*d).clamp(0.0, 1.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
pub struct Player;
|
||||||
|
|
||||||
|
//pub enum SuitSystemHandler {
|
||||||
|
// Heat,
|
||||||
|
// None,
|
||||||
|
//}
|
||||||
|
//#[derive(Component)]
|
||||||
|
//pub struct SuitSystem {
|
||||||
|
// pub name: String,
|
||||||
|
// pub active: bool,
|
||||||
|
// pub power: f32,
|
||||||
|
// pub handler: SuitSystemHandler,
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//impl Default for SuitSystem {
|
||||||
|
// fn default() -> Self {
|
||||||
|
// Self {
|
||||||
|
// name: "Untitled".to_string(),
|
||||||
|
// active: true,
|
||||||
|
// power: 0.0,
|
||||||
|
// handler: SuitSystemHandler::None,
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//pub fn setup(
|
||||||
|
// mut commands: Commands,
|
||||||
|
// settings: Res<settings::Settings>,
|
||||||
|
//) {
|
||||||
|
// commands.spawn((
|
||||||
|
// Player,
|
||||||
|
// SuitSystem {
|
||||||
|
// name: "HUD".to_string(),
|
||||||
|
// active: settings.hud_active,
|
||||||
|
// power: -0.05,
|
||||||
|
// ..default()
|
||||||
|
// },
|
||||||
|
// SuitSystem {
|
||||||
|
// name: "Heater".to_string(),
|
||||||
|
// handler: SuitSystemHandler::Heat,
|
||||||
|
// ..default()
|
||||||
|
// }
|
||||||
|
// ));
|
||||||
|
//}
|
37
src/hud.rs
37
src/hud.rs
|
@ -1,12 +1,12 @@
|
||||||
use crate::{settings, player};
|
use crate::{settings, actor};
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy::diagnostic::{DiagnosticsStore, FrameTimeDiagnosticsPlugin};
|
use bevy::diagnostic::{DiagnosticsStore, FrameTimeDiagnosticsPlugin};
|
||||||
|
|
||||||
const HUD_REFRESH_TIME: f32 = 0.5;
|
const HUD_REFRESH_TIME: f32 = 0.5;
|
||||||
const FONT: &str = "tmp/fonts/NotoSansSC-Thin.ttf";
|
const FONT: &str = "tmp/fonts/NotoSansSC-Thin.ttf";
|
||||||
|
|
||||||
pub struct OutFlyHudPlugin;
|
pub struct HudPlugin;
|
||||||
impl Plugin for OutFlyHudPlugin {
|
impl Plugin for HudPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.add_systems(Startup, setup);
|
app.add_systems(Startup, setup);
|
||||||
app.add_systems(Update, (update, handle_input));
|
app.add_systems(Update, (update, handle_input));
|
||||||
|
@ -114,25 +114,30 @@ fn setup(
|
||||||
|
|
||||||
fn update(
|
fn update(
|
||||||
diagnostics: Res<DiagnosticsStore>,
|
diagnostics: Res<DiagnosticsStore>,
|
||||||
time:Res<Time>,
|
time: Res<Time>,
|
||||||
playervars:Res<player::PlayerVars>,
|
player: Query<(&actor::Suit, &actor::LifeForm), With<actor::Player>>,
|
||||||
mut timer: ResMut<FPSUpdateTimer>,
|
mut timer: ResMut<FPSUpdateTimer>,
|
||||||
mut query: Query<&mut Text, With<GaugesText>>,
|
mut query: Query<&mut Text, With<GaugesText>>,
|
||||||
) {
|
) {
|
||||||
if timer.0.tick(time.delta()).just_finished() {
|
if timer.0.tick(time.delta()).just_finished() {
|
||||||
for mut text in &mut query {
|
let player = player.get_single();
|
||||||
if let Some(fps) = diagnostics.get(&FrameTimeDiagnosticsPlugin::FPS) {
|
if player.is_ok() {
|
||||||
if let Some(value) = fps.smoothed() {
|
let (suit, lifeform) = player.unwrap();
|
||||||
// Update the value of the second section
|
for mut text in &mut query {
|
||||||
text.sections[1].value = format!("{value:.0}");
|
if let Some(fps) = diagnostics.get(&FrameTimeDiagnosticsPlugin::FPS) {
|
||||||
|
if let Some(value) = fps.smoothed() {
|
||||||
|
// Update the value of the second section
|
||||||
|
text.sections[1].value = format!("{value:.0}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
let power = suit.power;
|
||||||
|
text.sections[3].value = format!("{power:}Wh");
|
||||||
|
let oxy_percent = suit.oxygen / suit.oxygen_max * 100.0;
|
||||||
|
let oxy_total = suit.oxygen * 1e6;
|
||||||
|
text.sections[5].value = format!("{oxy_percent:.1}% [{oxy_total:.0}mg]");
|
||||||
|
let adrenaline = lifeform.adrenaline * 990.0 + 10.0;
|
||||||
|
text.sections[7].value = format!("{adrenaline:.0}pg/mL");
|
||||||
}
|
}
|
||||||
let power = playervars.power;
|
|
||||||
text.sections[3].value = format!("{power:}Wh");
|
|
||||||
let oxygen = playervars.oxygen * 100.0;
|
|
||||||
text.sections[5].value = format!("{oxygen:.1}%");
|
|
||||||
let adrenaline = playervars.adrenaline * 990.0 + 10.0;
|
|
||||||
text.sections[7].value = format!("{adrenaline:.0}pg/mL");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
11
src/main.rs
11
src/main.rs
|
@ -1,9 +1,9 @@
|
||||||
mod audio;
|
mod audio;
|
||||||
mod player;
|
|
||||||
mod camera;
|
mod camera;
|
||||||
mod world;
|
mod world;
|
||||||
mod settings;
|
mod settings;
|
||||||
mod hud;
|
mod hud;
|
||||||
|
mod actor;
|
||||||
|
|
||||||
use bevy::window::{Window, WindowMode, PrimaryWindow, CursorGrabMode };
|
use bevy::window::{Window, WindowMode, PrimaryWindow, CursorGrabMode };
|
||||||
use bevy::diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin};
|
use bevy::diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin};
|
||||||
|
@ -14,29 +14,24 @@ fn main() {
|
||||||
.add_systems(Startup, (
|
.add_systems(Startup, (
|
||||||
setup,
|
setup,
|
||||||
audio::setup,
|
audio::setup,
|
||||||
player::setup,
|
|
||||||
world::setup,
|
world::setup,
|
||||||
))
|
))
|
||||||
.add_systems(Update, (
|
.add_systems(Update, (
|
||||||
handle_input,
|
handle_input,
|
||||||
player::handle_input,
|
|
||||||
audio::toggle_bgm,
|
audio::toggle_bgm,
|
||||||
world::asset_loaded.after(world::load_cubemap_asset),
|
world::asset_loaded.after(world::load_cubemap_asset),
|
||||||
))
|
))
|
||||||
.add_systems(FixedUpdate, (
|
|
||||||
player::drain_resources,
|
|
||||||
))
|
|
||||||
.add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest()))
|
.add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest()))
|
||||||
.add_plugins((
|
.add_plugins((
|
||||||
camera::CameraControllerPlugin,
|
camera::CameraControllerPlugin,
|
||||||
hud::OutFlyHudPlugin,
|
hud::HudPlugin,
|
||||||
|
actor::ActorPlugin,
|
||||||
))
|
))
|
||||||
.add_plugins((
|
.add_plugins((
|
||||||
FrameTimeDiagnosticsPlugin,
|
FrameTimeDiagnosticsPlugin,
|
||||||
LogDiagnosticsPlugin::default(),
|
LogDiagnosticsPlugin::default(),
|
||||||
))
|
))
|
||||||
.insert_resource(settings::Settings::default())
|
.insert_resource(settings::Settings::default())
|
||||||
.insert_resource(player::PlayerVars::default())
|
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,91 +1,6 @@
|
||||||
use crate::settings;
|
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy::window::PrimaryWindow;
|
use bevy::window::PrimaryWindow;
|
||||||
|
|
||||||
#[derive(Component)]
|
|
||||||
pub struct Player {
|
|
||||||
pub hp: f32,
|
|
||||||
pub pos: Vec3,
|
|
||||||
pub v: Vec3,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Player {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
hp: 100.0,
|
|
||||||
pos: Vec3::ZERO,
|
|
||||||
v: Vec3::ZERO,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum SuitSystemHandler {
|
|
||||||
Heat,
|
|
||||||
None,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Component)]
|
|
||||||
pub struct PlayerEntity;
|
|
||||||
|
|
||||||
#[derive(Component)]
|
|
||||||
pub struct SuitSystem {
|
|
||||||
pub name: String,
|
|
||||||
pub active: bool,
|
|
||||||
pub power: f32,
|
|
||||||
pub handler: SuitSystemHandler,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for SuitSystem {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
name: "Untitled".to_string(),
|
|
||||||
active: true,
|
|
||||||
power: 0.0,
|
|
||||||
handler: SuitSystemHandler::None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Resource)]
|
|
||||||
pub struct PlayerVars {
|
|
||||||
pub oxygen: f32,
|
|
||||||
pub adrenaline: f32,
|
|
||||||
pub adrenaline_jolt: f32,
|
|
||||||
pub power: f32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for PlayerVars {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
oxygen: 0.1984,
|
|
||||||
adrenaline: 0.1,
|
|
||||||
adrenaline_jolt: 0.5,
|
|
||||||
power: 6200.0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn setup(
|
|
||||||
mut commands: Commands,
|
|
||||||
settings: Res<settings::Settings>,
|
|
||||||
) {
|
|
||||||
commands.spawn(Player::default());
|
|
||||||
commands.spawn((
|
|
||||||
PlayerEntity,
|
|
||||||
SuitSystem {
|
|
||||||
name: "HUD".to_string(),
|
|
||||||
active: settings.hud_active,
|
|
||||||
power: -0.05,
|
|
||||||
..default()
|
|
||||||
},
|
|
||||||
SuitSystem {
|
|
||||||
name: "Heater".to_string(),
|
|
||||||
handler: SuitSystemHandler::Heat,
|
|
||||||
..default()
|
|
||||||
}
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn handle_input(
|
pub fn handle_input(
|
||||||
keyboard_input: Res<ButtonInput<KeyCode>>,
|
keyboard_input: Res<ButtonInput<KeyCode>>,
|
||||||
mut windows: Query<&mut Window, With<PrimaryWindow>>,
|
mut windows: Query<&mut Window, With<PrimaryWindow>>,
|
||||||
|
@ -104,15 +19,3 @@ pub fn handle_input(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn drain_resources(
|
|
||||||
mut playervars:ResMut<PlayerVars>,
|
|
||||||
) {
|
|
||||||
if playervars.adrenaline_jolt.abs() > 1e-3 {
|
|
||||||
playervars.adrenaline_jolt *= 0.99;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
playervars.adrenaline_jolt = 0.0
|
|
||||||
}
|
|
||||||
playervars.adrenaline = (playervars.adrenaline - 0.0001 + playervars.adrenaline_jolt * 0.01).clamp(0.0, 1.0);
|
|
||||||
playervars.oxygen = (playervars.oxygen - 0.000001).clamp(0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
13
src/world.rs
13
src/world.rs
|
@ -1,4 +1,4 @@
|
||||||
use crate::camera;
|
use crate::{actor, camera};
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy::core_pipeline::Skybox;
|
use bevy::core_pipeline::Skybox;
|
||||||
use bevy::asset::LoadState;
|
use bevy::asset::LoadState;
|
||||||
|
@ -22,6 +22,17 @@ pub fn setup(
|
||||||
mut ambient_light: ResMut<AmbientLight>,
|
mut ambient_light: ResMut<AmbientLight>,
|
||||||
asset_server: Res<AssetServer>,
|
asset_server: Res<AssetServer>,
|
||||||
) {
|
) {
|
||||||
|
// Add player
|
||||||
|
commands.spawn((
|
||||||
|
actor::Player,
|
||||||
|
actor::Actor::default(),
|
||||||
|
actor::LifeForm::default(),
|
||||||
|
actor::Suit {
|
||||||
|
oxygen: actor::OXY_M,
|
||||||
|
..default()
|
||||||
|
}
|
||||||
|
));
|
||||||
|
|
||||||
// Add skybox
|
// Add skybox
|
||||||
let skybox_handle = asset_server.load(CUBEMAP_PATH);
|
let skybox_handle = asset_server.load(CUBEMAP_PATH);
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
|
|
Loading…
Reference in a new issue