Latest commit ffecb05
use bevy::{prelude::*, tasks::prelude::*}; use rand::random; #[derive(Component)] struct Velocity(Vec2); fn spawn_system( mut commands: Commands, asset_server: Res<AssetServer>, ) { commands.spawn_bundle(OrthographicCameraBundle::new_2d()); let image_handle = asset_server.load("branding/icon.png"); for _ in 0..128 { commands .spawn_bundle(SpriteBundle { texture: image_handle.clone(), transform: Transform::from_scale(Vec3::splat(0.1)), ..Default::default() }) .insert(Velocity( 20.0 * Vec2::new(random::<f32>() - 0.5, random::<f32>() - 0.5), )); } } // 根据sprite的速度来移动它们 fn move_system( pool: Res<ComputeTaskPool>, mut sprites: Query<(&mut Transform, &Velocity)>, ) { // 使用批处理的32个Sprite在ComputeTaskPool上并行计算每个Sprite的新位置 // 这个例子仅用于演示,究竟是使用ParallelIterator还是Iterator,查看ParallelIterator文档 sprites.par_for_each_mut(&pool, 32, |(mut transform, velocity)| { transform.translation += velocity.0.extend(0.0); }); } // 窗口外弹出sprite fn bounce_system( pool: Res<ComputeTaskPool>, windows: Res<Windows>, mut sprites: Query<(&Transform, &mut Velocity)>, ) { let window = windows.get_primary().expect("No primary window."); let width = window.width(); let height = window.height(); let left = width / -2.0; let right = width - 2.0; let bottom = height / -2.0; let top = height / 2.0; sprites // 选择批处理大小为32,以限制ParallelIterator的开销,因为取反向量非常便宜 .par_for_each_mut(&pool, 32, |(transform, mut v)| { if !(left < transform.translation.x && transform.translation.x < right && bottom < transform.translation.y && transform.translation.y < top) { // 为简单起见,只需将速度反过来即可,不要用现实中的弹跳方式 v.0 = -v.0; } }); } /// 用ParallelIterator来说明如何并行查询 fn main() { App::new() .add_plugin(DefaultPlugins) .add_startup_system(spawn_system) .add_system(move_system) .add_system(bounce_system) .run(); }