migrant .ani a .yaml

This commit is contained in:
2025-11-17 13:08:38 +01:00
parent 3c4092df5e
commit 6a6cc22b21
72 changed files with 47 additions and 1050 deletions

View File

@@ -1,164 +0,0 @@
#!/usr/bin/env python3
"""
Script para convertir archivos .ani a formato YAML con nomenclatura camelCase
"""
import os
import glob
import re
def parse_ani_file(file_path):
"""
Parsea un archivo .ani y retorna un diccionario con los datos
"""
data = {
'tileSetFile': None,
'frameWidth': None,
'frameHeight': None,
'animations': []
}
current_animation = None
with open(file_path, 'r', encoding='utf-8') as f:
for line in f:
line = line.strip()
# Ignorar líneas vacías
if not line:
continue
# Detectar inicio de animación
if line == '[animation]':
current_animation = {}
continue
# Detectar fin de animación
if line == '[/animation]':
if current_animation:
data['animations'].append(current_animation)
current_animation = None
continue
# Parsear parámetros
if '=' in line:
key, value = line.split('=', 1)
key = key.strip()
value = value.strip()
# Parámetros globales
if key == 'tileSetFile':
data['tileSetFile'] = value
elif key == 'frame_width':
data['frameWidth'] = int(value)
elif key == 'frame_height':
data['frameHeight'] = int(value)
# Parámetros de animación
elif current_animation is not None:
if key == 'name':
current_animation['name'] = value
elif key == 'speed':
current_animation['speed'] = float(value)
elif key == 'loop':
current_animation['loop'] = int(value)
elif key == 'frames':
# Convertir "0,1,2,3" a [0, 1, 2, 3]
current_animation['frames'] = [int(x.strip()) for x in value.split(',')]
return data
def generate_yaml(data, comment_header=""):
"""
Genera el contenido YAML a partir de los datos parseados
"""
lines = []
# Añadir comentario de header si existe
if comment_header:
lines.append(f"# {comment_header}")
# Parámetros globales
if data['tileSetFile']:
lines.append(f"tileSetFile: {data['tileSetFile']}")
if data['frameWidth'] is not None:
lines.append(f"frameWidth: {data['frameWidth']}")
if data['frameHeight'] is not None:
lines.append(f"frameHeight: {data['frameHeight']}")
# Animaciones
if data['animations']:
lines.append("")
lines.append("animations:")
for anim in data['animations']:
lines.append(f" - name: {anim.get('name', 'default')}")
lines.append(f" speed: {anim.get('speed', 0.0)}")
lines.append(f" loop: {anim.get('loop', 0)}")
# Frames en formato compacto [0, 1, 2, 3]
frames = anim.get('frames', [])
frames_str = '[' + ', '.join(str(f) for f in frames) + ']'
lines.append(f" frames: {frames_str}")
# Línea vacía entre animaciones (excepto la última)
if anim != data['animations'][-1]:
lines.append("")
return '\n'.join(lines) + '\n'
def convert_ani_to_yaml(ani_path):
"""
Convierte un archivo .ani a .yaml
"""
# Generar nombre del archivo de salida
yaml_path = ani_path.replace('.ani', '.yaml')
# Parsear archivo .ani
data = parse_ani_file(ani_path)
# Generar comentario de header basado en el nombre del archivo
filename = os.path.basename(ani_path)
comment = f"{filename.replace('.ani', '')} animation"
# Generar contenido YAML
yaml_content = generate_yaml(data, comment)
# Escribir archivo .yaml
with open(yaml_path, 'w', encoding='utf-8') as f:
f.write(yaml_content)
print(f"{ani_path}{yaml_path}")
return yaml_path
def main():
"""
Función principal que convierte todos los archivos .ani a .yaml
"""
# Buscar todos los archivos .ani
ani_files = glob.glob('data/**/*.ani', recursive=True)
if not ani_files:
print("No se encontraron archivos .ani")
return
print(f"Encontrados {len(ani_files)} archivos .ani\n")
# Convertir cada archivo
converted = 0
for ani_file in sorted(ani_files):
try:
convert_ani_to_yaml(ani_file)
converted += 1
except Exception as e:
print(f"✗ Error al convertir {ani_file}: {e}")
print(f"\n{converted}/{len(ani_files)} archivos convertidos exitosamente")
if __name__ == '__main__':
main()

View File

