100 lines
2.2 KiB
Rust
100 lines
2.2 KiB
Rust
use crate::game::Level;
|
|
|
|
use bevy::prelude::{shape::Quad, *};
|
|
use bevy_rapier2d::prelude::*;
|
|
|
|
#[derive(Component)]
|
|
pub enum PassThroughFilter {
|
|
/// Absorbs this color (ignoring alpha)
|
|
Absorbing(Color),
|
|
/// Rotates hue by this angle (in degrees)
|
|
Rotating(f32),
|
|
}
|
|
|
|
impl PassThroughFilter {
|
|
pub fn apply(&self, color: Color) -> Color {
|
|
match self {
|
|
PassThroughFilter::Absorbing(filter_color) => Vec4::from(color)
|
|
.mul_add(
|
|
-Vec4::from(*filter_color) * Vec4::from([1., 1., 1., 0.]),
|
|
Vec4::from(color),
|
|
)
|
|
.into(),
|
|
PassThroughFilter::Rotating(filter_angle) => {
|
|
let mut hsla = color.as_hsla_f32();
|
|
hsla[0] = (hsla[0] + filter_angle) % 360.;
|
|
Color::hsla(hsla[0], hsla[1], hsla[2], hsla[3])
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Bundle)]
|
|
pub struct AbsorbingFilter {
|
|
#[bundle]
|
|
pub mesh: ColorMesh2dBundle,
|
|
pub collider: Collider,
|
|
pub sensor: Sensor,
|
|
pub filter: PassThroughFilter,
|
|
}
|
|
|
|
pub fn spawn_absorbing_filter(
|
|
commands: &mut Commands,
|
|
meshes: &mut ResMut<Assets<Mesh>>,
|
|
materials: &mut ResMut<Assets<ColorMaterial>>,
|
|
|
|
transform: Transform,
|
|
size: Vec2,
|
|
color: Color,
|
|
) {
|
|
let mut material_color = color;
|
|
material_color.set_a(0.5);
|
|
commands
|
|
.spawn_bundle(AbsorbingFilter {
|
|
mesh: ColorMesh2dBundle {
|
|
mesh: meshes.add(Mesh::from(Quad { size, flip: false })).into(),
|
|
material: materials.add(material_color.into()),
|
|
transform,
|
|
..Default::default()
|
|
},
|
|
collider: Collider::cuboid(size.x / 2., size.y / 2.),
|
|
sensor: Sensor,
|
|
filter: PassThroughFilter::Absorbing(color),
|
|
})
|
|
.insert(Level);
|
|
}
|
|
|
|
#[derive(Bundle)]
|
|
pub struct RotatingFilter {
|
|
#[bundle]
|
|
pub sprite: SpriteBundle,
|
|
pub collider: Collider,
|
|
pub sensor: Sensor,
|
|
pub filter: PassThroughFilter,
|
|
pub velocity: Velocity,
|
|
pub rigid_body: RigidBody,
|
|
}
|
|
|
|
pub fn spawn_rotating_filter(
|
|
commands: &mut Commands,
|
|
asset_server: &Res<AssetServer>,
|
|
|
|
transform: Transform,
|
|
angle: f32,
|
|
) {
|
|
commands
|
|
.spawn_bundle(RotatingFilter {
|
|
sprite: SpriteBundle {
|
|
texture: asset_server.get_handle("bevy.png"),
|
|
transform,
|
|
..Default::default()
|
|
},
|
|
collider: Collider::ball(32.),
|
|
sensor: Sensor,
|
|
filter: PassThroughFilter::Rotating(angle),
|
|
velocity: Velocity::angular(1.),
|
|
rigid_body: RigidBody::KinematicVelocityBased,
|
|
})
|
|
.insert(Level);
|
|
}
|