Skip to content

Commit 04308a0

Browse files
committed
Sprite textures is now an enum
1 parent 3d68094 commit 04308a0

22 files changed

+104
-151
lines changed

crates/bevy_sprite/src/bundle.rs

Lines changed: 5 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,15 @@
1-
use crate::{
2-
texture_atlas::{TextureAtlas, TextureAtlasSprite},
3-
Sprite,
4-
};
5-
use bevy_asset::Handle;
1+
use crate::{Sprite, SpriteImage};
62
use bevy_ecs::bundle::Bundle;
7-
use bevy_render::{
8-
texture::{Image, DEFAULT_IMAGE_HANDLE},
9-
view::Visibility,
10-
};
3+
use bevy_render::view::Visibility;
114
use bevy_transform::components::{GlobalTransform, Transform};
125

13-
#[derive(Bundle, Clone)]
6+
#[derive(Bundle, Clone, Default)]
147
pub struct SpriteBundle {
158
pub sprite: Sprite,
169
pub transform: Transform,
1710
pub global_transform: GlobalTransform,
18-
pub texture: Handle<Image>,
19-
/// User indication of whether an entity is visible
20-
pub visibility: Visibility,
21-
}
22-
23-
impl Default for SpriteBundle {
24-
fn default() -> Self {
25-
Self {
26-
sprite: Default::default(),
27-
transform: Default::default(),
28-
global_transform: Default::default(),
29-
texture: DEFAULT_IMAGE_HANDLE.typed(),
30-
visibility: Default::default(),
31-
}
32-
}
33-
}
34-
/// A Bundle of components for drawing a single sprite from a sprite sheet (also referred
35-
/// to as a `TextureAtlas`)
36-
#[derive(Bundle, Clone, Default)]
37-
pub struct SpriteSheetBundle {
38-
/// The specific sprite from the texture atlas to be drawn
39-
pub sprite: TextureAtlasSprite,
40-
/// A handle to the texture atlas that holds the sprite images
41-
pub texture_atlas: Handle<TextureAtlas>,
42-
/// Data pertaining to how the sprite is drawn on the screen
43-
pub transform: Transform,
44-
pub global_transform: GlobalTransform,
11+
/// The sprite texture
12+
pub texture: SpriteImage,
4513
/// User indication of whether an entity is visible
4614
pub visibility: Visibility,
4715
}

crates/bevy_sprite/src/image.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
use crate::TextureAtlas;
2+
use bevy_asset::Handle;
3+
use bevy_ecs::component::Component;
4+
use bevy_reflect::Reflect;
5+
use bevy_render::texture::{Image, DEFAULT_IMAGE_HANDLE};
6+
7+
/// The sprite texture
8+
#[derive(Component, Clone, Debug, Reflect)]
9+
pub enum SpriteImage {
10+
/// Single texture
11+
Image(Handle<Image>),
12+
/// Texture atlas.
13+
TextureAtlas {
14+
/// Texture atlas handle
15+
handle: Handle<TextureAtlas>,
16+
/// Texture atlas index
17+
index: usize,
18+
},
19+
}
20+
21+
impl Default for SpriteImage {
22+
fn default() -> Self {
23+
Self::Image(DEFAULT_IMAGE_HANDLE.typed())
24+
}
25+
}
26+
27+
impl From<Handle<Image>> for SpriteImage {
28+
fn from(handle: Handle<Image>) -> Self {
29+
Self::Image(handle)
30+
}
31+
}

crates/bevy_sprite/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
mod bundle;
22
mod dynamic_texture_atlas_builder;
3+
mod image;
34
mod mesh2d;
45
mod rect;
56
mod render;
@@ -12,15 +13,14 @@ pub mod collide_aabb;
1213
pub mod prelude {
1314
#[doc(hidden)]
1415
pub use crate::{
15-
bundle::{SpriteBundle, SpriteSheetBundle},
16-
sprite::Sprite,
17-
texture_atlas::{TextureAtlas, TextureAtlasSprite},
16+
bundle::SpriteBundle, image::SpriteImage, sprite::Sprite, texture_atlas::TextureAtlas,
1817
ColorMaterial, ColorMesh2dBundle, TextureAtlasBuilder,
1918
};
2019
}
2120

