merwaaan / bevy_spritesheet_animation

A Bevy plugin for animating sprites that are backed by spritesheets
MIT License
50 stars 3 forks source link

SpritesheetLibrary::new_clip #4

Closed UkoeHB closed 1 month ago

UkoeHB commented 3 months ago

Had some issues with this method.

merwaaan commented 3 months ago

@UkoeHB Thanks for the feedback!

UkoeHB commented 3 months ago

Hi @merwaaan

My use-case was solved by defining markers outside the closure. It was just a small headache when I wanted to make marker ids at the same spot I call builder.add_marker().

fn setup_animation(
    image_map: &ImageMap,
    library: &mut SpritesheetLibrary,
    atlas_layouts: &mut Assets<TextureAtlasLayout>,
    animations: &mut SpriteAnimations,
    spritesheet_markers: &mut SpritesheetMarkers,
    mut animation: SpriteAnimation,
)
{
    // Animation clips.
    let clips: Vec<(SpriteAnimationClip, Vec<(AnimationMarkerId, usize)>)> = animation
        .clips
        .drain(..)
        .map(|mut clip| {
            let markers: Vec<(AnimationMarkerId, usize)> = clip
                .markers
                .drain(..)
                .map(|(name, frame)| {
                    let marker_id = library.new_marker();
                    spritesheet_markers.insert(marker_id, name);
                    (marker_id, frame)
                })
                .collect();

            (clip, markers)
        })
        .collect();

    let clip_ids: Vec<AnimationClipId> = clips
        .iter()
        .map(|(clip, markers)| {
            library.new_clip(|builder| {
                match clip.frames.clone() {
                    AnimationFrames::Row(row) => {
                        builder.push_frame_indices(Spritesheet::new(animation.columns, animation.rows).row(row));
                    }
                    AnimationFrames::Column(column) => {
                        builder.push_frame_indices(
                            Spritesheet::new(animation.columns, animation.rows).column(column),
                        );
                    }
                    AnimationFrames::Frame(frame) => {
                        builder.push_frame_indices(vec![frame]);
                    }
                    AnimationFrames::Frames(frames) => {
                        builder.push_frame_indices(frames);
                    }
                }

                for (marker_id, marker_frame) in markers.iter() {
                    builder.add_marker(*marker_id, *marker_frame);
                }
            })
        })
        .collect();

    // Animation.
    let anim_id = library.new_animation(|builder| {
        // Set frame duration.
        builder.set_duration(AnimationDuration::PerFrame(animation.frame_time));

        // Set cycles.
        if let Some(cycles) = animation.loops {
            builder.set_repeat(AnimationRepeat::Cycles(cycles as u32));
        }

        // Add clips.
        for clip_id in clip_ids.iter() {
            builder.add_stage((*clip_id).into());
        }
    });

    // Save the animation's sprite info.
    let image = image_map.get(animation.image);
    let layout = atlas_layouts.add(TextureAtlasLayout::from_grid(
        animation.size,
        animation.columns,
        animation.rows,
        animation.padding,
        animation.offset,
    ));
    animations.insert(anim_id, animation.name, image, layout);
}
merwaaan commented 1 month ago

@UkoeHB Creating animations has been made way more straightforward with the latest commits so things should be easier for you now.