2020-09-08 19:18:32 +00:00
|
|
|
use bevy::{prelude::*, tasks::prelude::*};
|
|
|
|
use rand::random;
|
|
|
|
|
|
|
|
struct Velocity(Vec2);
|
|
|
|
|
|
|
|
fn spawn_system(
|
2020-11-08 20:34:05 +00:00
|
|
|
commands: &mut Commands,
|
2020-09-08 19:18:32 +00:00
|
|
|
asset_server: Res<AssetServer>,
|
|
|
|
mut materials: ResMut<Assets<ColorMaterial>>,
|
|
|
|
) {
|
2020-11-16 04:32:23 +00:00
|
|
|
commands.spawn(Camera2dBundle::default());
|
2020-10-18 20:48:15 +00:00
|
|
|
let texture_handle = asset_server.load("branding/icon.png");
|
2020-09-08 19:18:32 +00:00
|
|
|
let material = materials.add(texture_handle.into());
|
|
|
|
for _ in 0..128 {
|
|
|
|
commands
|
2020-11-16 04:32:23 +00:00
|
|
|
.spawn(SpriteBundle {
|
2020-10-18 20:48:15 +00:00
|
|
|
material: material.clone(),
|
2020-10-18 20:03:16 +00:00
|
|
|
transform: Transform::from_scale(Vec3::splat(0.1)),
|
2020-09-08 19:18:32 +00:00
|
|
|
..Default::default()
|
|
|
|
})
|
|
|
|
.with(Velocity(
|
|
|
|
20.0 * Vec2::new(random::<f32>() - 0.5, random::<f32>() - 0.5),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Move sprites according to their velocity
|
2020-09-14 21:00:32 +00:00
|
|
|
fn move_system(pool: Res<ComputeTaskPool>, mut sprites: Query<(&mut Transform, &Velocity)>) {
|
2020-09-08 19:18:32 +00:00
|
|
|
// Compute the new location of each sprite in parallel on the
|
2020-11-03 18:41:31 +00:00
|
|
|
// ComputeTaskPool using batches of 32 sprites
|
2020-09-08 19:18:32 +00:00
|
|
|
//
|
|
|
|
// This example is only for demonstrative purposes. Using a
|
|
|
|
// ParallelIterator for an inexpensive operation like addition on only 128
|
|
|
|
// elements will not typically be faster than just using a normal Iterator.
|
|
|
|
// See the ParallelIterator documentation for more information on when
|
|
|
|
// to use or not use ParallelIterator over a normal Iterator.
|
2020-09-14 21:00:32 +00:00
|
|
|
sprites
|
2020-10-30 06:39:55 +00:00
|
|
|
.par_iter_mut(32)
|
2020-09-14 21:00:32 +00:00
|
|
|
.for_each(&pool, |(mut transform, velocity)| {
|
2020-10-18 20:03:16 +00:00
|
|
|
transform.translation += velocity.0.extend(0.0);
|
2020-09-14 21:00:32 +00:00
|
|
|
});
|
2020-09-08 19:18:32 +00:00
|
|
|
}
|
|
|
|
|
2020-11-03 18:41:31 +00:00
|
|
|
// Bounce sprites outside the window
|
2020-09-08 19:18:32 +00:00
|
|
|
fn bounce_system(
|
|
|
|
pool: Res<ComputeTaskPool>,
|
|
|
|
windows: Res<Windows>,
|
2020-09-14 21:00:32 +00:00
|
|
|
mut sprites: Query<(&Transform, &mut Velocity)>,
|
2020-09-08 19:18:32 +00:00
|
|
|
) {
|
2020-12-02 19:31:16 +00:00
|
|
|
let window = windows.get_primary().expect("No primary window.");
|
2020-12-13 23:05:56 +00:00
|
|
|
let width = window.width();
|
|
|
|
let height = window.height();
|
2020-12-07 21:32:57 +00:00
|
|
|
let left = width / -2.0;
|
|
|
|
let right = width / 2.0;
|
|
|
|
let bottom = height / -2.0;
|
|
|
|
let top = height / 2.0;
|
2020-09-08 19:18:32 +00:00
|
|
|
sprites
|
|
|
|
// Batch size of 32 is chosen to limit the overhead of
|
|
|
|
// ParallelIterator, since negating a vector is very inexpensive.
|
2020-10-30 06:39:55 +00:00
|
|
|
.par_iter_mut(32)
|
2020-09-08 19:18:32 +00:00
|
|
|
// Filter out sprites that don't need to be bounced
|
2020-09-14 21:00:32 +00:00
|
|
|
.filter(|(transform, _)| {
|
2020-11-17 21:40:18 +00:00
|
|
|
!(left < transform.translation.x
|
|
|
|
&& transform.translation.x < right
|
|
|
|
&& bottom < transform.translation.y
|
|
|
|
&& transform.translation.y < top)
|
2020-09-14 21:00:32 +00:00
|
|
|
})
|
2020-09-08 19:18:32 +00:00
|
|
|
// For simplicity, just reverse the velocity; don't use realistic bounces
|
|
|
|
.for_each(&pool, |(_, mut v)| {
|
|
|
|
v.0 = -v.0;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
App::build()
|
2020-11-03 03:01:17 +00:00
|
|
|
.add_plugins(DefaultPlugins)
|
2020-12-16 05:57:16 +00:00
|
|
|
.add_startup_system(spawn_system.system())
|
|
|
|
.add_system(move_system.system())
|
|
|
|
.add_system(bounce_system.system())
|
2020-09-08 19:18:32 +00:00
|
|
|
.run();
|
|
|
|
}
|