shoot eggs
This commit is contained in:
parent
37fa990463
commit
6900d1ce31
|
@ -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)]
|
||||||
|
|
|
@ -15,6 +15,7 @@ mod off_map;
|
||||||
pub enum Layer {
|
pub enum Layer {
|
||||||
Map,
|
Map,
|
||||||
Player,
|
Player,
|
||||||
|
Projectile,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
12
src/map.rs
12
src/map.rs
|
@ -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,
|
||||||
|
|
|
@ -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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue