sprite_slice/
sprite_slice.rs

1//! Showcases sprite 9 slice scaling and tiling features, enabling usage of
2//! sprites in multiple resolutions while keeping it in proportion
3use bevy::prelude::*;
4
5fn main() {
6    App::new()
7        .add_plugins(DefaultPlugins)
8        .add_systems(Startup, setup)
9        .run();
10}
11
12fn spawn_sprites(
13    commands: &mut Commands,
14    texture_handle: Handle<Image>,
15    mut position: Vec3,
16    slice_border: f32,
17    style: TextFont,
18    gap: f32,
19) {
20    let cases = [
21        // Reference sprite
22        (
23            "Original",
24            style.clone(),
25            Vec2::splat(100.0),
26            SpriteImageMode::Auto,
27        ),
28        // Scaled regular sprite
29        (
30            "Stretched",
31            style.clone(),
32            Vec2::new(100.0, 200.0),
33            SpriteImageMode::Auto,
34        ),
35        // Stretched Scaled sliced sprite
36        (
37            "With Slicing",
38            style.clone(),
39            Vec2::new(100.0, 200.0),
40            SpriteImageMode::Sliced(TextureSlicer {
41                border: BorderRect::all(slice_border),
42                center_scale_mode: SliceScaleMode::Stretch,
43                ..default()
44            }),
45        ),
46        // Scaled sliced sprite
47        (
48            "With Tiling",
49            style.clone(),
50            Vec2::new(100.0, 200.0),
51            SpriteImageMode::Sliced(TextureSlicer {
52                border: BorderRect::all(slice_border),
53                center_scale_mode: SliceScaleMode::Tile { stretch_value: 0.5 },
54                sides_scale_mode: SliceScaleMode::Tile { stretch_value: 0.2 },
55                ..default()
56            }),
57        ),
58        // Scaled sliced sprite horizontally
59        (
60            "With Tiling",
61            style.clone(),
62            Vec2::new(300.0, 200.0),
63            SpriteImageMode::Sliced(TextureSlicer {
64                border: BorderRect::all(slice_border),
65                center_scale_mode: SliceScaleMode::Tile { stretch_value: 0.2 },
66                sides_scale_mode: SliceScaleMode::Tile { stretch_value: 0.3 },
67                ..default()
68            }),
69        ),
70        // Scaled sliced sprite horizontally with max scale
71        (
72            "With Corners Constrained",
73            style,
74            Vec2::new(300.0, 200.0),
75            SpriteImageMode::Sliced(TextureSlicer {
76                border: BorderRect::all(slice_border),
77                center_scale_mode: SliceScaleMode::Tile { stretch_value: 0.1 },
78                sides_scale_mode: SliceScaleMode::Tile { stretch_value: 0.2 },
79                max_corner_scale: 0.2,
80            }),
81        ),
82    ];
83
84    for (label, text_style, size, scale_mode) in cases {
85        position.x += 0.5 * size.x;
86        commands.spawn((
87            Sprite {
88                image: texture_handle.clone(),
89                custom_size: Some(size),
90                image_mode: scale_mode,
91                ..default()
92            },
93            Transform::from_translation(position),
94            children![(
95                Text2d::new(label),
96                text_style,
97                TextLayout::new_with_justify(Justify::Center),
98                Transform::from_xyz(0., -0.5 * size.y - 10., 0.0),
99                bevy::sprite::Anchor::TOP_CENTER,
100            )],
101        ));
102        position.x += 0.5 * size.x + gap;
103    }
104}
105
106fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
107    commands.spawn(Camera2d);
108
109    let font = asset_server.load("fonts/FiraSans-Bold.ttf");
110    let style = TextFont {
111        font: font.clone(),
112        ..default()
113    };
114
115    // Load textures
116    let handle_1 = asset_server.load("textures/slice_square.png");
117    let handle_2 = asset_server.load("textures/slice_square_2.png");
118
119    spawn_sprites(
120        &mut commands,
121        handle_1,
122        Vec3::new(-600.0, 150.0, 0.0),
123        200.0,
124        style.clone(),
125        40.,
126    );
127
128    spawn_sprites(
129        &mut commands,
130        handle_2,
131        Vec3::new(-600.0, -150.0, 0.0),
132        80.0,
133        style,
134        40.,
135    );
136}