159 lines
5.2 KiB
Rust
159 lines
5.2 KiB
Rust
use std::f32::consts::PI;
|
|
use bevy::prelude::*;
|
|
use heron::prelude::*;
|
|
use crate::{
|
|
map::GroundContact,
|
|
Layer,
|
|
};
|
|
|
|
#[derive(Component)]
|
|
pub struct Player {
|
|
rotation: f32,
|
|
}
|
|
|
|
pub fn setup(
|
|
mut commands: Commands,
|
|
asset_server: Res<AssetServer>,
|
|
) {
|
|
let mesh1 = asset_server.load("Mini-Game Variety Pack/Models/Characters/gltf/character_duck.gltf#Mesh0/Primitive0");
|
|
let mesh2 = asset_server.load("Mini-Game Variety Pack/Models/Characters/gltf/character_duck.gltf#Mesh0/Primitive1");
|
|
let mesh3 = asset_server.load("Mini-Game Variety Pack/Models/Characters/gltf/character_duck.gltf#Mesh0/Primitive2");
|
|
let mesh4 = asset_server.load("Mini-Game Variety Pack/Models/Characters/gltf/character_duck.gltf#Mesh1/Primitive0");
|
|
let material1 = asset_server.load("Mini-Game Variety Pack/Models/Characters/gltf/character_duck.gltf#Material0");
|
|
let material2 = asset_server.load("Mini-Game Variety Pack/Models/Characters/gltf/character_duck.gltf#Material1");
|
|
let material3 = asset_server.load("Mini-Game Variety Pack/Models/Characters/gltf/character_duck.gltf#Material2");
|
|
|
|
let transform = Transform::from_xyz(0.0, 12.0, 0.0);
|
|
commands.spawn()
|
|
.insert(RigidBody::Dynamic)
|
|
.insert(CollisionLayers::none()
|
|
.with_group(Layer::Player)
|
|
.with_masks(&[Layer::Player, Layer::Map])
|
|
)
|
|
.insert(CollisionShape::Cone {
|
|
half_height: 0.7,
|
|
radius: 0.4,
|
|
})
|
|
.insert(PhysicMaterial {
|
|
restitution: 0.0,
|
|
density: 8.0,
|
|
friction: 1.0,
|
|
})
|
|
.insert(RotationConstraints::lock())
|
|
.insert(Velocity::default())
|
|
.insert(Player {
|
|
rotation: 0.0,
|
|
})
|
|
.insert(GroundContact::default())
|
|
.insert(GlobalTransform::default())
|
|
.insert(transform)
|
|
.with_children(|children| {
|
|
children.spawn_bundle(PbrBundle {
|
|
mesh: mesh1.clone(),
|
|
material: material1.clone(),
|
|
..Default::default()
|
|
});
|
|
children.spawn_bundle(PbrBundle {
|
|
mesh: mesh2.clone(),
|
|
material: material2.clone(),
|
|
..Default::default()
|
|
});
|
|
children.spawn_bundle(PbrBundle {
|
|
mesh: mesh3.clone(),
|
|
material: material3.clone(),
|
|
..Default::default()
|
|
});
|
|
let transform = Transform::from_translation(-0.71 * Vec3::Y);
|
|
children.spawn_bundle(PbrBundle {
|
|
mesh: mesh4.clone(),
|
|
material: material1.clone(),
|
|
transform,
|
|
..Default::default()
|
|
});
|
|
});
|
|
}
|
|
|
|
pub fn input(time: Res<Time>, input: Res<Input<KeyCode>>, mut players: Query<(&mut Velocity, &mut Player, &mut Transform, &GroundContact)>) {
|
|
let x;
|
|
let z;
|
|
let target_rotation;
|
|
match [KeyCode::Right, KeyCode::Left, KeyCode::Up, KeyCode::Down].map(|k| input.pressed(k)) {
|
|
[false, false, false, true] => {
|
|
z = 1.0;
|
|
x = 0.0;
|
|
target_rotation = Some(0.0);
|
|
}
|
|
[false, true, false, true] => {
|
|
z = 0.7;
|
|
x = -0.7;
|
|
target_rotation = Some(1.75 * PI);
|
|
}
|
|
[false, true, false, false] => {
|
|
z = 0.0;
|
|
x = -1.0;
|
|
target_rotation = Some(1.5 * PI);
|
|
}
|
|
[false, true, true, false] => {
|
|
z = -0.7;
|
|
x = -0.7;
|
|
target_rotation = Some(1.25 * PI);
|
|
}
|
|
[false, false, true, false] => {
|
|
z = -1.0;
|
|
x = 0.0;
|
|
target_rotation = Some(1.0 * PI);
|
|
}
|
|
[true, false, true, false] => {
|
|
z = -0.7;
|
|
x = 0.7;
|
|
target_rotation = Some(0.75 * PI);
|
|
}
|
|
[true, false, false, false] => {
|
|
z = 0.0;
|
|
x = 1.0;
|
|
target_rotation = Some(0.5 * PI);
|
|
}
|
|
[true, false, false, true] => {
|
|
z = 0.7;
|
|
x = 0.7;
|
|
target_rotation = Some(0.25 * PI);
|
|
}
|
|
_ => {
|
|
z = 0.0;
|
|
x = 0.0;
|
|
target_rotation = None;
|
|
}
|
|
}
|
|
|
|
let y = if input.pressed(KeyCode::Space) {
|
|
1.6
|
|
} else if x != 0.0 || z != 0.0 {
|
|
// walk bobbing
|
|
0.3
|
|
} else {
|
|
0.0
|
|
};
|
|
|
|
const SPEED: f32 = 3.0;
|
|
let target_velocity = SPEED * Vec3::new(x, y, z);
|
|
for (mut velocity, mut player, mut transform, contact) in players.iter_mut() {
|
|
if contact.0 > 0 && velocity.linear.y.abs() < 0.2 {
|
|
velocity.linear = target_velocity;
|
|
}
|
|
|
|
if let Some(target_rotation) = target_rotation {
|
|
if (player.rotation - 2.0 * PI - target_rotation).abs() < (player.rotation - target_rotation).abs() {
|
|
player.rotation -= 2.0 * PI;
|
|
}
|
|
if (player.rotation + 2.0 * PI - target_rotation).abs() < (player.rotation - target_rotation).abs() {
|
|
player.rotation += 2.0 * PI;
|
|
}
|
|
player.rotation += 10.0 * time.delta_seconds() * (target_rotation - player.rotation);
|
|
transform.rotation = Quat::from_axis_angle(
|
|
Vec3::Y,
|
|
player.rotation
|
|
);
|
|
}
|
|
}
|
|
}
|