shoot eggs

This commit is contained in:
Astro 2022-01-16 00:10:11 +01:00
parent 37fa990463
commit 6900d1ce31
4 changed files with 63 additions and 10 deletions

View File

@ -18,6 +18,7 @@ pub enum Key {
Left, Left,
Right, Right,
Jump, Jump,
Shoot,
} }
const KEYBOARD_KEYS: &[(KeyCode, Source, Key)] = &[ const KEYBOARD_KEYS: &[(KeyCode, Source, Key)] = &[
@ -25,12 +26,14 @@ const KEYBOARD_KEYS: &[(KeyCode, Source, Key)] = &[
(KeyCode::Down, Source::KeyboardRight, Key::Down), (KeyCode::Down, Source::KeyboardRight, Key::Down),
(KeyCode::Left, Source::KeyboardRight, Key::Left), (KeyCode::Left, Source::KeyboardRight, Key::Left),
(KeyCode::Right, Source::KeyboardRight, Key::Right), (KeyCode::Right, Source::KeyboardRight, Key::Right),
(KeyCode::Return, Source::KeyboardRight, Key::Jump), (KeyCode::RShift, Source::KeyboardRight, Key::Jump),
(KeyCode::RControl, Source::KeyboardRight, Key::Shoot),
(KeyCode::W, Source::KeyboardLeft, Key::Up), (KeyCode::W, Source::KeyboardLeft, Key::Up),
(KeyCode::S, Source::KeyboardLeft, Key::Down), (KeyCode::S, Source::KeyboardLeft, Key::Down),
(KeyCode::A, Source::KeyboardLeft, Key::Left), (KeyCode::A, Source::KeyboardLeft, Key::Left),
(KeyCode::D, Source::KeyboardLeft, Key::Right), (KeyCode::D, Source::KeyboardLeft, Key::Right),
(KeyCode::Space, Source::KeyboardLeft, Key::Jump), (KeyCode::LShift, Source::KeyboardLeft, Key::Jump),
(KeyCode::LControl, Source::KeyboardLeft, Key::Shoot),
]; ];
const GAMEPAD_KEYS: &[(GamepadButtonType, Key)] = &[ const GAMEPAD_KEYS: &[(GamepadButtonType, Key)] = &[
@ -39,6 +42,7 @@ const GAMEPAD_KEYS: &[(GamepadButtonType, Key)] = &[
(GamepadButtonType::DPadLeft, Key::Left), (GamepadButtonType::DPadLeft, Key::Left),
(GamepadButtonType::DPadRight, Key::Right), (GamepadButtonType::DPadRight, Key::Right),
(GamepadButtonType::South, Key::Jump), (GamepadButtonType::South, Key::Jump),
(GamepadButtonType::East, Key::Shoot),
]; ];
#[derive(Default)] #[derive(Default)]

View File

@ -15,6 +15,7 @@ mod off_map;
pub enum Layer { pub enum Layer {
Map, Map,
Player, Player,
Projectile,
} }
fn main() { fn main() {

View File

@ -13,6 +13,8 @@ pub struct LevelResources {
soil_material: Handle<StandardMaterial>, soil_material: Handle<StandardMaterial>,
grass_material: Handle<StandardMaterial>, grass_material: Handle<StandardMaterial>,
bridge_material: Handle<StandardMaterial>, bridge_material: Handle<StandardMaterial>,
pub egg_material: Handle<StandardMaterial>,
pub egg_mesh: Handle<Mesh>,
last_build: Option<Time>, last_build: Option<Time>,
} }
@ -88,12 +90,18 @@ impl Ground {
pub fn setup( pub fn setup(
mut commands: Commands, mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>, mut materials: ResMut<Assets<StandardMaterial>>,
) { ) {
let res = LevelResources { let res = LevelResources {
soil_material: materials.add(Color::rgb(0.8, 0.7, 0.1).into()), soil_material: materials.add(Color::rgb(0.8, 0.7, 0.1).into()),
grass_material: materials.add(Color::rgb(0.2, 1.0, 0.25).into()), grass_material: materials.add(Color::rgb(0.2, 1.0, 0.25).into()),
bridge_material: materials.add(Color::rgb(0.5, 0.4, 0.1).into()), bridge_material: materials.add(Color::rgb(0.5, 0.4, 0.1).into()),
egg_material: materials.add(Color::rgb(1.0, 1.0, 0.9).into()),
egg_mesh: meshes.add(Mesh::from(shape::Icosphere {
radius: crate::player::EGG_RADIUS,
subdivisions: 8,
})),
last_build: None, last_build: None,
}; };
commands.insert_resource(res); commands.insert_resource(res);
@ -267,7 +275,7 @@ fn add_island(
.insert(RigidBody::Static) .insert(RigidBody::Static)
.insert(CollisionLayers::none() .insert(CollisionLayers::none()
.with_group(Layer::Map) .with_group(Layer::Map)
.with_masks(&[Layer::Player]) .with_masks(&[Layer::Player, Layer::Projectile])
) )
.insert(CollisionShape::Cuboid { .insert(CollisionShape::Cuboid {
border_radius: None, border_radius: None,
@ -310,7 +318,7 @@ fn add_bridge(
.insert(RigidBody::Static) .insert(RigidBody::Static)
.insert(CollisionLayers::none() .insert(CollisionLayers::none()
.with_group(Layer::Map) .with_group(Layer::Map)
.with_masks(&[Layer::Player]) .with_masks(&[Layer::Player, Layer::Projectile])
) )
.insert(CollisionShape::Cuboid { .insert(CollisionShape::Cuboid {
border_radius: None, border_radius: None,

View File

@ -9,10 +9,13 @@ use crate::{
Layer, Layer,
}; };
pub const EGG_RADIUS: f32 = 0.15;
#[derive(Component)] #[derive(Component)]
pub struct Player { pub struct Player {
input_source: InputSource, input_source: InputSource,
rotation: f32, rotation: f32,
last_shot: Option<Time>,
} }
pub fn spawn_player( pub fn spawn_player(
@ -22,7 +25,7 @@ pub fn spawn_player(
asset_server: Res<AssetServer>, asset_server: Res<AssetServer>,
) { ) {
let input_source = match input.keys.iter().find(|(input_source, key)| let input_source = match input.keys.iter().find(|(input_source, key)|
if *key == Key::Jump { if [Key::Jump, Key::Shoot].iter().find(|k| k == &key).is_some() {
! players.iter().any(|player| player.input_source == *input_source) ! players.iter().any(|player| player.input_source == *input_source)
} else { } else {
false false
@ -47,11 +50,11 @@ pub fn spawn_player(
.insert(RigidBody::Dynamic) .insert(RigidBody::Dynamic)
.insert(CollisionLayers::none() .insert(CollisionLayers::none()
.with_group(Layer::Player) .with_group(Layer::Player)
.with_masks(&[Layer::Player, Layer::Map]) .with_masks(&[Layer::Player, Layer::Projectile, Layer::Map])
) )
.insert(CollisionShape::Cone { .insert(CollisionShape::Cone {
half_height: 0.7, half_height: 0.8,
radius: 0.4, radius: 0.7,
}) })
.insert(PhysicMaterial { .insert(PhysicMaterial {
restitution: 0.0, restitution: 0.0,
@ -63,6 +66,7 @@ pub fn spawn_player(
.insert(Player { .insert(Player {
input_source: input_source.clone(), input_source: input_source.clone(),
rotation: 0.0, rotation: 0.0,
last_shot: None,
}) })
.insert(CanFallOffMap) .insert(CanFallOffMap)
.insert(GroundContact::default()) .insert(GroundContact::default())
@ -97,7 +101,9 @@ pub fn spawn_player(
pub fn input( pub fn input(
time: Res<Time>, time: Res<Time>,
input: Res<InputState>, input: Res<InputState>,
mut players: Query<(&mut Velocity, &mut Player, &mut Transform, &GroundContact)> mut players: Query<(&mut Velocity, &mut Player, &mut Transform, &GroundContact)>,
res: Res<crate::map::LevelResources>,
mut commands: Commands,
) { ) {
const SPEED: f32 = 4.0; const SPEED: f32 = 4.0;
@ -116,12 +122,13 @@ pub fn input(
}; };
let target_velocity = SPEED * Vec3::new(x, y, z); let target_velocity = SPEED * Vec3::new(x, y, z);
if contact.0 > 0 && velocity.linear.y.abs() < 0.2 { if contact.0 > 0 && velocity.linear.y.abs() < 0.2 {
// only move if GroundContact and not falling
velocity.linear = target_velocity; velocity.linear = target_velocity;
} }
if direction.length_squared() > 0.0 { if direction.length_squared() > 0.0 {
// spin
let target_rotation = direction.angle_between(Vec2::Y); let target_rotation = direction.angle_between(Vec2::Y);
if (player.rotation - 2.0 * PI - target_rotation).abs() < (player.rotation - target_rotation).abs() { if (player.rotation - 2.0 * PI - target_rotation).abs() < (player.rotation - target_rotation).abs() {
@ -136,5 +143,38 @@ pub fn input(
player.rotation player.rotation
); );
} }
if player.last_shot.as_ref().map_or(true, |last_shot| time.seconds_since_startup() - last_shot.seconds_since_startup() >= 0.5)
&& input.keys.contains(&(player.input_source.clone(), Key::Shoot))
{
let direction = Quat::from_rotation_y(player.rotation) * Vec3::Z;
let mut transform = Transform::from_translation(transform.translation + 0.5 * direction);
transform.scale += 0.3 * direction;
commands.spawn()
.insert(RigidBody::Dynamic)
.insert(CollisionLayers::none()
.with_group(Layer::Projectile)
.with_masks(&[Layer::Player, Layer::Map, Layer::Projectile])
)
.insert(CollisionShape::Sphere {
radius: EGG_RADIUS,
})
.insert(PhysicMaterial {
restitution: 0.0,
density: 50_000.0,
friction: 1.0,
})
.insert(Velocity::from_linear(20.0 * direction))
.insert(CanFallOffMap)
.insert(GlobalTransform::default())
.insert_bundle(PbrBundle {
mesh: res.egg_mesh.clone(),
material: res.egg_material.clone(),
transform,
..Default::default()
});
player.last_shot = Some(time.clone());
}
} }
} }