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(Startup, spawn_background)
.add_systems(Update, move_camera) .add_systems(Update, move_camera)
.add_systems(Update, parallax_gizmos) .add_systems(Update, parallax_gizmos)
.add_systems(Update, move_parallax_items)
.run(); .run();
} }
@ -19,33 +18,42 @@ fn spawn_background(
mut meshes: ResMut<Assets<Mesh>>, mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<ColorMaterial>>, 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 material = MeshMaterial2d(materials.add(ColorMaterial::from_color(RED)));
let transform = Transform::default().with_scale(Vec3::splat(50.0));
commands.spawn(( commands.spawn((
Name::new("Depth: 1"),
transform,
mesh.clone(), mesh.clone(),
material.clone(), material.clone(),
Parallax(1.0), ParallaxDepth(1.0),
Visibility::Inherited, Visibility::Inherited,
children![(Text2d("1.0".into()), Transform::from_xyz(0.0, 35.0, 0.0))], children![(Text2d("1.0".into()), Transform::from_xyz(0.0, 35.0, 0.0))],
)); ));
commands.spawn(( commands.spawn((
Name::new("Depth: 2"),
transform,
mesh.clone(), mesh.clone(),
material.clone(), material.clone(),
Parallax(2.0), ParallaxDepth(2.0),
Visibility::Inherited, Visibility::Inherited,
children![(Text2d("2.0".into()), Transform::from_xyz(0.0, 35.0, 0.0))], children![(Text2d("2.0".into()), Transform::from_xyz(0.0, 35.0, 0.0))],
)); ));
commands.spawn(( commands.spawn((
Name::new("Depth: 4"),
transform,
mesh.clone(), mesh.clone(),
material.clone(), material.clone(),
Parallax(4.0), ParallaxDepth(4.0),
Visibility::Inherited, Visibility::Inherited,
children![(Text2d("4.0".into()), Transform::from_xyz(0.0, 35.0, 0.0))], children![(Text2d("4.0".into()), Transform::from_xyz(0.0, 35.0, 0.0))],
)); ));
commands.spawn(( commands.spawn((
Name::new("Depth: 8"),
transform,
mesh.clone(), mesh.clone(),
material.clone(), material.clone(),
Parallax(8.0), ParallaxDepth(8.0),
Visibility::Inherited, Visibility::Inherited,
children![(Text2d("8.0".into()), Transform::from_xyz(0.0, 35.0, 0.0))], 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 // Closest to camera
// Parallax(1) // Parallax(1)
q.iter().for_each(|t| { q.iter().for_each(|t| {
@ -79,16 +87,3 @@ fn parallax_gizmos(mut gizmos: Gizmos, q: Query<&Transform, With<Parallax>>) {
.outer_edges(); .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)] #[derive(Component)]
#[require(Transform, ParallaxRepeat, ParallaxRepeatIteration)] pub struct ParallaxDepth(pub f32);
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);
fn move_parallax_items( fn move_parallax_items(
mut q: Query<(&mut Transform, &Parallax, &ParallaxRepeat, &ParallaxRepeatIteration), Without<Camera2d>>, mut q: Query<(&mut Transform, &ParallaxDepth), Without<Camera>>,
camera: Single<(&Camera, &Transform, &GlobalTransform), With<Camera2d>>, window: Single<&Window>,
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 (cam, cam_t, cam_gt) = *camera;
let base = cam_t.translation.truncate();
let size = window.size(); // Calculate how far the camera moved since the last update
let delta = cam_t.translation.truncate() - *prev_camera_pos;
q.iter_mut().for_each(|(mut t, p, pr, pri)| { debug!("Cam Delta: {:?}", delta);
let offset: Vec2 = {
let a = cam.viewport_to_world_2d(cam_gt, Vec2::new(0.0, size.y / 2.0)).unwrap(); // For each object
let b = cam.viewport_to_world_2d(cam_gt, Vec2::new(size.x, size.y / 2.0)).unwrap(); q.iter_mut().for_each(|(mut t, pd)| {
(b - a) * pr.0 * (pri.0 as f32) // Update ParallaxPosition
}; let depth_movement = delta / pd.0;
// Something like add screen-dimensions * parallax repeat cycle number
let val = base * (1.0 - (1.0 / p.0)) + offset; debug!("Depth: {:?} | Move: {:?}", pd.0, depth_movement);
t.translation.x = val.x;
t.translation.y = val.y; // 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