~starkingdoms/starkingdoms

ref: a2e0d5195f4ee1cf9b5f0f042502b6add8914a09 starkingdoms/crates/unified/src/client/starfield.rs -rw-r--r-- 2.7 KiB
a2e0d519 — ghostly_zsh starfield exists 5 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
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<AssetServer>,
    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<StarfieldFront>>,
    assets: Res<Assets<Image>>,
    mut asset_events: EventReader<AssetEvent<Image>>,
) {
    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<StarfieldFront>>,
    mut resize_event: EventReader<WindowResized>,
) {
    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<StarfieldFront>, Without<Me>)>,
    player: Query<&Transform, (With<Me>, Without<StarfieldFront>)>,
) {
    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;
}