Added object sprite animations

master
Mark 2024-01-04 19:34:18 -08:00
parent 7593be18ee
commit 1f154c1a58
Signed by: Mark
GPG Key ID: C6D63995FE72FD80
5 changed files with 77 additions and 8 deletions

2
assets

@ -1 +1 @@
Subproject commit 05e5272f3789b44192d0bf2bd253641e76659a2a Subproject commit 38fd6766762ce90bb699f98e30e46b17c4eda50c

View File

@ -1,5 +1,5 @@
[ship."Gypsum"] [ship."Gypsum"]
sprite = "ship::gypsum" sprite = "ship::peregrine"
size = 100 size = 100
mass = 1 mass = 1
hull = 200 hull = 200

View File

@ -19,6 +19,23 @@ file = "projectile/blaster.png"
[sprite."ship::gypsum"] [sprite."ship::gypsum"]
file = "ship/gypsum.png" file = "ship/gypsum.png"
[sprite."ship::peregrine"]
duration = 1
repeat = "repeat"
frames = [
"ship/peregrine/01.png",
"ship/peregrine/02.png",
"ship/peregrine/03.png",
"ship/peregrine/04.png",
"ship/peregrine/05.png",
"ship/peregrine/06.png",
"ship/peregrine/07.png",
"ship/peregrine/08.png",
"ship/peregrine/09.png",
"ship/peregrine/10.png",
"ship/peregrine/11.png",
]
[sprite."ui::radar"] [sprite."ui::radar"]
file = "ui/radar.png" file = "ui/radar.png"

View File

@ -26,7 +26,39 @@ var texture_array: binding_array<texture_2d<f32>>;
var sampler_array: binding_array<sampler>; var sampler_array: binding_array<sampler>;
fn fmod(x: f32, m: f32) -> f32 {
return x - floor(x / m) * m;
}
// Returns texture index
// TODO: random age
// TODO: preprocessor include function
// TODO: packed location config, better error
// TODO: bounce animations
// TODO: animation randomness?
fn animate(instance: InstanceInput) -> u32 {
// Age doesn't make sense here, so arbitrarily pick zero.
let age = global.current_time.x;
let len = sprites.data[instance.texture_index].frame_count;
let rep = sprites.data[instance.texture_index].repeatmode;
let fps = sprites.data[instance.texture_index].fps;
var frame: u32 = u32(0);
if rep == u32(1) {
// Repeat
frame = u32(fmod(
(age / fps),
f32(len)
));
} else {
// Once
frame = u32(min(
(age / fps),
f32(len) - 1.0
));
}
return frame + sprites.data[instance.texture_index].first_frame;
}
@vertex @vertex
fn vertex_main( fn vertex_main(
@ -44,8 +76,7 @@ fn vertex_main(
var out: VertexOutput; var out: VertexOutput;
out.position = transform * vec4<f32>(vertex.position, 1.0); out.position = transform * vec4<f32>(vertex.position, 1.0);
let i = sprites.data[instance.texture_index].first_frame; let t = atlas.data[animate(instance)];
let t = atlas.data[i];
out.texture_index = u32(0); out.texture_index = u32(0);
out.texture_coords = vec2(t.xpos, t.ypos); out.texture_coords = vec2(t.xpos, t.ypos);
if vertex.texture_coords.x == 1.0 { if vertex.texture_coords.x == 1.0 {

View File

@ -29,6 +29,30 @@ var texture_array: binding_array<texture_2d<f32>>;
var sampler_array: binding_array<sampler>; var sampler_array: binding_array<sampler>;
// Returns texture index
fn animate(instance: InstanceInput) -> u32 {
let age = global.current_time.x - instance.created;
let len = sprites.data[instance.texture_index].frame_count;
let rep = sprites.data[instance.texture_index].repeatmode;
let fps = sprites.data[instance.texture_index].fps;
var frame: u32 = u32(0);
if rep == u32(1) {
// Repeat
frame = u32(fmod(
(age / fps),
f32(len)
));
} else {
// Once
frame = u32(min(
(age / fps),
f32(len) - 1.0
));
}
return frame + sprites.data[instance.texture_index].first_frame;
}
fn fmod(x: f32, m: f32) -> f32 { fn fmod(x: f32, m: f32) -> f32 {
return x - floor(x / m) * m; return x - floor(x / m) * m;
} }
@ -68,10 +92,7 @@ fn vertex_main(
)); ));
} }
let t = atlas.data[animate(instance)];
// Pick image
frame = frame + sprites.data[instance.texture_index].first_frame;
let t = atlas.data[frame];
out.texture_index = u32(0); out.texture_index = u32(0);
out.texture_coords = vec2(t.xpos, t.ypos); out.texture_coords = vec2(t.xpos, t.ypos);
if vertex.texture_coords.x == 1.0 { if vertex.texture_coords.x == 1.0 {