35 lines
1.4 KiB
GDScript
35 lines
1.4 KiB
GDScript
class_name P91AnimationAdapter
|
|
extends RefCounted
|
|
|
|
var library: Dictionary = {}
|
|
|
|
func load_specs(specs: Dictionary) -> void:
|
|
library.clear()
|
|
for character in specs:
|
|
var loaded_states := {}
|
|
for state in specs[character]:
|
|
var spec: Dictionary = specs[character][state]
|
|
var frames: Array[Texture2D] = []
|
|
for index in range(int(spec["frames"])):
|
|
var path := "res://assets/animations/%s/frame-%d.png" % [spec["root"], index]
|
|
var texture := load(path) as Texture2D
|
|
assert(texture != null, "Missing animation texture: %s" % path)
|
|
frames.append(texture)
|
|
loaded_states[state] = {"frames": frames, "fps": float(spec["fps"]), "loop": bool(spec["loop"])}
|
|
library[character] = loaded_states
|
|
|
|
func frame_index(character: String, state: String, elapsed: float) -> int:
|
|
if not library.has(character):
|
|
return 0
|
|
var resolved := state if library[character].has(state) else "idle"
|
|
var spec: Dictionary = library[character][resolved]
|
|
var count: int = spec["frames"].size()
|
|
var raw := int(floor(maxf(0.0, elapsed) * float(spec["fps"])))
|
|
return raw % count if spec["loop"] else mini(raw, count - 1)
|
|
|
|
func texture(character: String, state: String, elapsed: float) -> Texture2D:
|
|
if not library.has(character):
|
|
return null
|
|
var resolved := state if library[character].has(state) else "idle"
|
|
return library[character][resolved]["frames"][frame_index(character, resolved, elapsed)]
|