use avian3d::prelude::*;
use bevy::{core_pipeline::Skybox, prelude::*, render::render_resource::AsBindGroupShaderType};
use leafwing_input_manager::prelude::*;
use crate::{
input::{self, Action},
mouse_joy::MouseJoy,
skybox::SkyCubeMap,
};
#[derive(Component)]
pub struct Player;
pub fn set_up_player(mut commands: Commands, assets: ResMut<AssetServer>) {
let skybox = assets.load("skybox.png");
let player_transform = Transform::from_xyz(0.0, 0.0, 0.0);
let camera_transform = Transform::from_xyz(0.0, 4.0, 20.0);
let player = assets.load("Racer.glb#Scene0");
commands.insert_resource(SkyCubeMap {
is_loaded: false,
image_handle: skybox.clone(),
});
commands
.spawn(SceneBundle {
scene: player,
transform: player_transform.clone(),
..default()
})
.insert(InputManagerBundle::with_map(input::default_input_map()))
.insert(Player)
.insert(Collider::sphere(1.0))
.insert(RigidBody::Dynamic)
.insert(ExternalForce::default().with_persistence(false))
.insert(ExternalTorque::default().with_persistence(false))
.insert(LinearVelocity::default())
.insert(LinearDamping(0.01))
.insert(AngularDamping(3.0))
.with_children(|parent| {
parent.spawn((
Camera3dBundle {
transform: camera_transform,
..default()
},
Skybox {
image: skybox,
brightness: 100.0,
},
));
});
}
pub fn quit_game(mut exit: EventWriter<AppExit>, mut query: Query<&mut ActionState<Action>>) {
let (actions) = query.single_mut();
if actions.pressed(&Action::Quit) {
exit.send(AppExit::Success);
}
}
pub fn move_player(
mut query: Query<(
&mut Player,
&Transform,
&mut ExternalForce,
&mut ExternalTorque,
&LinearVelocity,
&ActionState<Action>,
)>,
joy: Res<MouseJoy>,
time: Res<Time>,
) {
let speed = 200.0;
let key_multiplier = 10.0;
let turn_speed = 300.0;
let brake_speed = 50.0;
let dt = time.delta_seconds();
let (mut player, xform, mut force, mut torque, velocity, actions) = query.single_mut();
let strafe = actions.axis_pair(&Action::StrafeXZ);
let mut momentum = key_multiplier
* (xform.right().as_vec3() * strafe[0] + xform.forward().as_vec3() * strafe[1]);
if actions.pressed(&Action::StrafePosX) {
momentum = momentum + key_multiplier * xform.right().as_vec3();
}
if actions.pressed(&Action::StrafeNegX) {
momentum = momentum + key_multiplier * xform.left().as_vec3();
}
if actions.pressed(&Action::StrafePosY) {
momentum = momentum + key_multiplier * xform.up().as_vec3();
}
if actions.pressed(&Action::StrafeNegY) {
momentum = momentum + key_multiplier * xform.down().as_vec3();
}
if actions.pressed(&Action::StrafePosZ) {
momentum = momentum + key_multiplier * xform.forward().as_vec3();
}
if actions.pressed(&Action::StrafeNegZ) {
momentum = momentum + key_multiplier * xform.back().as_vec3();
}
if actions.pressed(&Action::Brake) {
momentum -= velocity.0 * dt * brake_speed;
}
force.apply_force(momentum * speed * dt);
let mut pya = actions.axis_pair(&Action::PitchYaw);
pya.y *= -1.0;
let py = pya + joy.0;
torque.apply_torque(dt * turn_speed * (xform.down() * py.x + xform.left() * py.y));
let mut roll = 0.0;
if actions.pressed(&Action::PosRoll) {
roll += turn_speed;
}
if actions.pressed(&Action::NegRoll) {
roll -= turn_speed;
}
torque.apply_torque(key_multiplier * 0.5 * xform.forward() * dt * roll);
}