From a2e0d5195f4ee1cf9b5f0f042502b6add8914a09 Mon Sep 17 00:00:00 2001 From: ghostly_zsh Date: Wed, 2 Jul 2025 14:12:15 -0500 Subject: [PATCH] starfield exists --- crates/unified/src/client/mod.rs | 9 +++- crates/unified/src/client/starfield.rs | 73 ++++++++++++++++++++++++++ crates/unified/src/ecs.rs | 4 ++ 3 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 crates/unified/src/client/starfield.rs diff --git a/crates/unified/src/client/mod.rs b/crates/unified/src/client/mod.rs index 37b15ff89b31324e52cf703c2e7fd9a40774ba82..357fa1149d3add5b7198a5d8292617579cfca07d 100644 --- a/crates/unified/src/client/mod.rs +++ b/crates/unified/src/client/mod.rs @@ -1,6 +1,7 @@ mod incoming_planets; mod incoming_parts; mod key_input; +mod starfield; use std::net::{SocketAddr, UdpSocket}; use std::time::SystemTime; @@ -15,6 +16,7 @@ use bevy_replicon_renet2::RenetChannelsExt; use crate::client::incoming_parts::incoming_parts_plugin; use crate::client::incoming_planets::incoming_planets_plugin; use crate::client::key_input::key_input_plugin; +use crate::client::starfield::starfield_plugin; use crate::ecs::{Ball, CursorWorldCoordinates, Ground, MainCamera, Player, SendBallHere}; pub struct ClientPlugin { @@ -53,7 +55,8 @@ impl Plugin for ClientPlugin { .add_systems(Update, find_me) .add_plugins(incoming_planets_plugin) .add_plugins(incoming_parts_plugin) - .add_plugins(key_input_plugin); + .add_plugins(key_input_plugin) + .add_plugins(starfield_plugin); } } @@ -74,6 +77,10 @@ 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 new file mode 100644 index 0000000000000000000000000000000000000000..b58c422a43bfd6efd142502697e9fe1d0111d080 --- /dev/null +++ b/crates/unified/src/client/starfield.rs @@ -0,0 +1,73 @@ +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 crate::{client::Me, ecs::StarfieldFront}; + +const STARFIELD_SIZE: f32 = 512.0; + +pub fn starfield_plugin(app: &mut App) { + app + .add_systems(Startup, setup_starfield) + .add_systems(Update, fix_starfield) + .add_systems(Update, resize_starfield) + .add_systems(Update, update_starfield); +} + +pub fn setup_starfield( + mut commands: Commands, + asset_server: Res, + window: Query<&Window> +) { + let starfield_handle = asset_server.load("textures/starfield.png"); + let window = window.iter().next().unwrap(); + commands.spawn(Sprite { + image: starfield_handle, + custom_size: Some(window.size() + Vec2::splat(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, 0.0)) + .insert(StarfieldFront); +} + +pub fn fix_starfield( + mut starfield_front: Query<&mut Sprite, With>, + assets: Res>, + mut asset_events: EventReader>, +) { + for event in asset_events.read() { + if let AssetEvent::Added { id } = event { + 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), + }; + } + } + } +} + +pub fn resize_starfield( + mut starfield_front: Query<&mut Sprite, With>, + mut resize_event: EventReader, +) { + for event in resize_event.read() { + starfield_front.single_mut().unwrap().custom_size = + Some(Vec2::new(event.width, event.height) + Vec2::splat(STARFIELD_SIZE)); + } +} + +pub fn update_starfield( + mut starfield: Query<&mut Transform, (With, 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; +} diff --git a/crates/unified/src/ecs.rs b/crates/unified/src/ecs.rs index 07c1b1c18c8895e979941e5a874219314bd4a957..51a115afdc8e9afdbcc92011a681be5792ecd521 100644 --- a/crates/unified/src/ecs.rs +++ b/crates/unified/src/ecs.rs @@ -13,6 +13,10 @@ pub struct Ball; pub struct Ground; #[derive(Component)] pub struct MainCamera; +#[derive(Component)] +pub struct StarfieldFront; +#[derive(Component)] +pub struct StarfieldBack; #[derive(Resource, Default)] pub struct CursorWorldCoordinates(pub Option);