├── .gitignore ├── .rusty-hook.toml ├── Cargo.toml ├── README.md ├── assets ├── Idle.png ├── Run.png ├── demo.gif ├── parallax-forest-back-trees.png ├── parallax-forest-front-trees.png ├── parallax-forest-lights.png └── parallax-forest-middle-trees.png ├── credits.txt ├── examples └── forest.rs └── src ├── layer.rs ├── lib.rs └── window_size.rs /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | Cargo.lock 3 | -------------------------------------------------------------------------------- /.rusty-hook.toml: -------------------------------------------------------------------------------- 1 | [hooks] 2 | pre-commit = "cargo fmt -- --check" 3 | 4 | [logging] 5 | verbose = true 6 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "bevy-prototype-parallax" 3 | version = "0.1.0" 4 | authors = ["beau trepp "] 5 | edition = "2018" 6 | description = "Parallax scrolling plugin for bevy" 7 | keywords = ["gamedev", "bevy", "bevy-prototype"] 8 | readme = "README.md" 9 | license = "MIT" 10 | 11 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 12 | 13 | [dependencies] 14 | bevy = "0.5.0" 15 | 16 | [dev-dependencies] 17 | rstest = "0.6.4" 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # bevy-prototype-parallax 2 | 3 | A simple parallax component for the bevy engine. 4 | 5 | This will allow you to quickly have a scrolling parralax style background. 6 | It should also be useable to have a simple scrolling background too. 7 | 8 | It does assume your image repeats nicely infinitely 9 | 10 | ![Demo](assets/demo.gif) 11 | 12 | # Usage 13 | 14 | ```rust 15 | 16 | App::build() 17 | .... 18 | .add_plugin(ParallaxPlugin) 19 | 20 | .... 21 | let handle = /*load your colormaterial */ 22 | 23 | commands 24 | .spawn(Camera2dComponents::default()) 25 | .with(WindowSize::default()) 26 | .with_children(|cb| { 27 | // Spawn the layers. 28 | // We can have as many as we like 29 | cb.spawn(LayerComponents { 30 | layer: Layer { 31 | speed: speed, 32 | }, 33 | material: handle, 34 | ..Default::default() 35 | }); 36 | ``` 37 | 38 | Make sure your camera has a window size component. 39 | This will enable a system that allows, the window size to be known, which allows the plugin to 40 | determine how many times to repeat the image. 41 | 42 | Then make sure your layer uses this camera as it's parent element. This allows it so shift 43 | itself depending on how much the camera is offset. Different speeds off different layers will 44 | achieve a repeating effect, a speed of 0 will make the layer static, a speed of 1.0 will 45 | make it move linearly with the camera. 46 | 47 | The sprite components are managed automatically by the layer system, it will only spawn as many 48 | as needed to fill the screen. 49 | 50 | Note: doesn't support resizing yet. 51 | Note: only horizontal for now. 52 | 53 | -------------------------------------------------------------------------------- /assets/Idle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/btrepp/bevy-prototype-parallax/c2838605548815c80e821fb8f8457e76d00e2d39/assets/Idle.png -------------------------------------------------------------------------------- /assets/Run.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/btrepp/bevy-prototype-parallax/c2838605548815c80e821fb8f8457e76d00e2d39/assets/Run.png -------------------------------------------------------------------------------- /assets/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/btrepp/bevy-prototype-parallax/c2838605548815c80e821fb8f8457e76d00e2d39/assets/demo.gif -------------------------------------------------------------------------------- /assets/parallax-forest-back-trees.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/btrepp/bevy-prototype-parallax/c2838605548815c80e821fb8f8457e76d00e2d39/assets/parallax-forest-back-trees.png -------------------------------------------------------------------------------- /assets/parallax-forest-front-trees.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/btrepp/bevy-prototype-parallax/c2838605548815c80e821fb8f8457e76d00e2d39/assets/parallax-forest-front-trees.png -------------------------------------------------------------------------------- /assets/parallax-forest-lights.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/btrepp/bevy-prototype-parallax/c2838605548815c80e821fb8f8457e76d00e2d39/assets/parallax-forest-lights.png -------------------------------------------------------------------------------- /assets/parallax-forest-middle-trees.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/btrepp/bevy-prototype-parallax/c2838605548815c80e821fb8f8457e76d00e2d39/assets/parallax-forest-middle-trees.png -------------------------------------------------------------------------------- /credits.txt: -------------------------------------------------------------------------------- 1 | ansimuz https://ansimuz.itch.io/parallax-forest 2 | LuizMelo https://luizmelo.itch.io/huntress -------------------------------------------------------------------------------- /examples/forest.rs: -------------------------------------------------------------------------------- 1 | use std::f32::consts::PI; 2 | 3 | use bevy::{prelude::*, render::camera::Camera}; 4 | use bevy_prototype_parallax::{Layer, LayerBundle, ParallaxPlugin, WindowSize}; 5 | 6 | struct Player { 7 | pub run: Handle, 8 | pub idle: Handle, 9 | } 10 | 11 | fn main() { 12 | let window = WindowDescriptor { 13 | title: "Forrest".to_string(), 14 | width: 1280.0, 15 | height: 720.0, 16 | vsync: true, 17 | resizable: false, 18 | ..Default::default() 19 | }; 20 | 21 | App::build() 22 | .insert_resource(window) 23 | .add_plugins(DefaultPlugins) 24 | .add_startup_system(setup_parallax.system()) 25 | .add_startup_system(setup_character.system()) 26 | .add_system(move_character_system.system()) 27 | .add_system(follow_player_camera.system()) 28 | .add_system(animate_sprite_system.system()) 29 | .add_plugin(ParallaxPlugin) 30 | .run(); 31 | } 32 | 33 | /// Set up our background layers 34 | fn setup_parallax( 35 | mut commands: Commands, 36 | asset_server: Res, 37 | mut materials: ResMut>, 38 | ) { 39 | // Helper that loads an asset as a parallax layer 40 | // layers should have different speeds to achieve the effect 41 | let mut layer = |path: &str, speed: f32| -> LayerBundle { 42 | let handle = { 43 | let handle = asset_server.load(path); 44 | let color = materials.add(handle.into()); 45 | color 46 | }; 47 | LayerBundle { 48 | layer: Layer { 49 | speed: speed, 50 | ..Default::default() 51 | }, 52 | material: handle, 53 | transform: Transform { 54 | scale: Vec3::new(4.0, 4.5, 1.0), 55 | translation: Vec3::new(0.0, 0.0, 0.0), 56 | ..Default::default() 57 | }, 58 | ..Default::default() 59 | } 60 | }; 61 | 62 | // Note the backgrounds are associated with a camera. 63 | commands 64 | .spawn_bundle(OrthographicCameraBundle::new_2d()) 65 | .insert(WindowSize::default()) 66 | .with_children(|cb| { 67 | // Spawn the layers. 68 | // We can have as many as we like 69 | cb.spawn_bundle(layer("parallax-forest-back-trees.png", 0.0)); 70 | cb.spawn_bundle(layer("parallax-forest-lights.png", 0.05)); 71 | cb.spawn_bundle(layer("parallax-forest-middle-trees.png", 0.1)); 72 | cb.spawn_bundle(layer("parallax-forest-front-trees.png", 0.2)); 73 | }); 74 | } 75 | 76 | /// Spawns our character and loads it's resources 77 | fn setup_character( 78 | mut commands: Commands, 79 | asset_server: Res, 80 | mut texture_atlases: ResMut>, 81 | ) { 82 | let player = { 83 | let texture_handle_run = asset_server.load("Run.png"); 84 | let texture_atlas_run = 85 | TextureAtlas::from_grid(texture_handle_run, Vec2::new(24.0, 24.0), 8, 1); 86 | let texture_handle_idle = asset_server.load("Idle.png"); 87 | let texture_atlas_idle = 88 | TextureAtlas::from_grid(texture_handle_idle, Vec2::new(24.0, 24.0), 8, 1); 89 | let run = texture_atlases.add(texture_atlas_run); 90 | let idle = texture_atlases.add(texture_atlas_idle); 91 | Player { run, idle } 92 | }; 93 | 94 | commands 95 | .spawn_bundle(SpriteSheetBundle { 96 | texture_atlas: player.idle.clone(), 97 | transform: Transform { 98 | scale: Vec3::new(25.0, 25.0, 1.0), 99 | translation: Vec3::new(0.0, -220.0, 1.0), 100 | ..Default::default() 101 | }, 102 | ..Default::default() 103 | }) 104 | .insert(Timer::from_seconds(0.1, true)) 105 | .insert(player); 106 | } 107 | 108 | /// From bevy examples, will animate the sprites in an atlas 109 | fn animate_sprite_system( 110 | texture_atlases: Res>, 111 | time: Res