wisp_storybook/stories/
s_sprite_batcher.rs1use glam::Vec2;
4use wisp::application::Application;
5use wisp::{Color, Sprite, Stage, Texture};
6
7use crate::story::Story;
8
9pub fn story() -> Story {
10 Story {
11 id: "sprite-batcher",
12 category: "Scene Graph",
13 title: "Sprite batcher",
14 milestone: "M0.9",
15 writeup: include_str!("writeups/sprite_batcher.md"),
16 build,
17 tick: Some(tick),
18 }
19}
20
21fn build(app: &Application, stage: &mut Stage) {
22 let bytes = vec![255u8; 4 * 4 * 4];
24 let texture = Texture::from_rgba(app, 4, 4, &bytes);
25
26 let root = stage.root();
27 for i in 0u16..100 {
28 let f = f32::from(i) / 100.0;
29 let mut sprite = Sprite::from_texture(texture.clone()).with_anchor(Vec2::splat(0.5));
30 sprite.container.transform.scale = Vec2::splat(0.06);
31 let angle = f * std::f32::consts::TAU;
33 let x = (angle * 2.0).sin() * 0.7;
34 let y = (angle * 3.0).sin() * 0.7;
35 sprite.container.transform.position = Vec2::new(x, y);
36 sprite.tint = Color::rgba(
37 0.5 + 0.5 * (angle * 1.0).cos(),
38 0.5 + 0.5 * (angle * 1.5).sin(),
39 0.5 + 0.5 * (angle * 2.0).cos(),
40 1.0,
41 );
42 let _ = stage.add_child(root, sprite);
43 }
44}
45
46fn tick(stage: &mut Stage, t: f32) {
47 let child_ids: Vec<_> = stage
48 .get(stage.root())
49 .map(|root| root.container().children().collect())
50 .unwrap_or_default();
51
52 for (i, id) in child_ids.iter().enumerate().take(100) {
53 let f = u16::try_from(i).map_or(0.0, f32::from) / 100.0;
54 let phase = t + f * std::f32::consts::TAU;
55 let angle = (f * std::f32::consts::TAU) + t * 0.2;
56 let x = (angle * 2.0).sin() * 0.7;
57 let y = (angle * 3.0).sin() * 0.7;
58 if let Some(node) = stage.get_mut(*id) {
59 node.container_mut().transform.position = glam::Vec2::new(x, y);
60 node.container_mut().transform.rotation = phase * 0.3;
61 }
62 }
63}