@@ -1,10 +0,0 @@
tileSetFile=shine.gif
frame_width=8
frame_height=8
[animation]
name=default
speed=0.1000
loop=-1
frames=0,1,2,3,4,5,6,7
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=abad.gif
frame_width=8
frame_height=16
[animation]
name=default
speed=0.1333
loop=0
frames=0,1,2
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=abad_bell.gif
frame_width=16
frame_height=16
[animation]
name=default
speed=0.0667
loop=0
frames=0,1,2,3,4,5,6,7,8,9
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=amstrad_cs.gif
frame_width=8
frame_height=8
[animation]
name=default
speed=0.0667
loop=0
frames=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=arounders_door.gif
frame_width=16
frame_height=16
[animation]
name=default
speed=0.1333
loop=0
frames=0,1,2,3,3,3,3,3,3,3,3,3,3,3,3,2,1,0,0,0
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=arounders_machine.gif
frame_width=16
frame_height=16
[animation]
name=default
speed=0.0667
loop=0
frames=0,1,2,3
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=bat.gif
frame_width=9
frame_height=7
[animation]
name=default
speed=0.0500
loop=0
frames=0,1
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=batman.gif
frame_width=8
frame_height=16
[animation]
name=default
speed=0.1333
loop=0
frames=0,1,2,3
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=batman_bell.gif
frame_width=16
frame_height=16
[animation]
name=default
speed=0.1000
loop=0
frames=0,1,2,3,4,5
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=batman_fire.gif
frame_width=16
frame_height=16
[animation]
name=default
speed=0.0667
loop=0
frames=0,1,2,3
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=bell.gif
frame_width=16
frame_height=16
[animation]
name=default
speed=0.1000
loop=0
frames=0,1,2,3,4,5,6,7,8,9,10,11
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=bin.gif
frame_width=16
frame_height=8
[animation]
name=default
speed=0.1667
loop=0
frames=0,1,2,3,4
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=bird.gif
frame_width=16
frame_height=16
[animation]
name=default
speed=0.1333
loop=0
frames=0,1,2,3
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=breakout.gif
frame_width=24
frame_height=32
[animation]
name=default
speed=0.1000
loop=0
frames=0,1,2,3,4,5,6,7,6,5,4,3,2,1
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=bry.gif
frame_width=10
frame_height=16
[animation]
name=default
speed=0.1000
loop=0
frames=0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=chip.gif
frame_width=8
frame_height=16
[animation]
name=default
speed=0.1333
loop=0
frames=0,1,2,3
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=code.gif
frame_width=16
frame_height=16
[animation]
name=default
speed=0.1000
loop=0
frames=0,1,2,3
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=congo.gif
frame_width=8
frame_height=16
[animation]
name=default
speed=0.1000
loop=0
frames=0,1,2,3
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=crosshair.gif
frame_width=16
frame_height=16
[animation]
name=default
speed=0.1000
loop=0
frames=0,1,2,3
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=demon.gif
frame_width=16
frame_height=16
[animation]
name=default
speed=0.1333
loop=0
frames=0,1,2,3
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=dimallas.gif
frame_width=16
frame_height=16
[animation]
name=default
speed=0.1333
loop=0
frames=0,1,2,3
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=dong.gif
frame_width=22
frame_height=16
[animation]
name=default
speed=0.1000
loop=0
frames=0,1,2,3,4,5
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=elsa.gif
frame_width=16
frame_height=16
[animation]
name=default
speed=0.1000
loop=0
frames=0,1,2,3,4,5
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=floppy.gif
frame_width=16
frame_height=16
[animation]
name=default
speed=0.1333
loop=0
frames=0,1,2,3
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=flying_arounder.gif
frame_width=7
frame_height=7
[animation]
name=default
speed=0.1667
loop=0
frames=0
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=guitar.gif
frame_width=16
frame_height=16
[animation]
name=default
speed=0.1333
loop=0
frames=0,1,2,3
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=heavy.gif
frame_width=16
frame_height=16
[animation]
name=default
speed=0.1333
loop=0
frames=0,1,2,3
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=jailbattle_alien.gif
frame_width=13
frame_height=15
[animation]
name=default
speed=0.1000
loop=0
frames=0,1
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=jailbattle_human.gif
frame_width=11
frame_height=13
[animation]
name=default
speed=0.1000
loop=0
frames=0,1
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=jailer_#1.gif
frame_width=16
frame_height=16
[animation]
name=default
speed=0.0667
loop=0
frames=0,1,2,3
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=jailer_#2.gif
frame_width=16
frame_height=16
[animation]
name=default
speed=0.0667
loop=0
frames=0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,1,3,5,1,3,5,1,3,5
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=jailer_#3.gif
frame_width=16
frame_height=16
[animation]
name=default
speed=0.0667
loop=0
frames=0,1,2,3
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=jeannine.gif
frame_width=8
frame_height=16
[animation]
name=default
speed=0.1000
loop=0
frames=0,1,2,3
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=lamp.gif
frame_width=16
frame_height=16
[animation]
name=default
speed=0.0667
loop=0
frames=0,1
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=lord_abad.gif
frame_width=16
frame_height=16
[animation]
name=default
speed=0.1000
loop=0
frames=0,1,2,3
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=matatunos.gif
frame_width=16
frame_height=16
[animation]
name=default
speed=0.1333
loop=0
frames=0,1,2,3,4,5
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=mummy.gif
frame_width=8
frame_height=16
[animation]
name=default
speed=0.2000
loop=0
frames=0,1,2,3
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=paco.gif
frame_width=16
frame_height=16
[animation]
name=default
speed=0.0667
loop=0
frames=0,1,2,3,4,5,6,7
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=qvoid.gif
frame_width=16
frame_height=16
[animation]
name=default
speed=0.1333
loop=0
frames=0,1,2,3,4,5,6,7
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=robot.gif
frame_width=16
frame_height=32
[animation]
name=default
speed=0.0667
loop=0
frames=0,1,2,3
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=sam.gif
frame_width=16
frame_height=16
[animation]
name=default
speed=0.0833
loop=0
frames=0,1
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=shock.gif
frame_width=8
frame_height=8
[animation]
name=default
speed=0.1000
loop=0
frames=0,1,2,3,4,5,4,3,2,1
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=sigmasua.gif
frame_width=16
frame_height=16
[animation]
name=default
speed=0.1333
loop=0
frames=0,1,2,3
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=spark.gif
frame_width=8
frame_height=16
[animation]
name=default
speed=0.1000
loop=0
frames=0,1,2,3
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=aerojailer.gif
frame_width=43
frame_height=44
[animation]
name=default
speed=1.6667
loop=0
frames=0
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=arounder.gif
frame_width=79
frame_height=90
[animation]
name=default
speed=1.6667
loop=0
frames=0
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=pepe_rosita_job.gif
frame_width=62
frame_height=47
[animation]
name=default
speed=1.6667
loop=0
frames=0
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=shooting_star.gif
frame_width=64
frame_height=64
[animation]
name=default
speed=0.1000
loop=-1
frames=18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=spider.gif
frame_width=8
frame_height=8
[animation]
name=default
speed=0.0667
loop=0
frames=0,1,2,3
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=stopped_arounder.gif
frame_width=7
frame_height=8
[animation]
name=default
speed=0.1667
loop=0
frames=0,1,2,3
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=tree_thing.gif
frame_width=16
frame_height=16
[animation]
name=default
speed=0.1000
loop=0
frames=0,1,2,3,4,5,6,7,8,9,10,11,12
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=tuno.gif
frame_width=16
frame_height=16
[animation]
name=default
speed=0.1333
loop=0
frames=0,1,2,3,3,2,1,0
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=tv.gif
frame_width=16
frame_height=18
[animation]
name=default
speed=0.0833
loop=0
frames=0,1,2,3
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=tv_panel.gif
frame_width=24
frame_height=16
[animation]
name=default
speed=0.0667
loop=0
frames=0,1,2,3
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=upv_student.gif
frame_width=8
frame_height=16
[animation]
name=default
speed=0.1333
loop=0
frames=0,1,2,3
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=walking_arounder.gif
frame_width=5
frame_height=8
[animation]
name=default
speed=0.1000
loop=0
frames=0,1
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=wave.gif
frame_width=8
frame_height=8
[animation]
name=default
speed=0.1333
loop=0
frames=0,1,2,3
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=z80.gif
frame_width=16
frame_height=32
[animation]
name=default
speed=0.1333
loop=0
frames=0,1,2,3
[/animation]

