2024-01-06 14:02:50 -08:00
|
|
|
// Pick a frame of a sprite animation from an instance.
|
|
|
|
fn animate(sprite_index: u32, age: f32, offset: f32) -> f32 {
|
2024-01-04 21:30:12 -08:00
|
|
|
|
2024-01-06 14:02:50 -08:00
|
|
|
let len = global_sprites[sprite_index].frame_count;
|
|
|
|
let rep = global_sprites[sprite_index].repeatmode;
|
|
|
|
let fps = global_sprites[sprite_index].fps;
|
|
|
|
var frame: f32 = 0.0;
|
2024-01-04 21:41:15 -08:00
|
|
|
|
2024-01-05 12:09:59 -08:00
|
|
|
// Once
|
2024-01-04 21:41:15 -08:00
|
|
|
if rep == u32(1) {
|
|
|
|
|
2024-01-06 14:02:50 -08:00
|
|
|
frame = min(
|
|
|
|
age / fps + offset,
|
2024-01-04 21:30:12 -08:00
|
|
|
f32(len) - 1.0
|
2024-01-06 14:02:50 -08:00
|
|
|
);
|
2024-01-04 21:41:15 -08:00
|
|
|
|
|
|
|
// Reverse
|
|
|
|
} else if rep == u32(2) {
|
2024-01-06 14:02:50 -08:00
|
|
|
let x = age / fps + offset;
|
2024-01-04 21:41:15 -08:00
|
|
|
let m = f32(len) * 2.0 - 1.0;
|
|
|
|
// x fmod m
|
2024-01-06 14:02:50 -08:00
|
|
|
frame = x - floor(x / m) * m;
|
|
|
|
|
|
|
|
if frame >= f32(len) {
|
|
|
|
frame = (
|
|
|
|
f32(len) + f32(len) - 1.0
|
|
|
|
// Split integer and fractional part so tweening works properly
|
|
|
|
- floor(frame)
|
|
|
|
+ fract(frame)
|
|
|
|
);
|
2024-01-04 21:41:15 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Repeat (default)
|
|
|
|
} else {
|
2024-01-06 14:02:50 -08:00
|
|
|
let x = age / fps + offset;
|
2024-01-04 21:41:15 -08:00
|
|
|
let m = f32(len);
|
2024-01-06 14:02:50 -08:00
|
|
|
frame = x - floor(x / m) * m;
|
2024-01-04 21:30:12 -08:00
|
|
|
}
|
|
|
|
|
2024-01-06 14:02:50 -08:00
|
|
|
return frame + f32(global_sprites[sprite_index].first_frame);
|
2024-01-04 21:30:12 -08:00
|
|
|
}
|