forked from btrepp/bevy-prototype-parallax
-
Notifications
You must be signed in to change notification settings - Fork 0
/
forest.rs
152 lines (141 loc) · 5.17 KB
/
forest.rs
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
use std::f32::consts::PI;
use bevy::{prelude::*, render::camera::Camera};
use bevy_prototype_parallax::{Layer, LayerBundle, ParallaxPlugin, WindowSize};
struct Player {
pub run: Handle<TextureAtlas>,
pub idle: Handle<TextureAtlas>,
}
fn main() {
let window = WindowDescriptor {
title: "Forrest".to_string(),
width: 1280.0,
height: 720.0,
vsync: true,
resizable: false,
..Default::default()
};
App::build()
.insert_resource(window)
.add_plugins(DefaultPlugins)
.add_startup_system(setup_parallax.system())
.add_startup_system(setup_character.system())
.add_system(move_character_system.system())
.add_system(follow_player_camera.system())
.add_system(animate_sprite_system.system())
.add_plugin(ParallaxPlugin)
.run();
}
/// Set up our background layers
fn setup_parallax(
mut commands: Commands,
asset_server: Res<AssetServer>,
mut materials: ResMut<Assets<ColorMaterial>>,
) {
// Helper that loads an asset as a parallax layer
// layers should have different speeds to achieve the effect
let mut layer = |path: &str, speed: f32| -> LayerBundle {
let handle = {
let handle = asset_server.load(path);
let color = materials.add(handle.into());
color
};
LayerBundle {
layer: Layer {
speed: speed,
..Default::default()
},
material: handle,
transform: Transform {
scale: Vec3::new(4.0, 4.5, 1.0),
translation: Vec3::new(0.0, 0.0, 0.0),
..Default::default()
},
..Default::default()
}
};
// Note the backgrounds are associated with a camera.
commands
.spawn_bundle(OrthographicCameraBundle::new_2d())
.insert(WindowSize::default())
.with_children(|cb| {
// Spawn the layers.
// We can have as many as we like
cb.spawn_bundle(layer("parallax-forest-back-trees.png", 0.0));
cb.spawn_bundle(layer("parallax-forest-lights.png", 0.05));
cb.spawn_bundle(layer("parallax-forest-middle-trees.png", 0.1));
cb.spawn_bundle(layer("parallax-forest-front-trees.png", 0.2));
});
}
/// Spawns our character and loads it's resources
fn setup_character(
mut commands: Commands,
asset_server: Res<AssetServer>,
mut texture_atlases: ResMut<Assets<TextureAtlas>>,
) {
let player = {
let texture_handle_run = asset_server.load("Run.png");
let texture_atlas_run =
TextureAtlas::from_grid(texture_handle_run, Vec2::new(24.0, 24.0), 8, 1);
let texture_handle_idle = asset_server.load("Idle.png");
let texture_atlas_idle =
TextureAtlas::from_grid(texture_handle_idle, Vec2::new(24.0, 24.0), 8, 1);
let run = texture_atlases.add(texture_atlas_run);
let idle = texture_atlases.add(texture_atlas_idle);
Player { run, idle }
};
commands
.spawn_bundle(SpriteSheetBundle {
texture_atlas: player.idle.clone(),
transform: Transform {
scale: Vec3::new(25.0, 25.0, 1.0),
translation: Vec3::new(0.0, -220.0, 1.0),
..Default::default()
},
..Default::default()
})
.insert(Timer::from_seconds(0.1, true))
.insert(player);
}
/// From bevy examples, will animate the sprites in an atlas
fn animate_sprite_system(
texture_atlases: Res<Assets<TextureAtlas>>,
time: Res<Time>,
mut query: Query<(&mut Timer, &mut TextureAtlasSprite, &Handle<TextureAtlas>)>,
) {
for (mut timer, mut sprite, texture_atlas_handle) in query.iter_mut() {
if timer.tick(time.delta()).finished() {
let texture_atlas = texture_atlases.get(texture_atlas_handle).unwrap();
sprite.index = ((sprite.index as usize + 1) % texture_atlas.textures.len()) as u32;
}
}
}
/// Moves the character and sets the appropriate atlas for animation
fn move_character_system(
keyboard_input: Res<Input<KeyCode>>,
mut query: Query<(&Player, &mut Transform, &mut Handle<TextureAtlas>)>,
) {
for (player, mut transform, mut atlas) in query.iter_mut() {
if keyboard_input.pressed(KeyCode::A) {
transform.translation.x += -1.0 * 5.0;
transform.rotation = Quat::from_rotation_y(PI).into();
*atlas = player.run.clone();
} else if keyboard_input.pressed(KeyCode::D) {
transform.translation.x += 1.0 * 5.0;
transform.rotation = Quat::from_rotation_y(0.0).into();
*atlas = player.run.clone();
} else {
*atlas = player.idle.clone();
}
}
}
/// A simple system that will cause the camera to follow the character
fn follow_player_camera(
player: Query<&Transform, (With<Player>, Without<Camera>)>,
mut camera: Query<&mut Transform, (With<Camera>, Without<Player>)>,
) {
if let Some(first_player) = player.iter().next() {
for mut transform in camera.iter_mut() {
transform.translation.x = first_player.translation.x;
}
}
}