View File

@@ -1,24 +0,0 @@
tileSetFile=player.gif
frame_width=8
frame_height=16
[animation]
name=stand
speed=0.1333
loop=0
frames=0
[/animation]
[animation]
name=walk
speed=0.1333
loop=0
frames=0,1,2,3
[/animation]
[animation]
name=walk_menu
speed=0.0
loop=0
frames=0,1,2,3
[/animation]

View File

@@ -1,24 +0,0 @@
tileSetFile=player2.gif
frame_width=8
frame_height=16
[animation]
name=stand
speed=0.1333
loop=0
frames=0
[/animation]
[animation]
name=walk
speed=0.1333
loop=0
frames=0,1,2,3,4,5,6,7
[/animation]
[animation]
name=walk_menu
speed=0.0
loop=0
frames=0,1,2,3,4,5,6,7
[/animation]

View File

@@ -1,10 +0,0 @@
tileSetFile=player_game_over.gif
frame_width=19
frame_height=18
[animation]
name=default
speed=0.1000
loop=0
frames=0,1,2,3
[/animation]

View File

@@ -13,36 +13,6 @@
#include "core/resources/resource_helper.hpp" // Para ResourceHelper #include "core/resources/resource_helper.hpp" // Para ResourceHelper
#include "utils/utils.hpp" // Para printWithDots #include "utils/utils.hpp" // Para printWithDots
// Carga las animaciones en un vector(Animations) desde un fichero
auto SurfaceAnimatedSprite::loadAnimationsFromFile(const std::string& file_path) -> Animations {
// Load file using ResourceHelper (supports both filesystem and pack)
auto file_data = Resource::Helper::loadFile(file_path);
if (file_data.empty()) {
std::cerr << "Error: Fichero no encontrado " << file_path << '\n';
throw std::runtime_error("Fichero no encontrado: " + file_path);
}
printWithDots("Animation : ", file_path.substr(file_path.find_last_of("\\/") + 1), "[ LOADED ]");
// Convert bytes to string and parse
std::string content(file_data.begin(), file_data.end());
std::istringstream stream(content);
std::vector<std::string> buffer;
std::string line;
while (std::getline(stream, line)) {
// Eliminar \r de Windows line endings
if (!line.empty() && line.back() == '\r') {
line.pop_back();
}
if (!line.empty()) {
buffer.push_back(line);
}
}
return buffer;
}
// Helper: Convierte un nodo YAML de frames (array) a vector de SDL_FRect // Helper: Convierte un nodo YAML de frames (array) a vector de SDL_FRect
auto convertYAMLFramesToRects(const fkyaml::node& frames_node, float frame_width, float frame_height, int frames_per_row, int max_tiles) -> std::vector<SDL_FRect> { auto convertYAMLFramesToRects(const fkyaml::node& frames_node, float frame_width, float frame_height, int frames_per_row, int max_tiles) -> std::vector<SDL_FRect> {
std::vector<SDL_FRect> frames; std::vector<SDL_FRect> frames;
@@ -154,65 +124,20 @@ auto SurfaceAnimatedSprite::loadAnimationsFromYAML(const std::string& file_path,
return animations; return animations;
} }
// Constructor // Constructor con datos pre-cargados del cache
SurfaceAnimatedSprite::SurfaceAnimatedSprite(const std::string& file_path) { SurfaceAnimatedSprite::SurfaceAnimatedSprite(const ResourceAnimation& cached_data)
// Carga las animaciones : SurfaceMovingSprite(cached_data.surface) {
if (!file_path.empty()) { // Copiar datos pre-cargados del cache
// Detectar extensión del archivo animations_ = cached_data.animations;
const bool IS_YAML = file_path.substr(file_path.find_last_of('.') + 1) == "yaml"; setWidth(cached_data.frame_width);
setHeight(cached_data.frame_height);
if (IS_YAML) { // Inicializar con la primera animación si existe
// Cargar desde YAML (formato nuevo) if (!animations_.empty() && !animations_[0].frames.empty()) {
float frame_width = 1.0F; setClip(animations_[0].frames[0]);
float frame_height = 1.0F;
animations_ = loadAnimationsFromYAML(file_path, surface_, frame_width, frame_height);
setWidth(frame_width);
setHeight(frame_height);
} else {
// Cargar desde .ani (formato legacy)
Animations v = SurfaceAnimatedSprite::loadAnimationsFromFile(file_path);
setAnimations(v);
}
} }
} }
// Constructor
SurfaceAnimatedSprite::SurfaceAnimatedSprite(const Animations& animations) {
if (!animations.empty()) {
setAnimations(animations);
}
}
// Constructor
SurfaceAnimatedSprite::SurfaceAnimatedSprite(std::shared_ptr<Surface> surface, const std::string& file_path)
: SurfaceMovingSprite(std::move(surface)) {
// Carga las animaciones
if (!file_path.empty()) {
// Detectar extensión del archivo
const bool IS_YAML = file_path.substr(file_path.find_last_of('.') + 1) == "yaml";
if (IS_YAML) {
// Cargar desde YAML (formato nuevo)
float frame_width = 1.0F;
float frame_height = 1.0F;
animations_ = loadAnimationsFromYAML(file_path, surface_, frame_width, frame_height);
setWidth(frame_width);
setHeight(frame_height);
} else {
// Cargar desde .ani (formato legacy)
Animations v = SurfaceAnimatedSprite::loadAnimationsFromFile(file_path);
setAnimations(v);
}
}
}
// Constructor
SurfaceAnimatedSprite::SurfaceAnimatedSprite(std::shared_ptr<Surface> surface, const Animations& animations)
: SurfaceMovingSprite(std::move(surface)) {
if (!animations.empty()) {
setAnimations(animations);
}
}
// Obtiene el indice de la animación a partir del nombre // Obtiene el indice de la animación a partir del nombre
auto SurfaceAnimatedSprite::getIndex(const std::string& name) -> int { auto SurfaceAnimatedSprite::getIndex(const std::string& name) -> int {
@@ -319,133 +244,6 @@ void SurfaceAnimatedSprite::resetAnimation() {
animations_[current_animation_].completed = false; animations_[current_animation_].completed = false;
} }
// Helper: Parsea los parámetros de configuración globales (frame_width, frame_height)
auto parseGlobalParameter(const std::string& line, std::shared_ptr<Surface>& surface, float& frame_width, float& frame_height) -> bool {
size_t pos = line.find('=');
if (pos == std::string::npos) {
return false;
}
std::string key = line.substr(0, pos);
if (key == "tileSetFile") {
std::string value = line.substr(pos + 1);
surface = Resource::Cache::get()->getSurface(value);
return true;
}
if (key == "frame_width") {
int value = std::stoi(line.substr(pos + 1));
frame_width = value;
return true;
}
if (key == "frame_height") {
int value = std::stoi(line.substr(pos + 1));
frame_height = value;
return true;
}
std::cout << "Warning: unknown parameter " << key << '\n';
return false;
}
// Helper: Parsea los frames de una animación desde una cadena separada por comas
void parseAnimationFrames(const std::string& value, SurfaceAnimatedSprite::AnimationData& animation, float frame_width, float frame_height, int frames_per_row, int max_tiles) {
std::stringstream ss(value);
std::string tmp;
SDL_FRect rect = {0.0F, 0.0F, frame_width, frame_height};
while (getline(ss, tmp, ',')) {
const int NUM_TILE = std::stoi(tmp);
if (NUM_TILE <= max_tiles) {
rect.x = (NUM_TILE % frames_per_row) * frame_width;
rect.y = (NUM_TILE / frames_per_row) * frame_height;
animation.frames.emplace_back(rect);
}
}
}
// Helper: Parsea un parámetro de animación individual
auto parseAnimationParameter(const std::string& key, const std::string& value, SurfaceAnimatedSprite::AnimationData& animation, float frame_width, float frame_height, int frames_per_row, int max_tiles) -> bool {
if (key == "name") {
animation.name = value;
return true;
}
if (key == "speed") {
// Soporta tanto float (segundos) como int (compatibilidad con sistema antiguo)
animation.speed = std::stof(value);
return true;
}
if (key == "loop") {
animation.loop = std::stoi(value);
return true;
}
if (key == "frames") {
parseAnimationFrames(value, animation, frame_width, frame_height, frames_per_row, max_tiles);
return true;
}
std::cout << "Warning: unknown parameter " << key << '\n';
return false;
}
// Helper: Parsea una animación completa
auto parseAnimation(const SurfaceAnimatedSprite::Animations& animations, size_t& index, float frame_width, float frame_height, int frames_per_row, int max_tiles) -> SurfaceAnimatedSprite::AnimationData {
SurfaceAnimatedSprite::AnimationData animation;
std::string line;
do {
index++;
line = animations.at(index);
size_t pos = line.find('=');
if (pos != std::string::npos) {
std::string key = line.substr(0, pos);
std::string value = line.substr(pos + 1);
parseAnimationParameter(key, value, animation, frame_width, frame_height, frames_per_row, max_tiles);
}
} while (line != "[/animation]");
return animation;
}
// Carga la animación desde un vector de cadenas
void SurfaceAnimatedSprite::setAnimations(const Animations& animations) {
float frame_width = 1.0F;
float frame_height = 1.0F;
int frames_per_row = 1;
int max_tiles = 1;
size_t index = 0;
while (index < animations.size()) {
const std::string& line = animations.at(index);
// Parsea el fichero para buscar variables y valores
if (line != "[animation]") {
if (parseGlobalParameter(line, surface_, frame_width, frame_height)) {
if (surface_) {
frames_per_row = surface_->getWidth() / frame_width;
const int W = surface_->getWidth() / frame_width;
const int H = surface_->getHeight() / frame_height;
max_tiles = W * H;
}
}
}
// Si la linea contiene el texto [animation] se realiza el proceso de carga de una animación
if (line == "[animation]") {
SurfaceAnimatedSprite::AnimationData animation = parseAnimation(animations, index, frame_width, frame_height, frames_per_row, max_tiles);
animations_.emplace_back(animation);
}
// Una vez procesada la linea, aumenta el indice para pasar a la siguiente
index++;
}
// Pone un valor por defecto
setWidth(frame_width);
setHeight(frame_height);
}
// Establece el frame actual de la animación // Establece el frame actual de la animación
void SurfaceAnimatedSprite::setCurrentAnimationFrame(int num) { void SurfaceAnimatedSprite::setCurrentAnimationFrame(int num) {
// Descarta valores fuera de rango // Descarta valores fuera de rango

View File

@@ -10,6 +10,7 @@
#include "core/rendering/surface_moving_sprite.hpp" // Para SMovingSprite #include "core/rendering/surface_moving_sprite.hpp" // Para SMovingSprite
class Surface; class Surface;
struct ResourceAnimation; // Forward declaration
class SurfaceAnimatedSprite : public SurfaceMovingSprite { class SurfaceAnimatedSprite : public SurfaceMovingSprite {
public: public:
@@ -27,16 +28,10 @@ class SurfaceAnimatedSprite : public SurfaceMovingSprite {
}; };
// Métodos estáticos // Métodos estáticos
static auto loadAnimationsFromFile(const std::string& file_path) -> Animations; // Carga las animaciones desde fichero .ani static auto loadAnimationsFromYAML(const std::string& file_path, std::shared_ptr<Surface>& surface, float& frame_width, float& frame_height) -> std::vector<AnimationData>; // Carga las animaciones desde fichero YAML
static auto loadAnimationsFromYAML(const std::string& file_path, std::shared_ptr<Surface>& surface, float& frame_width, float& frame_height) -> std::vector<AnimationData>; // Carga las animaciones desde fichero .yaml
// Constructores // Constructores
explicit SurfaceAnimatedSprite(const std::string& file_path); explicit SurfaceAnimatedSprite(const ResourceAnimation& cached_data); // Constructor con datos pre-cargados del cache
explicit SurfaceAnimatedSprite(const Animations& animations);
SurfaceAnimatedSprite(std::shared_ptr<Surface> surface, const std::string& file_path);
SurfaceAnimatedSprite(std::shared_ptr<Surface> surface, const Animations& animations);
explicit SurfaceAnimatedSprite(std::shared_ptr<Surface> surface)
: SurfaceMovingSprite(std::move(surface)) {}
~SurfaceAnimatedSprite() override = default; // Destructor ~SurfaceAnimatedSprite() override = default; // Destructor
@@ -55,15 +50,9 @@ class SurfaceAnimatedSprite : public SurfaceMovingSprite {
protected: protected:
// Métodos protegidos // Métodos protegidos
void animate(float delta_time); // Calcula el frame correspondiente a la animación actual (time-based) void animate(float delta_time); // Calcula el frame correspondiente a la animación actual (time-based)
void setAnimations(const Animations& animations); // Carga la animación desde un vector de cadenas
private: private:
// Funciones amigas (helper functions del .cpp)
friend void parseAnimationFrames(const std::string& value, AnimationData& animation, float frame_width, float frame_height, int frames_per_row, int max_tiles);
friend auto parseAnimationParameter(const std::string& key, const std::string& value, AnimationData& animation, float frame_width, float frame_height, int frames_per_row, int max_tiles) -> bool;
friend auto parseAnimation(const Animations& animations, size_t& index, float frame_width, float frame_height, int frames_per_row, int max_tiles) -> AnimationData;
// Variables miembro // Variables miembro
std::vector<AnimationData> animations_; // Vector con las diferentes animaciones std::vector<AnimationData> animations_; // Vector con las diferentes animaciones
int current_animation_{0}; // Animación activa int current_animation_{0}; // Animación activa

View File

@@ -148,12 +148,12 @@ auto Cache::getText(const std::string& name) -> std::shared_ptr<Text> {
throw std::runtime_error("Texto no encontrado: " + name); throw std::runtime_error("Texto no encontrado: " + name);
} }
// Obtiene la animación a partir de un nombre // Obtiene los datos de animación parseados a partir de un nombre
auto Cache::getAnimations(const std::string& name) -> SurfaceAnimatedSprite::Animations& { auto Cache::getAnimationData(const std::string& name) -> const ResourceAnimation& {
auto it = std::ranges::find_if(animations_, [&name](const auto& a) { return a.name == name; }); auto it = std::ranges::find_if(animations_, [&name](const auto& a) { return a.name == name; });
if (it != animations_.end()) { if (it != animations_.end()) {
return it->animation; return *it;
} }
std::cerr << "Error: Animación no encontrada " << name << '\n'; std::cerr << "Error: Animación no encontrada " << name << '\n';
@@ -300,7 +300,14 @@ void Cache::loadAnimations() {
for (const auto& l : list) { for (const auto& l : list) {
auto name = getFileName(l); auto name = getFileName(l);
animations_.emplace_back(name, SurfaceAnimatedSprite::loadAnimationsFromFile(l));
// Parsear YAML y almacenar datos pre-cargados
std::shared_ptr<Surface> surface;
float frame_width = 0.0F;
float frame_height = 0.0F;
auto animation_data = SurfaceAnimatedSprite::loadAnimationsFromYAML(l, surface, frame_width, frame_height);
animations_.emplace_back(name, animation_data, surface, frame_width, frame_height);
updateLoadingProgress(); updateLoadingProgress();
} }
} }

View File

@@ -80,13 +80,19 @@ struct ResourceText {
// Estructura para almacenar ficheros animaciones y su nombre // Estructura para almacenar ficheros animaciones y su nombre
struct ResourceAnimation { struct ResourceAnimation {
std::string name; // Nombre del fichero std::string name; // Nombre del fichero
SurfaceAnimatedSprite::Animations animation; // Objeto con las animaciones std::vector<SurfaceAnimatedSprite::AnimationData> animations; // Datos de animaciones parseadas desde YAML
std::shared_ptr<Surface> surface; // Surface asociada al sprite sheet
float frame_width{0.0F}; // Ancho de cada frame
float frame_height{0.0F}; // Alto de cada frame
// Constructor // Constructor
ResourceAnimation(std::string name, SurfaceAnimatedSprite::Animations animation) ResourceAnimation(std::string name, std::vector<SurfaceAnimatedSprite::AnimationData> animations, std::shared_ptr<Surface> surface, float frame_width, float frame_height)
: name(std::move(name)), : name(std::move(name)),
animation(std::move(animation)) {} animations(std::move(animations)),
surface(std::move(surface)),
frame_width(frame_width),
frame_height(frame_height) {}
}; };
// Estructura para almacenar ficheros con el mapa de tiles de una habitación y su nombre // Estructura para almacenar ficheros con el mapa de tiles de una habitación y su nombre
@@ -244,8 +250,8 @@ class Cache {
// Obtiene el objeto de texto a partir de un nombre // Obtiene el objeto de texto a partir de un nombre
auto getText(const std::string& name) -> std::shared_ptr<Text>; auto getText(const std::string& name) -> std::shared_ptr<Text>;
// Obtiene la animación a partir de un nombre // Obtiene los datos de animación parseados a partir de un nombre
auto getAnimations(const std::string& name) -> SurfaceAnimatedSprite::Animations&; auto getAnimationData(const std::string& name) -> const ResourceAnimation&;
// Obtiene el mapa de tiles a partir de un nombre // Obtiene el mapa de tiles a partir de un nombre
auto getTileMap(const std::string& name) -> std::vector<int>&; auto getTileMap(const std::string& name) -> std::vector<int>&;

View File

@@ -10,8 +10,7 @@
// Constructor // Constructor
Enemy::Enemy(const Data& enemy) Enemy::Enemy(const Data& enemy)
// [DOC:29/10/2025] la surface ara se pillarà del .ANI : sprite_(std::make_shared<SurfaceAnimatedSprite>(Resource::Cache::get()->getAnimationData(enemy.animation_path))),
: sprite_(std::make_shared<SurfaceAnimatedSprite>(/*Resource::Cache::get()->getSurface(enemy.surface_path), */ Resource::Cache::get()->getAnimations(enemy.animation_path))),
color_string_(enemy.color), color_string_(enemy.color),
x1_(enemy.x1), x1_(enemy.x1),
x2_(enemy.x2), x2_(enemy.x2),

View File

@@ -809,8 +809,8 @@ void Player::applySpawnValues(const SpawnData& spawn) {
// Inicializa el sprite del jugador // Inicializa el sprite del jugador
void Player::initSprite(const std::string& animations_path) { void Player::initSprite(const std::string& animations_path) {
auto animations = Resource::Cache::get()->getAnimations(animations_path); const auto& animation_data = Resource::Cache::get()->getAnimationData(animations_path);
sprite_ = std::make_unique<SurfaceAnimatedSprite>(animations); sprite_ = std::make_unique<SurfaceAnimatedSprite>(animation_data);
sprite_->setWidth(WIDTH); sprite_->setWidth(WIDTH);
sprite_->setHeight(HEIGHT); sprite_->setHeight(HEIGHT);
sprite_->setCurrentAnimation("walk"); sprite_->setCurrentAnimation("walk");

View File

@@ -21,9 +21,8 @@ Scoreboard::Scoreboard(std::shared_ptr<Data> data)
constexpr float SURFACE_HEIGHT = 6.0F * TILE_SIZE; constexpr float SURFACE_HEIGHT = 6.0F * TILE_SIZE;
// Reserva memoria para los objetos // Reserva memoria para los objetos
// auto player_texture = Resource::Cache::get()->getSurface(Options::cheats.alternate_skin == Options::Cheat::State::ENABLED ? "player2.gif" : "player.gif"); const auto& player_animation_data = Resource::Cache::get()->getAnimationData(Options::cheats.alternate_skin == Options::Cheat::State::ENABLED ? "player2.yaml" : "player.yaml");
auto player_animations = Resource::Cache::get()->getAnimations(Options::cheats.alternate_skin == Options::Cheat::State::ENABLED ? "player2.yaml" : "player.yaml"); player_sprite_ = std::make_shared<SurfaceAnimatedSprite>(player_animation_data);
player_sprite_ = std::make_shared<SurfaceAnimatedSprite>(player_animations);
player_sprite_->setCurrentAnimation("walk_menu"); player_sprite_->setCurrentAnimation("walk_menu");
surface_ = std::make_shared<Surface>(SURFACE_WIDTH, SURFACE_HEIGHT); surface_ = std::make_shared<Surface>(SURFACE_WIDTH, SURFACE_HEIGHT);

View File

@@ -23,7 +23,7 @@
Credits::Credits() Credits::Credits()
: text_surface_(std::make_shared<Surface>(Options::game.width, Options::game.height)), : text_surface_(std::make_shared<Surface>(Options::game.width, Options::game.height)),
cover_surface_(std::make_shared<Surface>(Options::game.width, Options::game.height)), cover_surface_(std::make_shared<Surface>(Options::game.width, Options::game.height)),
shining_sprite_(std::make_shared<SurfaceAnimatedSprite>(Resource::Cache::get()->getAnimations("shine.yaml"))), shining_sprite_(std::make_shared<SurfaceAnimatedSprite>(Resource::Cache::get()->getAnimationData("shine.yaml"))),
delta_timer_(std::make_unique<DeltaTimer>()) { delta_timer_(std::make_unique<DeltaTimer>()) {
// Configura la escena // Configura la escena
SceneManager::current = SceneManager::Scene::CREDITS; SceneManager::current = SceneManager::Scene::CREDITS;

View File

@@ -287,7 +287,8 @@ void Ending2::loadSprites() {
// Carga los sprites // Carga los sprites
for (const auto& file : sprite_list_) { for (const auto& file : sprite_list_) {
sprites_.emplace_back(std::make_shared<SurfaceAnimatedSprite>(Resource::Cache::get()->getAnimations(file + ".yaml"))); const auto& animation_data = Resource::Cache::get()->getAnimationData(file + ".yaml");
sprites_.emplace_back(std::make_shared<SurfaceAnimatedSprite>(animation_data));
sprite_max_width_ = std::max(sprites_.back()->getWidth(), sprite_max_width_); sprite_max_width_ = std::max(sprites_.back()->getWidth(), sprite_max_width_);
sprite_max_height_ = std::max(sprites_.back()->getHeight(), sprite_max_height_); sprite_max_height_ = std::max(sprites_.back()->getHeight(), sprite_max_height_);
} }

View File

@@ -21,8 +21,8 @@
// Constructor // Constructor
GameOver::GameOver() GameOver::GameOver()
: player_sprite_(std::make_shared<SurfaceAnimatedSprite>(Resource::Cache::get()->getAnimations("player_game_over.yaml"))), : player_sprite_(std::make_shared<SurfaceAnimatedSprite>(Resource::Cache::get()->getAnimationData("player_game_over.yaml"))),
tv_sprite_(std::make_shared<SurfaceAnimatedSprite>(Resource::Cache::get()->getAnimations("tv.yaml"))), tv_sprite_(std::make_shared<SurfaceAnimatedSprite>(Resource::Cache::get()->getAnimationData("tv.yaml"))),
delta_timer_(std::make_shared<DeltaTimer>()) { delta_timer_(std::make_shared<DeltaTimer>()) {
SceneManager::current = SceneManager::Scene::GAME_OVER; SceneManager::current = SceneManager::Scene::GAME_OVER;
SceneManager::options = SceneManager::Options::NONE; SceneManager::options = SceneManager::Options::NONE;