More correct parallax example!

main
Elijah Voigt 2 months ago
parent 1525cc75f9
commit 4a2bbf3242

BIN
assets/bevy.png (Stored with Git LFS)

Binary file not shown.

@ -9,7 +9,6 @@ fn main() {
},))
.add_systems(Startup, spawn_background)
.add_systems(Update, move_camera)
.add_systems(Update, parallax_gizmos)
.run();
}
@ -17,43 +16,55 @@ fn spawn_background(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<ColorMaterial>>,
server: Res<AssetServer>,
) {
let mesh = Mesh2d(meshes.add(Circle::new(1.0)));
commands.spawn((
Name::new("Depth: 1.1"),
Name::new("Depth: 1.0"),
Transform::default().with_translation(Vec3::new(0.0, 0.0, 0.0)).with_scale(Vec3::splat(50.0)),
mesh.clone(),
MeshMaterial2d(materials.add(ColorMaterial::from_color(RED))),
ParallaxDepth(1.1),
Mesh2d(meshes.add(Circle::new(1.0))),
MeshMaterial2d(materials.add(ColorMaterial {
texture: Some(server.load("bevy.png")),
color: RED.into(),
..default()
})),
ParallaxDepth(1.0),
Visibility::Inherited,
children![(Text2d("1.1".into()), Transform::from_xyz(0.0, 35.0, 0.0))],
));
commands.spawn((
Name::new("Depth: 2.1"),
Transform::default().with_translation(Vec3::new(0.0, 0.0, -1.0)).with_scale(Vec3::splat(50.0)),
mesh.clone(),
MeshMaterial2d(materials.add(ColorMaterial::from_color(GREEN))),
ParallaxDepth(2.1),
Name::new("Depth: 2.0"),
Transform::default().with_translation(Vec3::new(0.0, 0.0, -1.0)).with_scale(Vec3::splat(25.0)),
Mesh2d(meshes.add(Circle::new(2.0))),
MeshMaterial2d(materials.add(ColorMaterial {
texture: Some(server.load("bevy.png")),
color: GREEN.into(),
..default()
})),
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.1"),
Transform::default().with_translation(Vec3::new(0.0, 0.0, -2.0)).with_scale(Vec3::splat(50.0)),
mesh.clone(),
MeshMaterial2d(materials.add(ColorMaterial::from_color(BLUE))),
ParallaxDepth(4.1),
Name::new("Depth: 4.0"),
Transform::default().with_translation(Vec3::new(0.0, 0.0, -2.0)).with_scale(Vec3::splat(12.5)),
Mesh2d(meshes.add(Circle::new(4.0))),
MeshMaterial2d(materials.add(ColorMaterial {
texture: Some(server.load("bevy.png")),
color: BLUE.into(),
..default()
})),
ParallaxDepth(4.0),
Visibility::Inherited,
children![(Text2d("4.1".into()), Transform::from_xyz(0.0, 35.0, 0.0))],
));
commands.spawn((
Name::new("Depth: 8.1"),
Transform::default().with_translation(Vec3::new(0.0, 0.0, -3.0)).with_scale(Vec3::splat(50.0)),
mesh.clone(),
MeshMaterial2d(materials.add(ColorMaterial::from_color(YELLOW))),
ParallaxDepth(8.1),
Name::new("Depth: 8.0"),
Transform::default().with_translation(Vec3::new(0.0, 0.0, -3.0)).with_scale(Vec3::splat(6.25)),
Mesh2d(meshes.add(Circle::new(8.0))),
MeshMaterial2d(materials.add(ColorMaterial {
texture: Some(server.load("bevy.png")),
color: YELLOW.into(),
..default()
})),
ParallaxDepth(8.0),
Visibility::Inherited,
children![(Text2d("8.1".into()), Transform::from_xyz(0.0, 35.0, 0.0))],
));
}
@ -70,18 +81,3 @@ fn move_camera(mut t: Single<&mut Transform, With<Camera2d>>, keys: Res<ButtonIn
t.translation.y += 5.0;
}
}
fn parallax_gizmos(mut gizmos: Gizmos, q: Query<&Transform, With<ParallaxDepth>>) {
// Closest to camera
// Parallax(1)
q.iter().for_each(|t| {
gizmos
.grid_2d(
t.translation.truncate(),
UVec2::new(5, 5),
Vec2::splat(10.),
MAGENTA,
)
.outer_edges();
});
}

