support multiple thrown projectiles

This commit is contained in:
2025-04-08 10:51:46 +02:00
parent bf90ad8caf
commit ae8026588b
7 changed files with 50 additions and 30 deletions

Binary file not shown.

View File

@@ -44,6 +44,7 @@ pub struct TriggerData {
rot: Quat, rot: Quat,
pos: Vec3, pos: Vec3,
target_layer: GameLayer, target_layer: GameLayer,
head: usize,
} }
impl TriggerData { impl TriggerData {
@@ -53,6 +54,7 @@ impl TriggerData {
rot: Quat, rot: Quat,
pos: Vec3, pos: Vec3,
target_layer: GameLayer, target_layer: GameLayer,
head: usize,
) -> Self { ) -> Self {
Self { Self {
target, target,
@@ -60,6 +62,7 @@ impl TriggerData {
rot, rot,
pos, pos,
target_layer, target_layer,
head,
} }
} }
} }
@@ -135,6 +138,7 @@ fn on_trigger_state(
pos: transform.translation, pos: transform.translation,
target: target.0, target: target.0,
target_layer: GameLayer::Npc, target_layer: GameLayer::Npc,
head: state.head,
}; };
active_heads.use_ammo(time.elapsed_secs()); active_heads.use_ammo(time.elapsed_secs());

View File

@@ -15,7 +15,9 @@ use bevy_sprite3d::{Sprite3dBuilder, Sprite3dParams};
use std::f32::consts::PI; use std::f32::consts::PI;
#[derive(Component)] #[derive(Component)]
struct ThrownProjectile; struct ThrownProjectile {
impact_animation: bool,
}
#[derive(Component, Reflect)] #[derive(Component, Reflect)]
#[reflect(Component)] #[reflect(Component)]
@@ -113,10 +115,17 @@ fn on_trigger_thrown(
let t = Transform::from_translation(state.pos); let t = Transform::from_translation(state.pos);
let (mesh, explosion_animation) = match state.head {
8 => (assets.hammer.clone(), false),
_ => (assets.molotov.clone(), true),
};
commands commands
.spawn(( .spawn((
Name::new("projectile-thrown"), Name::new("projectile-thrown"),
ThrownProjectile, ThrownProjectile {
impact_animation: explosion_animation,
},
Collider::sphere(0.5), Collider::sphere(0.5),
CollisionLayers::new( CollisionLayers::new(
LayerMask(GameLayer::Projectile.to_bits()), LayerMask(GameLayer::Projectile.to_bits()),
@@ -130,8 +139,7 @@ fn on_trigger_thrown(
)) ))
.with_child(( .with_child((
AutoRotation(Quat::from_rotation_x(0.4) * Quat::from_rotation_z(0.3)), AutoRotation(Quat::from_rotation_x(0.4) * Quat::from_rotation_z(0.3)),
Transform::from_scale(Vec3::splat(10.)), SceneRoot(mesh),
SceneRoot(assets.molotov.clone()),
)); ));
} }
@@ -149,7 +157,10 @@ fn shot_collision(
let shot_entity = if query_shot.contains(*e1) { *e1 } else { *e2 }; let shot_entity = if query_shot.contains(*e1) { *e1 } else { *e2 };
let Ok(shot_pos) = query_shot.get(shot_entity).map(|(_, t)| t.translation) else { let Ok((shot_pos, animation)) = query_shot
.get(shot_entity)
.map(|(projectile, t)| (t.translation, projectile.impact_animation))
else {
continue; continue;
}; };
@@ -164,29 +175,32 @@ fn shot_collision(
radius: 5., radius: 5.,
}); });
commands //TODO: support different impact animations
.spawn( if animation {
Sprite3dBuilder { commands
image: assets.image.clone(), .spawn(
pixels_per_metre: 32., Sprite3dBuilder {
alpha_mode: AlphaMode::Blend, image: assets.image.clone(),
unlit: true, pixels_per_metre: 32.,
..default() alpha_mode: AlphaMode::Blend,
} unlit: true,
.bundle_with_atlas( ..default()
&mut sprite_params, }
TextureAtlas { .bundle_with_atlas(
layout: assets.layout.clone(), &mut sprite_params,
index: 0, TextureAtlas {
}, layout: assets.layout.clone(),
), index: 0,
) },
.insert(( ),
Billboard, )
Transform::from_translation(shot_pos), .insert((
NotShadowCaster, Billboard,
AnimationTimer::new(Timer::from_seconds(0.02, TimerMode::Repeating)), Transform::from_translation(shot_pos),
)); NotShadowCaster,
AnimationTimer::new(Timer::from_seconds(0.02, TimerMode::Repeating)),
));
}
} }
} }

View File

@@ -39,6 +39,7 @@ fn update(
t.rotation, t.rotation,
t.translation, t.translation,
crate::physics_layers::GameLayer::Player, crate::physics_layers::GameLayer::Player,
npc.head,
))); )));
} }
} }

View File

@@ -78,6 +78,9 @@ pub struct GameAssets {
#[asset(path = "models/head_misc/molotov_cocktail.glb#Scene0")] #[asset(path = "models/head_misc/molotov_cocktail.glb#Scene0")]
pub molotov: Handle<Scene>, pub molotov: Handle<Scene>,
#[asset(path = "models/head_misc/hammer.glb#Scene0")]
pub hammer: Handle<Scene>,
#[asset(path = "models/alien_naked.glb#Scene0")] #[asset(path = "models/alien_naked.glb#Scene0")]
pub mesh_alien: Handle<Scene>, pub mesh_alien: Handle<Scene>,

View File

@@ -79,9 +79,7 @@ fn move_active(
let t = (elapsed - active.start_time) / active.duration; let t = (elapsed - active.start_time) / active.duration;
transform.rotation = active.start.rotation.lerp(active.target.rotation, t); transform.rotation = active.start.rotation.lerp(active.target.rotation, t);
} else { } else {
info!("movable done");
*transform = active.target; *transform = active.target;
commands.entity(e).remove::<(ActiveMovable, Movable)>(); commands.entity(e).remove::<(ActiveMovable, Movable)>();
} }
} }