2221
pub use bundle::*;
2322
pub use dynamic_texture_atlas_builder::*;
23+
pub use image::*;
2424
pub use mesh2d::*;
2525
pub use rect::*;
2626
pub use render::*;

crates/bevy_sprite/src/render/mod.rs

Lines changed: 20 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
use std::cmp::Ordering;
22

3-
use crate::{
4-
texture_atlas::{TextureAtlas, TextureAtlasSprite},
5-
Rect, Sprite, SPRITE_SHADER_HANDLE,
6-
};
3+
use crate::{texture_atlas::TextureAtlas, Rect, Sprite, SpriteImage, SPRITE_SHADER_HANDLE};
74
use bevy_asset::{AssetEvent, Assets, Handle, HandleId};
85
use bevy_core_pipeline::core_2d::Transparent2d;
96
use bevy_ecs::{
@@ -224,54 +221,43 @@ pub fn extract_sprite_events(
224221
pub fn extract_sprites(
225222
mut render_world: ResMut<RenderWorld>,
226223
texture_atlases: Res<Assets<TextureAtlas>>,
227-
sprite_query: Query<(&Visibility, &Sprite, &GlobalTransform, &Handle<Image>)>,
228-
atlas_query: Query<(
229-
&Visibility,
230-
&TextureAtlasSprite,
231-
&GlobalTransform,
232-
&Handle<TextureAtlas>,
233-
)>,
224+
sprite_query: Query<(&Visibility, &Sprite, &GlobalTransform, &SpriteImage)>,
234225
) {
235226
let mut extracted_sprites = render_world.resource_mut::<ExtractedSprites>();
236227
extracted_sprites.sprites.clear();
237-
for (visibility, sprite, transform, handle) in sprite_query.iter() {
228+
for (visibility, sprite, transform, image) in sprite_query.iter() {
238229
if !visibility.is_visible {
239230
continue;
240231
}
232+
233+
let (rect, image_handle_id) = match image {
234+
SpriteImage::Image(handle) => (None, handle.id),
235+
SpriteImage::TextureAtlas { handle, index } => {
236+
if let Some(atlas) = texture_atlases.get(handle) {
237+
let rect = atlas.textures.get(*index).copied().unwrap_or_else(|| {
238+
panic!("TextureAtlas {:?} as no texture at index {}", atlas, index)
239+
});
240+
(Some(rect), atlas.texture.id)
241+
} else {
242+
// Skip loading images
243+
continue;
244+
}
245+
}
246+
};
241247
// PERF: we don't check in this function that the `Image` asset is ready, since it should be in most cases and hashing the handle is expensive
242248
extracted_sprites.sprites.alloc().init(ExtractedSprite {
243249
color: sprite.color,
244250
transform: *transform,
245251
// Use the full texture
246-
rect: None,
252+
rect,
247253
// Pass the custom size
248254
custom_size: sprite.custom_size,
249255
flip_x: sprite.flip_x,
250256
flip_y: sprite.flip_y,
251-
image_handle_id: handle.id,
257+
image_handle_id,
252258
anchor: sprite.anchor.as_vec(),
253259
});
254260
}
255-
for (visibility, atlas_sprite, transform, texture_atlas_handle) in atlas_query.iter() {
256-
if !visibility.is_visible {
257-
continue;
258-
}
259-
if let Some(texture_atlas) = texture_atlases.get(texture_atlas_handle) {
260-
let rect = Some(texture_atlas.textures[atlas_sprite.index as usize]);
261-
extracted_sprites.sprites.alloc().init(ExtractedSprite {
262-
color: atlas_sprite.color,
263-
transform: *transform,
264-
// Select the area in the texture atlas
265-
rect,
266-
// Pass the custom size
267-
custom_size: atlas_sprite.custom_size,
268-
flip_x: atlas_sprite.flip_x,
269-
flip_y: atlas_sprite.flip_y,
270-
image_handle_id: texture_atlas.texture.id,
271-
anchor: atlas_sprite.anchor.as_vec(),
272-
});
273-
}
274-
}
275261
}
276262

277263
#[repr(C)]

crates/bevy_sprite/src/texture_atlas.rs

Lines changed: 3 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
use crate::{Anchor, Rect};
1+
use crate::Rect;
22
use bevy_asset::Handle;
3-
use bevy_ecs::component::Component;
43
use bevy_math::Vec2;
5-
use bevy_reflect::{Reflect, TypeUuid};
6-
use bevy_render::{color::Color, texture::Image};
4+
use bevy_reflect::TypeUuid;
5+
use bevy_render::texture::Image;
76
use bevy_utils::HashMap;
87

98
/// An atlas containing multiple textures (like a spritesheet or a tilemap).
@@ -21,40 +20,6 @@ pub struct TextureAtlas {
2120
pub texture_handles: Option<HashMap<Handle<Image>, usize>>,
2221
}
2322

24-
#[derive(Component, Debug, Clone, Reflect)]
25-
pub struct TextureAtlasSprite {
26-
pub color: Color,
27-
pub index: usize,
28-
pub flip_x: bool,
29-
pub flip_y: bool,
30-
/// An optional custom size for the sprite that will be used when rendering, instead of the size
31-
/// of the sprite's image in the atlas
32-
pub custom_size: Option<Vec2>,
33-
pub anchor: Anchor,
34-
}
35-
36-
impl Default for TextureAtlasSprite {
37-
fn default() -> Self {
38-
Self {
39-
index: 0,
40-
color: Color::WHITE,
41-
flip_x: false,
42-
flip_y: false,
43-
custom_size: None,
44-
anchor: Anchor::default(),
45-
}
46-
}
47-
}
48-
49-
impl TextureAtlasSprite {
50-
pub fn new(index: usize) -> TextureAtlasSprite {
51-
Self {
52-
index,
53-
..Default::default()
54-
}
55-
}
56-
}
57-
5823
impl TextureAtlas {
5924
/// Create a new `TextureAtlas` that has a texture, but does not have
6025
/// any individual sprites specified

examples/2d/move_sprite.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
2020
commands.spawn_bundle(Camera2dBundle::default());
2121
commands
2222
.spawn_bundle(SpriteBundle {
23-
texture: asset_server.load("branding/icon.png"),
23+
texture: asset_server.load("branding/icon.png").into(),
2424
transform: Transform::from_xyz(100., 0., 0.),
2525
..default()
2626
})

examples/2d/rotation.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
6767
// player controlled ship
6868
commands
6969
.spawn_bundle(SpriteBundle {
70-
texture: ship_handle,
70+
texture: ship_handle.into(),
7171
..default()
7272
})
7373
.insert(Player {
@@ -78,14 +78,14 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
7878
// enemy that snaps to face the player spawns on the bottom and left
7979
commands
8080
.spawn_bundle(SpriteBundle {
81-
texture: enemy_a_handle.clone(),
81+
texture: enemy_a_handle.clone().into(),
8282
transform: Transform::from_xyz(0.0 - horizontal_margin, 0.0, 0.0),
8383
..default()
8484
})
8585
.insert(SnapToPlayer);
8686
commands
8787
.spawn_bundle(SpriteBundle {
88-
texture: enemy_a_handle,
88+
texture: enemy_a_handle.into(),
8989
transform: Transform::from_xyz(0.0, 0.0 - vertical_margin, 0.0),
9090
..default()
9191
})
@@ -94,7 +94,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
9494
// enemy that rotates to face the player enemy spawns on the top and right
9595
commands
9696
.spawn_bundle(SpriteBundle {
97-
texture: enemy_b_handle.clone(),
97+
texture: enemy_b_handle.clone().into(),
9898
transform: Transform::from_xyz(0.0 + horizontal_margin, 0.0, 0.0),
9999
..default()
100100
})
@@ -103,7 +103,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
103103
});
104104
commands
105105
.spawn_bundle(SpriteBundle {
106-
texture: enemy_b_handle,
106+
texture: enemy_b_handle.into(),
107107
transform: Transform::from_xyz(0.0, 0.0 + vertical_margin, 0.0),
108108
..default()
109109
})

examples/2d/sprite.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ fn main() {
1212
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
1313
commands.spawn_bundle(Camera2dBundle::default());
1414
commands.spawn_bundle(SpriteBundle {
15-
texture: asset_server.load("branding/icon.png"),
15+
texture: asset_server.load("branding/icon.png").into(),
1616
..default()
1717
});
1818
}

examples/2d/sprite_flipping.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ fn main() {
1212
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
1313
commands.spawn_bundle(Camera2dBundle::default());
1414
commands.spawn_bundle(SpriteBundle {
15-
texture: asset_server.load("branding/icon.png"),
15+
texture: asset_server.load("branding/icon.png").into(),
1616
sprite: Sprite {
1717
// Flip the logo to the left
1818
flip_x: true,

examples/2d/sprite_sheet.rs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
//! into a texture atlas, and changing the displayed image periodically.
33
44
use bevy::{prelude::*, render::texture::ImageSettings};
5+
use std::ops::DerefMut;
56

67
fn main() {
78
App::new()
@@ -18,17 +19,15 @@ struct AnimationTimer(Timer);
1819
fn animate_sprite(
1920
time: Res<Time>,
2021
texture_atlases: Res<Assets<TextureAtlas>>,
21-
mut query: Query<(
22-
&mut AnimationTimer,
23-
&mut TextureAtlasSprite,
24-
&Handle<TextureAtlas>,
25-
)>,
22+
mut query: Query<(&mut AnimationTimer, &mut SpriteImage)>,
2623
) {
27-
for (mut timer, mut sprite, texture_atlas_handle) in query.iter_mut() {
24+
for (mut timer, mut image) in query.iter_mut() {
2825
timer.tick(time.delta());
2926
if timer.just_finished() {
30-
let texture_atlas = texture_atlases.get(texture_atlas_handle).unwrap();
31-
sprite.index = (sprite.index + 1) % texture_atlas.textures.len();
27+
if let SpriteImage::TextureAtlas { index, handle } = image.deref_mut() {
28+
let texture_atlas = texture_atlases.get(handle).unwrap();
29+
*index = (*index + 1) % texture_atlas.textures.len();
30+
}
3231
}
3332
}
3433
}
@@ -43,8 +42,11 @@ fn setup(
4342
let texture_atlas_handle = texture_atlases.add(texture_atlas);
4443
commands.spawn_bundle(Camera2dBundle::default());
4544
commands
46-
.spawn_bundle(SpriteSheetBundle {
47-
texture_atlas: texture_atlas_handle,
45+
.spawn_bundle(SpriteBundle {
46+
texture: SpriteImage::TextureAtlas {
47+
handle: texture_atlas_handle,
48+
index: 0,
49+
},
4850
transform: Transform::from_scale(Vec3::splat(6.0)),
4951
..default()
5052
})

examples/2d/texture_atlas.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,19 +65,21 @@ fn setup(
6565
// set up a scene to display our texture atlas
6666
commands.spawn_bundle(Camera2dBundle::default());
6767
// draw a sprite from the atlas
68-
commands.spawn_bundle(SpriteSheetBundle {
68+
commands.spawn_bundle(SpriteBundle {
6969
transform: Transform {
7070
translation: Vec3::new(150.0, 0.0, 0.0),
7171
scale: Vec3::splat(4.0),
7272
..default()
7373
},
74-
sprite: TextureAtlasSprite::new(vendor_index),
75-
texture_atlas: atlas_handle,
74+
texture: SpriteImage::TextureAtlas {
75+
handle: atlas_handle,
76+
index: vendor_index,
77+
},
7678
..default()
7779
});
7880
// draw the atlas itself
7981
commands.spawn_bundle(SpriteBundle {
80-
texture: texture_atlas_texture,
82+
texture: texture_atlas_texture.into(),
8183
transform: Transform::from_xyz(-300.0, 0.0, 0.0),
8284
..default()
8385
});

0 commit comments

Comments
 (0)