@ -36,6 +36,7 @@ fn main() {
init_bird.after(init_assets),
init_first_batches.after(init_assets),
init_ui,
init_background,
tweak_camera.after(create_camera_2d),
),
)
@ -699,6 +700,47 @@ fn init_ui(mut commands: Commands, server: Res<AssetServer>) {
));
}
fn init_background(
mut commands: Commands,
server: Res<AssetServer>,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<ColorMaterial>>,
) {
{
let material = MeshMaterial2d(materials.add(ColorMaterial {
texture: Some(server.load("flappy/background-city.png")),
color: BLACK.into(),
alpha_mode: AlphaMode2d::Blend,
..default()
}));
let mesh = Mesh2d(meshes.add(Rectangle::new(1.0, 1.0)));
let t = Transform::from_xyz(0.0, 0.0, -32.0).with_scale(Vec3::splat(650.0));
commands.spawn((ParallaxDepth(4.0), mesh, material, t));
}
{
let material = MeshMaterial2d(materials.add(ColorMaterial {
texture: Some(server.load("flappy/background-clouds.png")),
color: BLACK.into(),
alpha_mode: AlphaMode2d::Blend,
..default()
}));
let mesh = Mesh2d(meshes.add(Rectangle::new(1.0, 1.0)));
let t = Transform::from_xyz(0.0, 0.0, -64.0).with_scale(Vec3::splat(650.0));
commands.spawn((ParallaxDepth(8.0), mesh, material, t));
}
{
let material = MeshMaterial2d(materials.add(ColorMaterial {
texture: Some(server.load("flappy/background-gradient.png")),
color: BLACK.into(),
alpha_mode: AlphaMode2d::Blend,
..default()
}));
let mesh = Mesh2d(meshes.add(Rectangle::new(1.0, 1.0)));
let t = Transform::from_xyz(0.0, 0.0, -128.0).with_scale(Vec3::splat(650.0));
commands.spawn((ParallaxDepth(16.0), mesh, material, t));
}
}
fn start_rewind(_trigger: Trigger<Pointer<Pressed>>, mut next: ResMut<NextState<PlayerState>>) {
next.set(PlayerState::Rewind);
}

@ -1,3 +1,6 @@
use bevy::render::primitives::Aabb;
use bevy::render::mesh::MeshAabb;
use super::*;
pub struct ParallaxPlugin;
@ -54,9 +57,10 @@ fn move_parallax_items(
}
fn wrap_parallax_items(
mut items: Query<(&mut Transform, &GlobalTransform, &ViewVisibility), (With<ParallaxDepth>, Without<Camera2d>, Changed<ViewVisibility>)>,
mut items: Query<(&mut Transform, &GlobalTransform, &ViewVisibility, &Mesh2d), (With<ParallaxDepth>, Without<Camera2d>, Changed<ViewVisibility>)>,
camera: Single<(&Camera, &GlobalTransform), With<Camera2d>>,
window: Single<&Window>,
meshes: Res<Assets<Mesh>>,
) {
if !items.is_empty() {
let (cam, cam_gt) = *camera;
@ -68,26 +72,28 @@ fn wrap_parallax_items(
Vec2::abs(Vec2::new(bottom_right.x - top_left.x, bottom_right.y - top_left.y))
};
debug!("Window size: {:?}", window_size_in_world_space);
// for each item in the paralax items
items.iter_mut().for_each(|(mut t, gt, v)| {
items.iter_mut().for_each(|(mut t, gt, v, Mesh2d(m))| {
if !v.get() {
debug!("The item is not visible");
info!("Item is not visible");
// Get the total size (window + scale)
let total_size = window_size_in_world_space + (t.scale.truncate() * 2.0);
debug!("Window size: {:?} | Object size: {:?}", window_size_in_world_space, t.scale.truncate());
debug!("Total size: {:?}", total_size);
let half_extents = {
let Aabb { half_extents, .. } = meshes.get(m).unwrap().compute_aabb().unwrap();
half_extents.truncate()
};
let object_size = t.scale.truncate() * 2.0;
let total_size = window_size_in_world_space + (object_size * half_extents);
info!("Sizes:\n\twindow {window_size_in_world_space}\n\tobject size: {object_size}\n\tAabb Half extents: {half_extents}\n\tTotal size: {total_size}");
// Double check that item is out of bounds
let bounds_check = Vec2::abs(cam_gt.translation().truncate() - gt.translation().truncate());
let out_of_bounds = (total_size / 2.0) - bounds_check;
debug!("Bounds check {:?}", bounds_check);
debug!("Out of bounds: {:?}", out_of_bounds);
debug!("Starting position: {:?}", t.translation);
info!("Bounds check {bounds_check} | Out of bounds: {out_of_bounds:?}");
info!("Starting position: {:?}", t.translation);
if out_of_bounds.x < 0.0 {
debug!("Object is actually out of bounds horizontally");
info!("Object is actually out of bounds horizontally");
// determine if should move to the left or right relative to camera
let move_right = cam_gt.translation().x > gt.translation().x;
@ -99,7 +105,7 @@ fn wrap_parallax_items(
}
}
if out_of_bounds.y < 0.0 {
debug!("Object is actually out of bounds vertically");
info!("Object is actually out of bounds vertically");
let move_up = cam_gt.translation().y > gt.translation().y;
// move up or down
@ -109,7 +115,7 @@ fn wrap_parallax_items(
t.translation.y -= total_size.y;
}
}
debug!("Moved to {:?}", t.translation);
info!("Moved to {:?}", t.translation);
}
});
}

Loading…
Cancel
Save