forked from bevyengine/bevy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
many_sprites.rs
119 lines (99 loc) · 3.8 KB
/
many_sprites.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
//! Renders a lot of sprites to allow performance testing.
//! See <https://github.com/bevyengine/bevy/pull/1492>
//!
//! It sets up many sprites in different sizes and rotations, and at different scales in the world,
//! and moves the camera over them to see how well frustum culling works.
//!
//! Add the `--colored` arg to run with color tinted sprites. This will cause the sprites to be rendered
//! in multiple batches, reducing performance but useful for testing.
use bevy::{
diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin},
prelude::*,
window::PresentMode,
};
use rand::Rng;
const CAMERA_SPEED: f32 = 1000.0;
const COLORS: [Color; 3] = [Color::BLUE, Color::WHITE, Color::RED];
#[derive(Resource)]
struct ColorTint(bool);
fn main() {
App::new()
.insert_resource(ColorTint(
std::env::args().nth(1).unwrap_or_default() == "--colored",
))
// Since this is also used as a benchmark, we want it to display performance data.
.add_plugin(LogDiagnosticsPlugin::default())
.add_plugin(FrameTimeDiagnosticsPlugin::default())
.add_plugins(DefaultPlugins.set(WindowPlugin {
window: WindowDescriptor {
present_mode: PresentMode::AutoNoVsync,
..default()
},
..default()
}))
.add_startup_system(setup)
.add_system(print_sprite_count)
.add_system(move_camera.after(print_sprite_count))
.run();
}
fn setup(mut commands: Commands, assets: Res<AssetServer>, color_tint: Res<ColorTint>) {
warn!(include_str!("warning_string.txt"));
let mut rng = rand::thread_rng();
let tile_size = Vec2::splat(64.0);
let map_size = Vec2::splat(320.0);
let half_x = (map_size.x / 2.0) as i32;
let half_y = (map_size.y / 2.0) as i32;
let sprite_handle = assets.load("branding/icon.png");
// Spawns the camera
commands.spawn(Camera2dBundle::default());
// Builds and spawns the sprites
let mut sprites = vec![];
for y in -half_y..half_y {
for x in -half_x..half_x {
let position = Vec2::new(x as f32, y as f32);
let translation = (position * tile_size).extend(rng.gen::<f32>());
let rotation = Quat::from_rotation_z(rng.gen::<f32>());
let scale = Vec3::splat(rng.gen::<f32>() * 2.0);
sprites.push(SpriteBundle {
texture: sprite_handle.clone(),
transform: Transform {
translation,
rotation,
scale,
},
sprite: Sprite {
custom_size: Some(tile_size),
color: if color_tint.0 {
COLORS[rng.gen_range(0..3)]
} else {
Color::WHITE
},
..default()
},
..default()
});
}
}
commands.spawn_batch(sprites);
}
// System for rotating and translating the camera
fn move_camera(time: Res<Time>, mut camera_query: Query<&mut Transform, With<Camera>>) {
let mut camera_transform = camera_query.single_mut();
camera_transform.rotate_z(time.delta_seconds() * 0.5);
*camera_transform = *camera_transform
* Transform::from_translation(Vec3::X * CAMERA_SPEED * time.delta_seconds());
}
#[derive(Deref, DerefMut)]
struct PrintingTimer(Timer);
impl Default for PrintingTimer {
fn default() -> Self {
Self(Timer::from_seconds(1.0, TimerMode::Repeating))
}
}
// System for printing the number of sprites on every tick of the timer
fn print_sprite_count(time: Res<Time>, mut timer: Local<PrintingTimer>, sprites: Query<&Sprite>) {
timer.tick(time.delta());
if timer.just_finished() {
info!("Sprites: {}", sprites.iter().count(),);
}
}