Slight rework of parallax system

main
Elijah Voigt 2 months ago
parent c1de38988f
commit b8a626194b

@ -10,7 +10,6 @@ fn main() {
.add_systems(Startup, spawn_background)
.add_systems(Update, move_camera)
.add_systems(Update, parallax_gizmos)
.add_systems(Update, move_parallax_items)
.run();
}
@ -19,33 +18,42 @@ fn spawn_background(
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<ColorMaterial>>,
) {
let mesh = Mesh2d(meshes.add(Circle::new(50.0)));
let mesh = Mesh2d(meshes.add(Circle::new(1.0)));
let material = MeshMaterial2d(materials.add(ColorMaterial::from_color(RED)));
let transform = Transform::default().with_scale(Vec3::splat(50.0));
commands.spawn((
Name::new("Depth: 1"),
transform,
mesh.clone(),
material.clone(),
Parallax(1.0),
ParallaxDepth(1.0),
Visibility::Inherited,
children![(Text2d("1.0".into()), Transform::from_xyz(0.0, 35.0, 0.0))],
));
commands.spawn((
Name::new("Depth: 2"),
transform,
mesh.clone(),
material.clone(),
Parallax(2.0),
ParallaxDepth(2.0),
Visibility::Inherited,
children![(Text2d("2.0".into()), Transform::from_xyz(0.0, 35.0, 0.0))],
));
commands.spawn((
Name::new("Depth: 4"),
transform,
mesh.clone(),
material.clone(),
Parallax(4.0),
ParallaxDepth(4.0),
Visibility::Inherited,
children![(Text2d("4.0".into()), Transform::from_xyz(0.0, 35.0, 0.0))],
));
commands.spawn((
Name::new("Depth: 8"),
transform,
mesh.clone(),
material.clone(),
Parallax(8.0),
ParallaxDepth(8.0),
Visibility::Inherited,
children![(Text2d("8.0".into()), Transform::from_xyz(0.0, 35.0, 0.0))],
));
@ -65,7 +73,7 @@ fn move_camera(mut t: Single<&mut Transform, With<Camera2d>>, keys: Res<ButtonIn
}
}
fn parallax_gizmos(mut gizmos: Gizmos, q: Query<&Transform, With<Parallax>>) {
fn parallax_gizmos(mut gizmos: Gizmos, q: Query<&Transform, With<ParallaxDepth>>) {
// Closest to camera
// Parallax(1)
q.iter().for_each(|t| {
@ -79,16 +87,3 @@ fn parallax_gizmos(mut gizmos: Gizmos, q: Query<&Transform, With<Parallax>>) {
.outer_edges();
});
}
// TODO: Move to src/parallax.rs
fn move_parallax_items(
mut q: Query<(Entity, &ViewVisibility, &mut ParallaxRepeatIteration), (With<Parallax>, Changed<ViewVisibility>)>,
) {
q.iter_mut().for_each(|(e, vis, mut pri)| {
warn!("{e} {:?}", vis.get());
if !vis.get() {
pri.0 += 1;
todo!("Works when moving camera right, make it work left too");
}
});
}

@ -11,40 +11,42 @@ impl Plugin for ParallaxPlugin {
}
}
///
/// ParallaxDepth describes how far from the camera something is
///
/// A parallax depth of 1 means it moves 1:1 with camera movement;
/// If the camera moves 1 pixel to the left, the background moves 1px to the right
///
/// A parallax depth of 2 means the movement is 1:2
/// Camera moves 2px, the element moves 1px
///
#[derive(Component)]
#[require(Transform, ParallaxRepeat, ParallaxRepeatIteration)]
pub struct Parallax(pub f32);
#[derive(Component)]
pub struct ParallaxRepeat(pub f32);
impl Default for ParallaxRepeat{
fn default() -> Self {
ParallaxRepeat(1.0)
}
}
#[derive(Component, Default)]
pub struct ParallaxRepeatIteration(pub isize);
pub struct ParallaxDepth(pub f32);
fn move_parallax_items(
mut q: Query<(&mut Transform, &Parallax, &ParallaxRepeat, &ParallaxRepeatIteration), Without<Camera2d>>,
camera: Single<(&Camera, &Transform, &GlobalTransform), With<Camera2d>>,
window: Single<&Window>
mut q: Query<(&mut Transform, &ParallaxDepth), Without<Camera>>,
window: Single<&Window>,
camera: Single<(&Camera, &Transform, &GlobalTransform), (With<Camera2d>, Changed<Transform>)>,
mut prev_camera_pos: Local<Vec2>,
) {
// Unpack the camera data
let (cam, cam_t, cam_gt) = *camera;
let base = cam_t.translation.truncate();
let size = window.size();
q.iter_mut().for_each(|(mut t, p, pr, pri)| {
let offset: Vec2 = {
let a = cam.viewport_to_world_2d(cam_gt, Vec2::new(0.0, size.y / 2.0)).unwrap();
let b = cam.viewport_to_world_2d(cam_gt, Vec2::new(size.x, size.y / 2.0)).unwrap();
(b - a) * pr.0 * (pri.0 as f32)
};
// Something like add screen-dimensions * parallax repeat cycle number
let val = base * (1.0 - (1.0 / p.0)) + offset;
t.translation.x = val.x;
t.translation.y = val.y;
// Calculate how far the camera moved since the last update
let delta = cam_t.translation.truncate() - *prev_camera_pos;
debug!("Cam Delta: {:?}", delta);
// For each object
q.iter_mut().for_each(|(mut t, pd)| {
// Update ParallaxPosition
let depth_movement = delta / pd.0;
debug!("Depth: {:?} | Move: {:?}", pd.0, depth_movement);
// Update actual position
t.translation.x -= depth_movement.x;
t.translation.y -= depth_movement.y;
});
*prev_camera_pos = cam_t.translation.truncate();
}

Loading…
Cancel
Save