From 7010c6a97904fa90e723a5fc852f3415d9da8902 Mon Sep 17 00:00:00 2001 From: ghostly_zsh Date: Wed, 2 Jul 2025 16:39:24 -0500 Subject: [PATCH] 3 layer starfield with parallax --- crates/unified/src/client/mod.rs | 8 +-- crates/unified/src/client/starfield.rs | 90 ++++++++++++++++++++++---- crates/unified/src/ecs.rs | 2 + 3 files changed, 83 insertions(+), 17 deletions(-) diff --git a/crates/unified/src/client/mod.rs b/crates/unified/src/client/mod.rs index 357fa1149d3add5b7198a5d8292617579cfca07d..9e501a72fba9ec590bb3178c6a9fc0b1f4516872 100644 --- a/crates/unified/src/client/mod.rs +++ b/crates/unified/src/client/mod.rs @@ -5,6 +5,8 @@ mod starfield; use std::net::{SocketAddr, UdpSocket}; use std::time::SystemTime; +use bevy::core_pipeline::bloom::Bloom; +use bevy::core_pipeline::tonemapping::Tonemapping; use bevy::prelude::*; use bevy::window::PrimaryWindow; use bevy_rapier2d::prelude::RigidBody; @@ -75,12 +77,8 @@ fn find_me(mut commands: Commands, q_clients: Query<(Entity, &Player), Added, Without)>, mut player: Query<&Transform, With>) { diff --git a/crates/unified/src/client/starfield.rs b/crates/unified/src/client/starfield.rs index b58c422a43bfd6efd142502697e9fe1d0111d080..b31ea875c6789fe95f018076bca2882f31f2fe52 100644 --- a/crates/unified/src/client/starfield.rs +++ b/crates/unified/src/client/starfield.rs @@ -1,8 +1,10 @@ -use bevy::{app::{App, Startup, Update}, asset::{AssetEvent, AssetServer, Assets}, ecs::{event::EventReader, query::{With, Without}, system::{Commands, Query, Res, ResMut}}, image::Image, math::Vec2, sprite::{Sprite, SpriteImageMode}, transform::components::Transform, window::{Window, WindowResized}}; +use bevy::{app::{App, Startup, Update}, asset::{AssetEvent, AssetServer, Assets}, color::Color, ecs::{event::EventReader, query::{With, Without}, system::{Commands, Query, Res, ResMut}}, image::Image, math::{Vec2, Vec3}, sprite::{Sprite, SpriteImageMode}, transform::components::Transform, window::{Window, WindowResized}}; -use crate::{client::Me, ecs::StarfieldFront}; +use crate::{client::Me, ecs::{StarfieldBack, StarfieldFront, StarfieldMid}}; -const STARFIELD_SIZE: f32 = 512.0; +const BACK_STARFIELD_SIZE: f32 = 256.0; +const MID_STARFIELD_SIZE: f32 = 384.0; +const FRONT_STARFIELD_SIZE: f32 = 512.0; pub fn starfield_plugin(app: &mut App) { app @@ -18,10 +20,11 @@ pub fn setup_starfield( window: Query<&Window> ) { let starfield_handle = asset_server.load("textures/starfield.png"); + let starfield_transp_handle = asset_server.load("textures/starfield_transp.png"); let window = window.iter().next().unwrap(); commands.spawn(Sprite { image: starfield_handle, - custom_size: Some(window.size() + Vec2::splat(STARFIELD_SIZE)), + custom_size: Some(window.size() + Vec2::splat(BACK_STARFIELD_SIZE)), image_mode: SpriteImageMode::Tiled { tile_x: true, tile_y: true, @@ -29,24 +32,68 @@ pub fn setup_starfield( }, ..Default::default() }) - .insert(Transform::from_xyz(0.0, 0.0, 0.0)) + .insert(Transform::from_xyz(0.0, 0.0, 5.0)) + .insert(StarfieldBack); + commands.spawn(Sprite { + image: starfield_transp_handle.clone(), + custom_size: Some(window.size() + Vec2::splat(MID_STARFIELD_SIZE)), + image_mode: SpriteImageMode::Tiled { + tile_x: true, + tile_y: true, + stretch_value: 1.0, + }, + ..Default::default() + }) + .insert(Transform::from_xyz(0.0, 0.0, 4.5)) + .insert(StarfieldMid); + commands.spawn(Sprite { + image: starfield_transp_handle, + custom_size: Some(window.size() + Vec2::splat(FRONT_STARFIELD_SIZE)), + image_mode: SpriteImageMode::Tiled { + tile_x: true, + tile_y: true, + stretch_value: 1.0, + }, + ..Default::default() + }) + .insert(Transform::from_xyz(0.0, 0.0, 4.0)) .insert(StarfieldFront); } pub fn fix_starfield( - mut starfield_front: Query<&mut Sprite, With>, + mut starfield_back: Query<&mut Sprite, (With, Without, Without)>, + mut starfield_mid: Query<&mut Sprite, (With, Without, Without)>, + mut starfield_front: Query<&mut Sprite, (With, Without, Without)>, assets: Res>, mut asset_events: EventReader>, ) { for event in asset_events.read() { if let AssetEvent::Added { id } = event { + let mut starfield_back = starfield_back.single_mut().unwrap(); + if *id == starfield_back.image.id() { + let starfield_image = assets.get(*id).unwrap(); + starfield_back.image_mode = SpriteImageMode::Tiled { + tile_x: true, + tile_y: true, + stretch_value: BACK_STARFIELD_SIZE / (starfield_image.size().x as f32), + }; + } + let mut starfield_mid = starfield_mid.single_mut().unwrap(); + if *id == starfield_mid.image.id() { + let starfield_image = assets.get(*id).unwrap(); + starfield_mid.image_mode = SpriteImageMode::Tiled { + tile_x: true, + tile_y: true, + stretch_value: MID_STARFIELD_SIZE / (starfield_image.size().x as f32), + }; + } let mut starfield_front = starfield_front.single_mut().unwrap(); if *id == starfield_front.image.id() { let starfield_image = assets.get(*id).unwrap(); starfield_front.image_mode = SpriteImageMode::Tiled { tile_x: true, tile_y: true, - stretch_value: STARFIELD_SIZE / (starfield_image.size().x as f32), + stretch_value: FRONT_STARFIELD_SIZE / (starfield_image.size().x as f32), }; } } @@ -54,20 +101,39 @@ pub fn fix_starfield( } pub fn resize_starfield( - mut starfield_front: Query<&mut Sprite, With>, + mut starfield_back: Query<&mut Sprite, (With, Without, Without)>, + mut starfield_mid: Query<&mut Sprite, (With, Without, Without)>, + mut starfield_front: Query<&mut Sprite, (With, Without, Without)>, mut resize_event: EventReader, ) { for event in resize_event.read() { + starfield_back.single_mut().unwrap().custom_size = + Some(Vec2::new(event.width, event.height) + Vec2::splat(BACK_STARFIELD_SIZE*2.0)); + starfield_mid.single_mut().unwrap().custom_size = + Some(Vec2::new(event.width, event.height) + Vec2::splat(MID_STARFIELD_SIZE*2.0)); starfield_front.single_mut().unwrap().custom_size = - Some(Vec2::new(event.width, event.height) + Vec2::splat(STARFIELD_SIZE)); + Some(Vec2::new(event.width, event.height) + Vec2::splat(FRONT_STARFIELD_SIZE*2.0)); } } pub fn update_starfield( - mut starfield: Query<&mut Transform, (With, Without)>, + mut starfield_back: Query<&mut Transform, (With, Without, Without, Without)>, + mut starfield_mid: Query<&mut Transform, (With, Without, Without, Without)>, + mut starfield_front: Query<&mut Transform, (With, Without, Without, Without)>, player: Query<&Transform, (With, Without)>, ) { let Some(player) = player.iter().next() else { return }; - let mut starfield_pos = starfield.single_mut().unwrap(); - starfield_pos.translation = (player.translation / STARFIELD_SIZE).round() * STARFIELD_SIZE; + let mut starfield_back_pos = starfield_back.single_mut().unwrap(); + let mut starfield_mid_pos = starfield_mid.single_mut().unwrap(); + let mut starfield_front_pos = starfield_front.single_mut().unwrap(); + //starfield_pos.translation = (player.translation / STARFIELD_SIZE).round() * STARFIELD_SIZE; + starfield_back_pos.translation = player.translation + + (-player.translation/3.0) % BACK_STARFIELD_SIZE + - Vec3::new(0.0, 0.0, 5.0); + starfield_mid_pos.translation = player.translation + + (-player.translation/2.5) % MID_STARFIELD_SIZE + - Vec3::new(0.0, 0.0, 4.5); + starfield_front_pos.translation = player.translation + + (-player.translation/2.0) % FRONT_STARFIELD_SIZE + - Vec3::new(0.0, 0.0, 4.0); } diff --git a/crates/unified/src/ecs.rs b/crates/unified/src/ecs.rs index 51a115afdc8e9afdbcc92011a681be5792ecd521..9b5a46f72bac48d7d486ee3ab81b23d98b88efe4 100644 --- a/crates/unified/src/ecs.rs +++ b/crates/unified/src/ecs.rs @@ -16,6 +16,8 @@ pub struct MainCamera; #[derive(Component)] pub struct StarfieldFront; #[derive(Component)] +pub struct StarfieldMid; +#[derive(Component)] pub struct StarfieldBack; #[derive(Resource, Default)] pub struct CursorWorldCoordinates(pub Option);