Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add index_range for TextureAtlas #16611

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions crates/bevy_sprite/src/texture_atlas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ impl TextureAtlasSources {
Some(TextureAtlas {
layout,
index: self.texture_index(texture)?,
index_range: (0, 0),
})
}

Expand Down Expand Up @@ -170,6 +171,8 @@ pub struct TextureAtlas {
pub layout: Handle<TextureAtlasLayout>,
/// Texture atlas section index
pub index: usize,
/// The index of the first and last images in the atlas
pub index_range: (usize, usize),
}

impl TextureAtlas {
Expand All @@ -178,13 +181,22 @@ impl TextureAtlas {
let atlas = texture_atlases.get(&self.layout)?;
atlas.textures.get(self.index).copied()
}

pub fn advance_index(&mut self) -> &mut Self {
self.index += 1;
if self.index > self.index_range.1 {
self.index = self.index_range.0;
}
Comment on lines +186 to +189
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like it should just use a saturating add.

self
}
}

impl From<Handle<TextureAtlasLayout>> for TextureAtlas {
fn from(texture_atlas: Handle<TextureAtlasLayout>) -> Self {
Self {
layout: texture_atlas,
index: 0,
index_range: (0, 0),
}
}
}
6 changes: 4 additions & 2 deletions examples/2d/sprite_animation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ fn execute_animations(time: Res<Time>, mut query: Query<(&mut AnimationConfig, &
if let Some(atlas) = &mut sprite.texture_atlas {
if atlas.index == config.last_sprite_index {
// ...and it IS the last frame, then we move back to the first frame and stop.
atlas.index = config.first_sprite_index;
atlas.advance_index();
} else {
// ...and it is NOT the last frame, then we move to the next frame...
atlas.index += 1;
atlas.advance_index();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, this change looks subtly wrong to me. Previously the logic was:

  • If the index is not the last, then increment it (inline).

Now the logic is (due to advance_index):

  • If the index is not the last, then increment it (inside advance_index).
  • (Inside advance_index) If the index is more than the last set it to the index of the first.

Even if this particular change is the same as before (I didn't completely check because it looks subtly wrong and it's no longer intuitive, at least to me), my main concerns are left in a comment at the end of the review.

// ...and reset the frame timer to start counting all over again
config.frame_timer = AnimationConfig::timer_from_fps(config.fps);
}
Expand Down Expand Up @@ -106,6 +106,7 @@ fn setup(
texture_atlas: Some(TextureAtlas {
layout: texture_atlas_layout.clone(),
index: animation_config_1.first_sprite_index,
index_range: (animation_config_1.first_sprite_index, animation_config_1.last_sprite_index),
}),
..default()
},
Expand All @@ -124,6 +125,7 @@ fn setup(
texture_atlas: Some(TextureAtlas {
layout: texture_atlas_layout.clone(),
index: animation_config_2.first_sprite_index,
index_range: (animation_config_2.first_sprite_index, animation_config_2.last_sprite_index),
}),
..Default::default()
},
Expand Down
23 changes: 6 additions & 17 deletions examples/2d/sprite_sheet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,19 @@ fn main() {
.run();
}

#[derive(Component)]
struct AnimationIndices {
first: usize,
last: usize,
}

#[derive(Component, Deref, DerefMut)]
struct AnimationTimer(Timer);

fn animate_sprite(
time: Res<Time>,
mut query: Query<(&AnimationIndices, &mut AnimationTimer, &mut Sprite)>,
mut query: Query<(&mut AnimationTimer, &mut Sprite)>,
) {
for (indices, mut timer, mut sprite) in &mut query {
for (mut timer, mut sprite) in &mut query {
timer.tick(time.delta());

if timer.just_finished() {
if let Some(atlas) = &mut sprite.texture_atlas {
atlas.index = if atlas.index == indices.last {
indices.first
} else {
atlas.index + 1
};
atlas.advance_index();
}
}
}
Expand All @@ -47,19 +37,18 @@ fn setup(
let texture = asset_server.load("textures/rpg/chars/gabe/gabe-idle-run.png");
let layout = TextureAtlasLayout::from_grid(UVec2::splat(24), 7, 1, None, None);
let texture_atlas_layout = texture_atlas_layouts.add(layout);
// Use only the subset of sprites in the sheet that make up the run animation
let animation_indices = AnimationIndices { first: 1, last: 6 };

commands.spawn(Camera2d);
commands.spawn((
Sprite::from_atlas_image(
texture,
TextureAtlas {
layout: texture_atlas_layout,
index: animation_indices.first,
index: 1,
index_range: (1, 6)
},
),
Transform::from_scale(Vec3::splat(6.0)),
animation_indices,
AnimationTimer(Timer::from_seconds(0.1, TimerMode::Repeating)),
));
}
23 changes: 6 additions & 17 deletions examples/picking/sprite_picking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,32 +88,22 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
});
}

#[derive(Component)]
struct AnimationIndices {
first: usize,
last: usize,
}

#[derive(Component, Deref, DerefMut)]
struct AnimationTimer(Timer);

fn animate_sprite(
time: Res<Time>,
mut query: Query<(&AnimationIndices, &mut AnimationTimer, &mut Sprite)>,
mut query: Query<(&mut AnimationTimer, &mut Sprite)>,
) {
for (indices, mut timer, mut sprite) in &mut query {
for (mut timer, mut sprite) in &mut query {
let Some(texture_atlas) = &mut sprite.texture_atlas else {
continue;
};

timer.tick(time.delta());

if timer.just_finished() {
texture_atlas.index = if texture_atlas.index == indices.last {
indices.first
} else {
texture_atlas.index + 1
};
texture_atlas.advance_index();
}
}
}
Expand All @@ -126,19 +116,18 @@ fn setup_atlas(
let texture_handle = asset_server.load("textures/rpg/chars/gabe/gabe-idle-run.png");
let layout = TextureAtlasLayout::from_grid(UVec2::new(24, 24), 7, 1, None, None);
let texture_atlas_layout_handle = texture_atlas_layouts.add(layout);
// Use only the subset of sprites in the sheet that make up the run animation
let animation_indices = AnimationIndices { first: 1, last: 6 };

commands
.spawn((
Sprite::from_atlas_image(
texture_handle,
TextureAtlas {
layout: texture_atlas_layout_handle,
index: animation_indices.first,
index: 1,
index_range: (1, 6)
},
),
Transform::from_xyz(300.0, 0.0, 0.0).with_scale(Vec3::splat(6.0)),
animation_indices,
AnimationTimer(Timer::from_seconds(0.1, TimerMode::Repeating)),
))
.observe(recolor_on::<Pointer<Over>>(Color::srgb(0.0, 1.0, 1.0)))
Expand Down
3 changes: 2 additions & 1 deletion examples/ui/ui_texture_atlas_slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ fn button_system(
Interaction::Pressed => {
**text = "Press".to_string();
if let Some(atlas) = &mut image.texture_atlas {
atlas.index = (atlas.index + 1) % 30;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is supposed to cycle

atlas.advance_index();
}
image.color = GOLD.into();
}
Expand Down Expand Up @@ -87,6 +87,7 @@ fn setup(
TextureAtlas {
index: idx,
layout: atlas_layout_handle.clone(),
index_range: (idx, 30)
},
)
.with_mode(NodeImageMode::Sliced(slicer.clone())),
Expand Down
Loading