From 6a550cfcb84ab93ec7fcdcf551b8dd97a2f79ad2 Mon Sep 17 00:00:00 2001 From: TudbuT Date: Sun, 24 Nov 2024 05:48:56 +0100 Subject: [PATCH] parallax!!!!!! --- assets/world.txt | 22 ++++++++++++ src/game/scene.rs | 25 ++++++++++++++ src/main.rs | 2 ++ src/parallax.rs | 88 ++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 136 insertions(+), 1 deletion(-) diff --git a/assets/world.txt b/assets/world.txt index 58e7a24..a714bb6 100644 --- a/assets/world.txt +++ b/assets/world.txt @@ -1,4 +1,26 @@ header + parallax.size = 2000x1000 + parallax.tiles = 2 + parallax.factor.y = 100000 + parallax.tex = BG0_himmel_blau.png + parallax.factor = 30 + parallax.depth = 10 + parallax.offset = -200 + parallax.enable = true + parallax.tex = BG1_Berge_blau.png + parallax.factor = 10 + parallax.depth = 9 + parallax.enable = true + parallax.tex = BG2_Berge_gau.png + parallax.factor = 8 + parallax.depth = 8 + parallax.offset = -350 + parallax.enable = true + parallax.tex = BG3_Berge_gruen.png + parallax.factor = 6 + parallax.depth = 7 + parallax.offset = 100 + parallax.enable = true block-size = 60 .P = [player] .S = [spawn] diff --git a/src/game/scene.rs b/src/game/scene.rs index 2b0291b..d806cde 100644 --- a/src/game/scene.rs +++ b/src/game/scene.rs @@ -9,6 +9,7 @@ use bevy_rapier2d::prelude::{Collider, *}; use readformat::{readf, readf1}; use crate::game::WORLD_DEPTH; +use crate::parallax::{parallax, Parallax}; use crate::AppState; use super::player::PlayerSpawnOneshot; @@ -77,6 +78,7 @@ pub(super) fn import_text_world( }; let mut wi = WorldInfo::default(); + let mut parallax_info = Parallax::default(); for line in info_string.lines() { let [name, val] = &readf(" {} = {}", line).expect("invalid line in info section")[..] else { @@ -85,6 +87,29 @@ pub(super) fn import_text_world( match name.as_str() { "block-size" => wi.block_size = val.parse().unwrap(), + "parallax.offset" => parallax_info.offset = val.parse().unwrap(), + "parallax.size" => { + parallax_info.size = { + let x = readf("{}x{}", val).unwrap(); + Vec2::new(x[0].parse().unwrap(), x[1].parse().unwrap()) + } + } + "parallax.tiles" => parallax_info.tiles = val.parse().unwrap(), + "parallax.tex" => parallax_info.tex = val.clone(), + "parallax.factor" => parallax_info.factor = val.parse().unwrap(), + "parallax.factor.y" => parallax_info.y_factor = val.parse().unwrap(), + "parallax.depth" => parallax_info.depth = val.parse().unwrap(), + "parallax.enable" => { + if val == "true" { + parallax( + &mut commands, + &mut materials, + &mut meshes, + &assets, + parallax_info.clone(), + ) + } + } x if x.starts_with(".") => { let x = readf1(".{}", x).unwrap(); wi.blocks.push((x, val.to_owned())); diff --git a/src/main.rs b/src/main.rs index 7c3df87..a0baa63 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,7 @@ use bevy::prelude::*; use bevy_rapier2d::prelude::*; use game::game_plugin; +use parallax::parallax_plugin; mod game; mod parallax; @@ -42,6 +43,7 @@ fn main() { //.add_plugins(RapierDebugRenderPlugin::default()) .add_systems(Startup, setup_camera) .add_plugins(game_plugin) + .add_plugins(parallax_plugin) .init_state::() .init_state::() .insert_state(AppState::InGame) // TODO dont diff --git a/src/parallax.rs b/src/parallax.rs index 26a6fc8..6dcb1a7 100644 --- a/src/parallax.rs +++ b/src/parallax.rs @@ -1 +1,87 @@ -use bevy::prelude::*; +use bevy::{ + prelude::*, + render::{ + primitives::Aabb, + view::{NoFrustumCulling, VisibilitySystems}, + }, + sprite::MaterialMesh2dBundle, +}; +use bevy_rapier2d::parry::simba::scalar::SupersetOf; + +#[derive(Component)] +pub struct ParallaxTile(usize); + +#[derive(Component, Clone)] +pub struct Parallax { + pub offset: f32, + pub factor: f32, + pub y_factor: f32, + pub size: Vec2, + pub depth: f32, + pub tiles: usize, + pub tex: String, +} + +impl Default for Parallax { + fn default() -> Self { + Self { + offset: 0., + factor: 10., + y_factor: 10., + size: Vec2::new(2000., 1000.), + depth: 100., + tiles: 4, + tex: "".to_owned(), + } + } +} + +pub fn parallax_plugin(app: &mut App) { + app.add_systems(Update, (update_parallax,)); +} + +pub fn parallax( + commands: &mut Commands, + materials: &mut ResMut>, + meshes: &mut ResMut>, + assets: &Res, + parallax_info: Parallax, +) { + for i in 0..parallax_info.tiles { + commands.spawn(( + ParallaxTile(i), + parallax_info.clone(), + MaterialMesh2dBundle { + mesh: meshes.add(Rectangle::from_size(parallax_info.size)).into(), + material: materials.add(assets.load(parallax_info.tex.clone())), + transform: Transform::from_xyz(0.0, 0.0, -parallax_info.depth), + visibility: Visibility::Visible, + ..Default::default() + }, + NoFrustumCulling, + )); + } +} + +fn update_parallax( + mut commands: Commands, + mut query: Query<(Entity, &Parallax, &ParallaxTile, &mut Transform)>, + camera_query: Query<(&Camera2d, &Transform), (Without)>, +) { + let (_, cam_transform) = camera_query.single(); + let cam_transform = cam_transform.translation; + for (entity, parallax_info, ParallaxTile(tile), mut transform) in query.iter_mut() { + let position_on_parallax = cam_transform.xy() + - Vec2::new( + cam_transform.x / parallax_info.factor, + cam_transform.y / parallax_info.y_factor, + ); + let first_parallax_on_cam = + (position_on_parallax / parallax_info.size).floor() * parallax_info.size; + let position = first_parallax_on_cam + + Vec2::new(*tile as f32, 0.) * parallax_info.size + + position_on_parallax % parallax_info.size; + transform.translation = + position.extend(-parallax_info.depth) + Vec3::new(0., parallax_info.offset, 0.); + } +}