Exportar a motores

La ventana Exportar

Exportar (Ctrl+E) está justo después de Importar… en la cabecera de la ventana, y abre una ventana dibujada como la de Importar (D51):

  1. Pipeline de Asset: el que muestra el selector Asset de la cabecera, para empezar. Lo que escribe se diseña en el grafo de Asset.
  2. Carpeta de exportación: escribe una ruta, o Elegir… una. El proyecto la conserva.
  3. Exportar ahora: el proyecto tal como está abierto, guardado o no: exportar nunca lo guarda, y un proyecto sin título se exporta tal cual.

La ventana Exportar: el pipeline de asset, la carpeta, los archivos que escribirá y el botón Exportar

Antes de pulsar Exportar, la ventana lista cada archivo que escribirá la exportación, tal como los nombra pxr names: cada uno por su ruta en la carpeta y su tipo (hoja de sprites, JSON, GIF…), y se reemplazará en un archivo que la carpeta ya tiene. La lista se vuelve a calcular (con un pequeño indicador de carga, sin bloquear nunca la ventana) cuando cambias el pipeline de Asset, la carpeta o el proyecto. Un pipeline que no se puede exportar tal como está (dos salidas que escriben un mismo archivo, por ejemplo) dice por qué ahí mismo, y Exportar espera hasta que se corrija.

Al pulsarlo, esas mismas filas, en sus lugares, son la exportación: cada una con un indicador de carga hasta que se escribe, luego una marca, su tamaño, Abrir (en el programa con el que lo abre tu sistema) y Mostrar carpeta. Lo que falla se indica en el archivo en el que se detuvo. Detener termina una exportación a medias: lo escrito se queda, y el archivo que se estaba escribiendo se elimina. La ventana se puede cerrar mientras se ejecuta; Exportar la vuelve a abrir.

Ejecuta exactamente lo que ejecuta la línea de comandos: pxr render PROJECT --pipeline NAME -o FOLDER, en un proceso propio, para que Pixor siga respondiendo, sobre una instantánea del proyecto tal como está abierto, escrita en la carpeta generada (con las rutas de sus archivos convertidas en absolutas) y eliminada cuando termina la exportación. Los archivos se nombran como pxr render nombra los de ese proyecto: según el proyecto, o, si no tiene título, según su modelo. Cada archivo se escribe de nuevo desde el pipeline: lo que Generar de los nodos del grafo de Asset produce nunca se copia.

Cada archivo va a la carpeta. La hoja toma su nombre de archivo del nodo PNG del proyecto (out/hero.png escribe FOLDER/hero.png); un archivo cuya ruta está bajo la carpeta de la hoja conserva su lugar debajo de FOLDER, y cualquier otra ruta (un archivo comprimido, una animación, iconos con nombre en otro sitio) conserva solo su última parte.

Lo que escribe una exportación

Cada exportación escribe una hoja: una fila por acción y lado, una columna por fotograma, todas las celdas del mismo tamaño, con el pivote en el mismo píxel en cada una. Añade nodos Archivo a la hoja en el grafo de Asset (o usa --export en la línea de comandos) para obtener archivos junto a ella con el mismo nombre. Cada uno es un nodo conectado desde la hoja, con sus propios ajustes. --export all escribe todos los formatos de abajo excepto p8 y video, que solo se escriben cuando se nombran: un cartucho solo encaja con una hoja hecha para uno, y un vídeo sin comprimir de cada clip y lado puede ocupar gigabytes. Nunca escriben dos el mismo archivo: pxr names rechaza un proyecto en el que dos lo harían.

Formato Archivo Para
png name.png la hoja, un PNG indexado (índice 0 transparente)
json name.json rectángulos de celda, duraciones de fotograma, una etiqueta por acción y lado, el pivote. El formato «array» de Aseprite, para que lo lean los importadores escritos para Aseprite
aseprite name.aseprite un archivo de Aseprite indexado: capas final, lines, flat y una por cada salida adicional del grafo de Estilo; una etiqueta por acción y lado; duraciones por fotograma; un slice pivot
normal name_normal.png un mapa de normales con la misma disposición, para iluminación 2D
profundidad name_depth.png profundidad con la misma disposición: blanco lo más cercano, oscuro lo más lejano, una sola escala para toda la hoja (meta.pixor.depth da ambos en metros); transparente donde no hay nada. Para ordenar, niebla e iluminación 2.5D
emisión name_emission.png cada píxel luminoso en su propio color, tan brillante como brilla (un material luminoso o el mapa emisivo del modelo); transparente en el resto. Para resplandor y bloom
capas name_lines.png, name_flat.png y name_LAYER.png por cada salida adicional del grafo de Estilo las capas de líneas y de color plano como hojas, y la imagen de un nodo donde el grafo de Estilo nombre una
paleta name.hex, name.gpl la paleta (formatos de Lospec y GIMP)
godot name.tres un recurso SpriteFrames de Godot 4
gif name_walk_Southeast.gif, … un GIF animado por acción y lado, con las duraciones como retardos de fotograma, para compartir y para vistas previas
apng name_walk_Southeast.apng, … lo mismo como PNG animados, con retardos exactos en milisegundos
vídeo name_walk_Southeast.avi, … un vídeo por acción y lado: un AVI sin comprimir, cada píxel tal cual, para un tráiler o una página de tienda
light-kit name_ramps.png, name_normal.png, name_light.png, shaders iluminación fiel a la paleta en los motores (consulta más abajo)
informe name_report.png la hoja con los hallazgos de cada comprobación marcados (consulta más abajo)
p8 name.p8 un cartucho de PICO-8 (consulta Modos de consola)
zip la ruta en su nodo un nodo Archivo ZIP en el grafo de Asset: los archivos conectados a él, o todo lo que escribió la exportación

Una fila lleva el nombre de su acción y su lado: walk_Southeast.

Qué fotogramas toma una hoja, cómo se disponen y cuántos archivos escribe un render es cosa del grafo de Asset: un nodo Hoja y sus nodos Archivo, hasta que lo vuelvas a conectar.

Cómo se llaman los fotogramas y qué son

Cada fotograma de una hoja tiene un nombre y un id, y responden a dos preguntas distintas.

El nombre es una plantilla, un patrón sobre las propias palabras de tu proyecto, así que el valor predeterminado sencillo es lo que quiere un principiante, y un estudio puede seguir una convención que no eligió:

{project}_{action}_{side}_{index:2}.{ext}     hero_walk_East_00.png

Las palabras son {project}, {object}, {action}, {side}, {layer}, {set} (el conjunto de partes con el que un nodo Sprites dibujó el fotograma), {size}, {index} y {ext}. {index:3} rellena un número con ceros hasta tres dígitos. {{ y }} escriben una llave. Una palabra que Pixor no conoce es un error cuando escribes la plantilla, no un archivo llamado hero_{genre}_00.png, y una palabra vacía se lleva consigo el separador que la precede, así que un sprite sin lado es hero_Static_00.png.

Un valor que no puede formar parte de un nombre de archivo (/ \ : * ? " < > |) se rechaza en lugar de sustituirse en silencio; un espacio se convierte en _. La única excepción es la palabra propia de Pixor: un clip de la biblioteca llamado lib:walk es lib-walk en un nombre, porque esos dos puntos son de Pixor y no tuyos.

Dos fotogramas que acabarían con el mismo nombre se rechazan antes de renderizar nada. Fíjalo con --names en la línea de comandos, o guárdalo en el proyecto:

pxr project set hero.pixor --names '{object}/{action}-{side}-{index:3}.{ext}'
pxr names hero.pixor                  # what it will write, without rendering
pxr names hero.pixor --json           # the same, for a build script

El id dice qué es un fotograma, nunca dónde acabó. Es un hash del objeto, la acción, el lado, el tiempo dentro de la acción y la capa, y se escribe junto a cada fotograma en el JSON y en los datos de usuario del .aseprite. Reempaquetar una hoja, añadir un clip o cambiar el relleno mueve rectángulos y no toca los ids, así que una build que se refiere a los fotogramas por id no se rompe cada vez que se ejecuta el empaquetador. Volver a muestrear un clip a otra velocidad de fotogramas sí cambia sus ids, porque son fotogramas distintos.

Hojas más pequeñas

En el nodo Organizar del grafo de Asset (o en la línea de comandos):

  • Recortar el espacio vacío (--trim) recorta cada fotograma hasta sus píxeles. El JSON da la posición de cada fotograma dentro de la celda completa (spriteSourceSize, trimmed: true) y el archivo de Godot fija el margin de cada fotograma, así que los motores siguen colocando cada fotograma sobre el pivote.
  • Guardar una sola vez los fotogramas repetidos (--dedupe): los fotogramas exactamente iguales (poses mantenidas, lados de un objeto quieto) comparten un mismo hueco.
  • Ancho máximo de la hoja (--max-width 4096) empieza una fila nueva antes de que la hoja se ensanche más, para motores y GPU con un límite de tamaño de textura.
  • Alto máximo de la hoja (--max-height 2048) divide una hoja más alta que eso en páginas, con clips enteros por página: hero_1.png, hero_2.png, cada una con su propio JSON y los demás archivos al lado.
  • Fotogramas por fila (--columns 8) pone tantos fotogramas en una fila, con cada clip a continuación del anterior: una hoja de contactos, o la cuadrícula fija que pide el importador de un motor.
  • Un lado dibujado a partir de otro (el nodo Voltear del grafo de asset): un modelo con simetría izquierda-derecha se ve igual desde la izquierda que una vista volteada desde la derecha, así que el lado oeste no hace falta renderizarlo: toma los sprites de la cámara este, voltéalos como Oeste, y la hoja tiene walk_West dibujado a partir de walk_East, con píxeles, normales, cajas y root motion reflejados. Renderiza solo las cámaras que difieren; voltea el resto.
  • Los grados de cada lado están en el JSON: en cada fotograma (pixor.degrees) y, para todos ellos, bajo meta.pixor.sides ({"South": 0, "Southeast": 45, ...}): grados desde el frente, en sentido antihorario visto desde arriba, como los toma --sides. Un juego convierte un ángulo en una fila con esa tabla.

Capa de sombra

Capa de sombra (--shadow contact o --shadow drop) escribe name_shadow.png, dispuesta como la hoja: negro donde cae la sombra, transparente en el resto. De contacto es una mancha bajo los pies del tamaño de la huella del modelo; Proyectada es la silueta proyectada sobre el suelo en dirección contraria a la luz principal. Dibújala bajo tus sprites con la opacidad que quieras, u ordénala por separado. El nodo Capa de un grafo de Asset puede nombrar shadow, y una Superposición la pone bajo el sprite en una sola hoja (grafo de Asset).

Ciclo de color en tiempo de ejecución

Con materiales cíclicos, el JSON lista cada uno bajo meta.pixor.cycles ("material" y sus "indices" en la paleta, en el orden del ciclo), y Pixor escribe name_index.png, la hoja como índices de paleta. Un motor puede rotar esas entradas de la paleta en cada tick en lugar de guardar más fotogramas. Otros materiales que comparten los mismos tonos ciclan con ellos, como en cualquier ciclo de paleta; da a un material cíclico sus propios colores para mantenerlo aparte.

Escenas de varios modelos y fondos con parallax

Un proyecto puede contener más de una cosa: modelos dispuestos sobre un plano de suelo y renderizados como una sola imagen, con una luz y sombras entre ellos: un rincón de una aldea, una sala de mazmorra, un campamento, arte para la página de la tienda a partir de la biblioteca gratuita.

Cada uno es un objeto: un modelo, dónde está, hacia dónde mira y qué tamaño tiene; un nodo Objeto del grafo de Escena, añadido al final de su cadena, que un anillo o una dispersión posteriores repiten. En la línea de comandos, cada --item es uno:

pxr project new camp.pixor \
  --item tent.glb@-1.8,-1.6,25,1.2 \
  --item campfire.pixoritem@0,0 \
  --item barrel.glb@2,1,0,1,2 \
  --ground 7,5,#5d7a45 \
  --size 200
pxr render camp.pixor

@x,z[,yaw[,scale[,layer]]] es donde está un objeto (en metros, x a la derecha, z hacia la cámara); --ground W,D[,#rrggbb] pone un plano de suelo debajo. Añade :clip[,phase] y ese objeto reproduce un clip propio, en su propio punto, mientras los de al lado se quedan quietos. Las rutas son relativas al proyecto.

Las capas de parallax (un nodo Archivo Capas de parallax, de 2 a 8 capas, o --parallax N) dividen la imagen por profundidad en capas para un fondo con desplazamiento: cada una se renderiza sola en el mismo escenario y con la misma paleta, y las capas más lejanas se desvanecen hacia tonos más oscuros y azulados, hacia el color de la bruma (--haze), como se ve la distancia (desactivar Bruma en capas lejanas, o --haze none, mantiene cada capa en la paleta tal cual, para un juego cuya paleta es fija). La capa de un objeto lo pone en una capa (0 es la más lejana); los demás se reparten por profundidad. Pixor escribe name_layer0.png, name_layer1.png, …, name_parallax.json (la imagen de cada capa y una velocidad de desplazamiento sugerida, de 0.25 para la más lejana a 1 para la más cercana) y name_parallax.png, las capas apiladas. Cualquier modelo se puede dividir, no solo una escena de varios. El nodo Capa de un grafo de Asset nombra una capa como layer0, layer1, … para ponerla en una hoja propia (grafo de Asset). pxr project set --parallax N --haze #rrggbb|none fija ambos en un proyecto.

Modos de la consola

Para consolas homebrew y de fantasía, elige una Consola en Estilo (o --console). Pixor usa entonces los colores propios de la consola y sus límites:

Consola Colores Por sprite Notas
Game Boy los 4 tonos de verde 3 + transparente tonos por luminosidad
NES la paleta maestra de 54 colores 3 + transparente también se comprueba por tile de 8 × 8
PICO-8 su 16 todos 16 exporta un cartucho .p8 (marca p8; la hoja debe caber en 128 × 128: pon un ancho máximo de 128)
TIC-80 su 16 (Sweetie 16) todos 16 importa el PNG con import sprites de TIC-80
C64 su 16 3 + transparente sprites multicolor: píxeles el doble de anchos; mantén el ancho par (los sprites de C64 son de 24 px)

Cuando un sprite solo puede usar tres colores, Pixor elige los tres colores de la consola que mejor cubren tu modelo en sombra, color base y luz, para que cada fotograma y lado use los mismos tres. La sección Estilo dice si el fotograma en pantalla encaja; pxr console check sheet.png comprueba una hoja entera (colores, colores por fotograma y por tile, pares de doble ancho, tamaño) y lee la consola de la receta guardada en la hoja. Cada render en un modo de consola hace la misma comprobación sobre la hoja que escribió, y falla (código de salida 1, con los problemas listados) cuando no encaja. Una paleta propia se conserva en un modo de consola, no se sustituye por la de la consola, así que una paleta de dieciséis colores en una Game Boy se señala, bien alto, en vez de cambiarse en silencio por los cuatro verdes. Pixor calcula los colores de la NES a partir de la señal de vídeo de la consola; los demás son los valores publicados de las consolas.

Iluminación fiel a la paleta en los motores

Los motores iluminan los sprites a partir de mapas de normales con un sombreado suave, que introduce colores que tu paleta nunca tuvo. Marca Kit de luz (o --export light-kit) y los sprites reaccionan a la luz del juego mientras cada píxel iluminado se queda en un paso de su propia rampa de color, con las bandas, el desplazamiento de tono y los brillos de Pixor. Pixor escribe, junto a la hoja:

Archivo Qué es
name_ramps.png la rampa de color de cada píxel (número de rampa + 1 en rojo; 0 para los píxeles que la luz no toca, como las líneas)
name_normal.png las normales, en espacio de vista: x a la derecha, y hacia arriba, z hacia la cámara
name_light.png la tabla de consulta: una fila por rampa, una columna por nivel de luz, luego el color del brillo y luego dos columnas que no son colores en absoluto: los umbrales de brillo propios de esa rampa, porque un material brillante o metálico toma su brillo con más facilidad que uno mate
pixor_palette_light.gdshader, name_light.tres el shader de Godot y un material con todas las texturas asignadas: pon el material en un Sprite2D o un AnimatedSprite2D
PixorPaletteLight.shader el shader de Unity: haz un material con él para un SpriteRenderer y asigna sus tres mapas
pixor_palette_light.fsh, .vsh el shader de GameMaker; los comentarios muestran cómo enlazar los mapas

Los shaders iluminan con una luz principal (light_dir, hacia la luz, en el espacio de las normales), la luz de relleno del preset, y brillos especulares y de contorno cuyos umbrales vienen de la textura de consulta, por rampa, como hacía el propio Pixor. Poner specular o rim a un número entre -1 y 1 los sustituye para todo el sprite; por encima de 1 desactiva esos brillos; por debajo de -1 (el valor por defecto) usa los de la consulta. Un brillo solo se dibuja donde uno de los cuatro píxeles vecinos también lo tiene, que es la regla propia de Pixor contra un píxel brillante aislado; min_highlight 1 la desactiva. Mueve la luz desde un script, por ejemplo hacia una antorcha: material.set_shader_parameter("light_dir", dir). Importa los tres mapas sin filtrado, sin compresión y sin mipmaps. Para verlo antes de exportar, activa la Vista previa de iluminación 2D (L) sobre el sprite y elige Light as: the light kit: la luz se orienta hacia el puntero y el fotograma se ilumina con la misma consulta y las mismas reglas (brillos solo junto a otro, píxeles sin rampa intactos) con que lo iluminan los shaders. Con la luz del render, un fotograma se ve exactamente como lo dibujó Pixor (salvo unos pocos píxeles en los bordes de banda); las sombras proyectadas, el tramado y el suavizado del parpadeo de las hojas animadas son solo de Pixor, así que desactiva las sombras proyectadas en las hojas que ilumines en el motor. El JSON lista los archivos y la luz bajo meta.pixor.light_kit.

Variantes de paleta

Añadir variante (--variant NAME, repetible) exporta la misma hoja en otros colores. Pixor dibuja con índices de paleta, así que una variante solo cambia la paleta: cada píxel, línea y tono se queda donde está.

  • Efectos: hit-flash, frozen, poisoned, petrified, burning, silhouette, selected, las horas del día dawn, noon, dusk, night, y las estaciones autumn y winter (los verdes se vuelven naranjas, o pálidos y nevados).
  • Colores de equipo: team:blue (o red, green, yellow, purple, orange, teal, pink, white, black, o team:#3050e0) cambia el color solo del color de equipo —los materiales o colores marcados con --team o en Materiales— y deja la piel, el acero y el oro como están. Cada tono conserva su luminosidad, así que la rampa se sigue leyendo. Cuatro equipos a partir de un sprite: --team cloth --variant team:red --variant team:blue --variant team:green --variant team:yellow. El JSON enumera los índices de paleta del equipo en meta.pixor.team, para los motores que cambian el color en tiempo de ejecución mediante la textura de consulta que se describe abajo.
  • Todos los colores girados: hue:120 gira cada tono con color 120 grados; los grises siguen siendo grises.
  • Otras paletas: palette:pixor-8 o palette:my-colours.hex lleva cada color al más cercano de esa paleta, manteniendo separados los claros y los oscuros.

Cada variante es name_<variant>.png. Con cualquier variante, Pixor escribe también dos archivos para cambiar de paleta en tiempo de ejecución, de modo que una sola hoja sirve para cada nivel y cada equipo:

  • name_index.png: la hoja con el índice de paleta de cada píxel como valor de gris (0 es transparente);
  • name_lut.png: una textura de consulta de 256 píxeles de ancho, una fila por paleta (la fila 0, la de la propia hoja; la fila k, la variante k).

Un shader consulta lut(index / 255, row). El JSON enumera las variantes y sus filas en meta.pixor.variants.

La receta dentro de cada exportación

Cada archivo que exporta Pixor recuerda el proyecto que lo creó: la hoja, sus hojas de capas y mapas (_lines, _flat, _normal, _depth, _emission, _shadow), sus variantes de paleta y hoja de índices, el .aseprite, y cada GIF (en un comentario) y APNG. Suelta cualquiera de ellos en Pixor (o elígelo en Abrir proyecto…) para recuperar el proyecto: el archivo .pixor si sigue ahí, o un proyecto nuevo reconstruido a partir de la receta. Las rutas se guardan relativas al archivo exportado; una ruta que no puede hacerse relativa conserva solo el nombre del archivo, así que una hoja que compartes no muestra los nombres de tus carpetas. Desmarca Receta en archivos (o pasa --no-recipe) para no incluirla.

Godot 4

  1. Copia name.png y name.tres en tu proyecto, uno junto al otro.
  2. El .tres carga la hoja desde res://name.png. Si la pones en otro sitio, pasa --godot-path res://path/name.png al exportar desde la línea de comandos, o edita la ruta al principio del .tres.
  3. Crea un AnimatedSprite2D y ajusta su Sprite Frames a name.tres. Cada acción y lado es una animación, en bucle, con las duraciones de sus fotogramas.
  4. Para tener píxeles nítidos, ajusta Texture > Filter a Nearest.

Unity

  • Con el paquete Aseprite Importer (2D Aseprite Importer): suelta name.aseprite en Assets. Cada etiqueta se convierte en un clip de animación; usa la capa final.
  • Sin él: importa name.png como Sprite (Multiple), Filter Mode Point, Compression None, y córtalo por tamaño de celda (el tamaño de celda está en name.json, en meta.pixor.cell). El pivote está en meta.pixor.pivot, en píxeles desde la esquina superior izquierda de la celda.

GameMaker

Importa name.png como una tira de sprites: usa una exportación con disposición Strip (--layout strip) por animación o corta la cuadrícula por tamaño de celda. Pon el origen en el pivote de name.json.

Aseprite

Abre name.aseprite, o haz clic en Abrir en el nodo del archivo de Aseprite (Pixor busca Aseprite en el PATH y en las carpetas habituales de Steam e itch, y si no, pregunta dónde está). Las etiquetas listan cada acción y lado. La capa final es visible; lines y flat son capas auxiliares ocultas para retocar a mano, igual que cada salida extra que nombra el grafo de Estilo, por encima de final. El archivo está en modo indexado con la paleta de Pixor.

Pinta encima y conserva tu trabajo. Añade tus propias capas y pinta; luego cambia el modelo o el aspecto en Pixor y vuelve a hornear:

pxr rebake out/hero.aseprite

Pixor es dueño de lo que escribió, y de nada más. Al volver a hornear, Pixor renderiza de nuevo el proyecto y:

  • sustituye los píxeles de las capas que hizo Pixor (final, lines, flat), donde nadie ha pintado sobre ellas;
  • deja tus capas exactamente como están (nunca se mueven, renombran, reordenan ni recolorean) con cada cel pintado en el fotograma en que se pintó. Cada fotograma lleva un id hecho de lo que es (acción, lado, tiempo), así que si la caminata gana tres fotogramas en medio, los ojos que pintaste se quedan en sus propias poses en lugar de deslizarse a otras nuevas, y el re-bake lo indica, fotograma a fotograma: moved your paint on frame 1 is on frame 2 now, y qué fotogramas son nuevos (moved y new_at en --json);
  • mantiene cada color con el que pintaste en su índice, añadiendo los colores nuevos al final de la paleta, o, en una hoja que pasaste a escala de grises o RGB en Aseprite, escribe el render en grises o en colores a juego;
  • conserva tus slices, con sus claves en los fotogramas en que estaban, vayan donde vayan esos fotogramas;
  • marca con una etiqueta los fotogramas en los que el modelo se movió de debajo de tu pintura, pxr check, y deja la pintura donde está.

Dos cosas que no decide solo, y conserva ambas versiones hasta que decidas tú:

Qué ocurrió Qué hace el re-bake
Pintaste en una de las capas propias de Pixor La capa de Pixor recibe el nuevo render; tu edición pasa a una capa propia, final edits, justo encima; el fotograma se etiqueta como pxr conflict
Un fotograma que pintaste no está en el nuevo render (el clip se acortó) el fotograma se conserva al final, con tu pintura, etiquetado pxr removed

No se pierde nada en ningún caso. pxr rebake sale entonces con el código 7 hasta que digas qué camino tomar: --resolve keep conserva tus ediciones como capas propias, --resolve pixor toma el render de Pixor y las descarta. --dry-run dice lo que haría un nuevo horneado sin escribir nada, y --json lo dice para una herramienta; la extensión te hace la misma pregunta en un diálogo.

GIF y APNG

Cada acción y lado se convierte en su propio archivo en bucle (un clip que no está en bucle se reproduce una vez). Los fotogramas usan la paleta del sprite, con el índice 0 transparente. Escala, en el nodo GIF o APNG (--anim-scale K), los amplía por un número entero, de 1 a 16, para que un sprite de 64 px pueda salir como un GIF de 256 px con cada píxel aún nítido.

GIF guarda los retardos en centésimas de segundo, así que el retardo de cada fotograma se redondea, pero la duración total del clip se conserva. Los navegadores muestran los retardos de menos de 20 ms como 100 ms, así que ningún fotograma de un GIF dura menos de 20 ms: por encima de 50 fps, el GIF omite los fotogramas que estarían visibles menos tiempo y dura lo mismo que el clip. APNG guarda los milisegundos exactos, redondeados sobre el total acumulado como los del JSON, así que los fotogramas de un clip a 12 fps duran 83 y 84 ms. Cambia el nombre de un archivo .apng a .png si un sitio solo acepta PNG. Un clip que dibujó el nodo Capa de un grafo de Asset anima esa capa (solo las líneas, los colores planos) tal como la muestra la hoja; una Capa de los mapas de normales, profundidad o emisión anima el sprite, ya que un GIF solo contiene colores de paleta.

Vídeo

Vídeo por clip escribe cada acción y lado como name_walk_Southeast.avi: un AVI sin comprimir, con color de 24 bits, que abre cualquier editor o conversor y que no pierde nada: ningún códec emborrona un píxel. Su nodo tiene tres ajustes:

  • Escala (de 1 a 16, 4 al principio): cuántos píxeles de vídeo mide un píxel del arte.
  • Fotogramas por segundo (1 a 100, 30 para empezar): un vídeo va a una sola frecuencia, así que un fotograma de sprite se escribe tantas veces como dura, y el clip conserva su duración con una precisión de un fotograma de vídeo.
  • Fondo: lo que hay detrás del sprite. Un vídeo no tiene transparencia.

--export video en la línea de comandos toma los valores iniciales, o --video-scale K, --video-fps N y --video-background #RRGGBB. --export all deja fuera los vídeos: nómbralos.

No está comprimido, así que es grande (un sprite de 64 px a escala 4 ocupa unos 200 KB por fotograma), y un vídeo de más de un gigabyte se rechaza en lugar de escribirse. Para subirlo a internet, conviértelo: ffmpeg -i hero_walk_South.avi -crf 0 hero_walk_South.mp4.

Motores sencillos y tu propio código

Lee name.json: frames[i].frame es el rectángulo de la celda y frames[i].duration su duración en milisegundos; meta.frameTags agrupa los fotogramas en animaciones, y una etiqueta que se reproduce una vez en lugar de en bucle lleva "repeat": "1", como lo escribe Aseprite. frames[i].pixor nombra la tag del fotograma (el nombre de su etiqueta de fotogramas), su index en ella, su action y su side, su id y su pivot: el punto de la celda sobre el que el motor apoya el sprite, que es el de la hoja salvo que un nodo Etiqueta le haya dado al clip el suyo propio. El slice del pivote en meta.slices tiene una clave allí donde cambia el pivote, y el slice del pivote del archivo .aseprite tiene las mismas claves.

Root motion

Un clip exportado En el sitio tiene dos valores más por fotograma, en píxeles conservando las fracciones (x hacia la derecha, y hacia abajo):

  • frames[i].pixor.root: dónde estaría la raíz del modelo, medido desde donde estaba al empezar el clip.
  • frames[i].pixor.root_delta: cuánto se mueve la raíz hasta el fotograma siguiente. En el último fotograma es el movimiento hasta el final del clip, para que los ciclos de caminar en bucle sigan a la misma velocidad.

Para mover el personaje como lo hacía el clip, suma root_delta a la posición del sprite cada vez que termina un fotograma.

Iconos de inventario

pxr icons (o un nodo Iconos en el grafo de Asset, generado al exportar el proyecto) convierte modelos en iconos de inventario a juego: cada modelo desde el mismo ángulo de ¾ bajo la iluminación Estudio, a 16, 24, 32 y 48 píxeles (o --sizes), con la silueta del color de su rareza (--rarity common|uncommon|rare|epic|legendary) y, con --framed, sobre un tile enmarcado como una casilla de inventario. Cada icono es un PNG, y cada tamaño recibe un atlas icons_N.png con un icons_N.json que indica dónde está cada icono. Apúntalo a una carpeta para convertir un pack entero en un conjunto de iconos; en la aplicación, suelta la carpeta en la ventana y activa Iconos en lugar de sprites: ahí están los tamaños, la rareza (a partir del nombre de cada archivo, salvo que elijas una) y el marco, y la receta se guarda junto a los iconos como icons.pixoricons:

pxr icons library/pickups --out icons --rarity epic --framed

--rarity from-name da a cada modelo la rareza que indica una palabra de su nombre de archivo (potion_rare.glb, Sword-Epic.glb; sin esa palabra es común), y el JSON indica la de cada icono. Los archivos se toman por orden de nombre, así que el atlas es el mismo sin importar cómo liste la carpeta.

Una receta conserva el pack: --save pack.pixoricons escribe las carpetas y los ajustes (rutas relativas a la receta), y pxr icons pack.pixoricons vuelve a crear el pack, byte a byte. Un accesorio añadido a la carpeta se suma en la siguiente ejecución; una opción después de la receta cambia un ajuste para esa ejecución (pxr icons pack.pixoricons --sizes 64).

Vóxeles y sprite stacks

Un .vox de MagicaVoxel se abre como cualquier otro modelo: cada modelo de su escena donde lo pone el grafo de escena (girado y movido como lo muestra MagicaVoxel), su paleta y los vóxeles de un material luminoso brillando. Un vóxel se lee como una décima de metro, con +Z hacia arriba.

pxr voxels MODEL -o hero.vox --height 32 convierte cualquier modelo en vóxeles, de 32 de alto: la superficie muestreada de sus texturas y colores, el interior relleno, cada vóxel en la paleta propia del aspecto (--preset, --palette y las demás opciones de aspecto), para que los vóxeles coincidan con los sprites. Con --stack también escribe un sprite stack: hero_stack.png, el modelo cortado en rebanadas horizontales una al lado de otra, empezando por abajo, cada una vista desde arriba, y hero_stack.json con el tamaño y el número de rebanadas. Un juego dibuja la rebanada k un píxel por encima de la rebanada k - 1 y las gira todas juntas, que es como el sprite stacking simula el 3D.

pxr voxels knight.glb -o knight.vox --height 32 --stack --preset selout

Comprobar que todo coincide

pxr audit folder --style game.pixorkit lee cada PNG y cada archivo .aseprite exportados de una carpeta y los comprueba con el kit, usando la receta que lleva cada archivo: preset, iluminación, vista, inclinación de la cámara, luz principal, bandas de luz, líneas, paleta y píxeles por metro, y que cada color que usa esté en la paleta del kit. Sin kit, el primer archivo es la referencia. Se enumera cada diferencia; cualquier diferencia hace que el código de salida sea 1, así que puede proteger una build.

En la aplicación, el tablero de coherencia (el botón de las tres figuras, Tablero de coherencia: todos los lados a la vez, o B) muestra el fotograma actual desde todos los lados, uno junto a otro sobre una misma línea de suelo, con la parte superior de cada silueta marcada y su ancho, su altura y su número de colores debajo. Bajo el botón:

  • Siluetas dibuja cada lado solo como su forma, en un único color: una pose que no se lee como silueta no se lee al tamaño del juego.
  • Pivotes marca el píxel sobre el que se apoya y gira cada lado. Un lado cuyos pies no están sobre él se desliza cuando el sprite gira.
  • Recuento de colores escribe el recuento de cada lado; el tablero avisa cuando las alturas difieren en más de un píxel entre lados (Heights differ … between sides), o cuando un lado tiene varios colores más que otro (normalmente una luz que solo capta un lado).

pxr audit, arriba, es la mitad que abarca toda la carpeta: cada hoja frente a un kit.

Lo que encontraron las comprobaciones, sobre los píxeles a los que se refieren

Cada comprobación que hace Pixor (píxeles sueltos, esquinas de línea dibujadas en un píxel, líneas gruesas, un color fuera de la paleta, un tile o un fotograma con más colores de los que permite un modo de consola) marca los píxeles a los que se refiere en lugar de solo imprimir una línea de texto al exportar.

  • En la app: el botón Comprobaciones sobre el sprite (el triángulo de advertencia) dibuja las marcas en el fotograma, y la sección Informe de los pasos Estilo y Asset lista cada hallazgo de cada fotograma renderizado hasta el momento. Haz clic en uno y Pixor va a ese fotograma y lado con las marcas activadas. Bajo la lista, cada tipo de hallazgo indica qué ajuste lo decide (los píxeles sueltos, la limpieza; las esquinas dentadas, las líneas; los colores, la paleta; los límites de consola, el modo consola; un lado volteado que no coincide con el reflejo de la exportación) e Ir a abre ese ajuste.
  • Lados reflejados: con un nodo Voltear en el grafo de asset, un lado que se dibujará volteado se compara con el que voltea, y donde el modelo no es lo bastante simétrico para ello se marcan los píxeles que cambian, mientras aún estás eligiendo, no solo como aviso al exportar.
  • Al exportar: marca Informe (o --export report) y Pixor escribe name_report.png junto a la hoja: la hoja con cada hallazgo marcado. Los píxeles sueltos se rellenan; un tile o un fotograma se enmarca, para que se siga viendo de qué se trata.
Color Qué
cian un píxel suelto (un huérfano)
amarillo una línea que gira una esquina en un píxel
magenta un bloque de línea de dos por dos: una línea gruesa
rojo un píxel fuera de la paleta
naranja un tile de 8 x 8 con más colores de los que permite la consola
naranja intenso un fotograma con más colores de los que permite la consola
rosa un color que la consola no tiene
violeta un píxel que difiere del lado del que se refleja
caja verde una parte dibujada con su color plano porque falta su archivo de textura: pon el archivo junto al modelo

Efectos de píxel

Un nodo Efecto del grafo de Escena (en Efectos en el Esquema) añade un efecto dibujado a partir de partículas 3D: Explosión, Chispa de impacto, Tajo, Estallido mágico, Curación, Portal, Bocanada de humo, Polvo, Fuego en bucle, Lluvia, Nieve, Luciérnagas y Hojas que caen. Cada uno es su propia acción (fx-explosion, …), renderizada con el mismo pipeline que el modelo, así que toma la paleta, el tamaño de píxel, la luz y las líneas del sprite: parece del mismo juego. Fija sus fotogramas, tamaño, energía, posición y semilla (la misma semilla da siempre los mismos píxeles); haz que siga a un hueso (un tajo desde la mano, un fogonazo en la boca de un cañón) y que se reproduzca sobre un clip (el golpe bajo el tajo, o un clip con claves hecho en Pixor); marca Solo el efecto para dibujarlo sin el modelo, como capa propia alineada con la hoja del personaje. Fotograma de impacto marca el fotograma en el que conecta el golpe: el JSON lo enumera en meta.pixor.hits. En la línea de comandos: --effect fireflies:12 --effect-clip shatter --effect-hit 6, con un clip también hecho en Pixor: fragmentos con claves que salen volando bajo el destello. Crear un efecto en la pantalla de un proyecto vacío, junto a Importar… y Explorar modelos gratuitos (o pxr effect explosion -o fx.png), crea un efecto sin ningún modelo.

Hitboxes, hurtboxes y puntos de anclaje

La Caja de una parte en el Inspector (o --hitbox, --hurtbox) la convierte en hitbox (da golpes: una espada) o en hurtbox (puede recibirlos: el cuerpo), y el Punto de anclaje en el JSON de un hueso (o --socket) lo convierte en punto de anclaje (una mano, la boca de un cañón). El JSON de cada fotograma lleva entonces pixor.boxes (part, kind, x, y, w, h en píxeles de la celda, a partir de los píxeles que cubre realmente cada parte) y pixor.sockets (la posición de cada hueso en píxeles de la celda), para que el código del juego compruebe los golpes y acople efectos sin adivinar. Un archivo de modelo también puede marcar partes (pxr.box).

Capas de paper doll

Con accesorios acoplados, Capas de paper doll (--paper-doll) también escribe name_base.png, el modelo sin sus accesorios en el mismo lienzo, y una capa por accesorio (name_sword.png), con sus píxeles visibles y las líneas que los rodean. Apiladas con la base primero, dan la hoja completa; cambiar la capa de un accesorio cambia el equipo. name_stacked.png son ellas apiladas así, como las apilará el motor: la vista previa que muestra que encajan. Los píxeles de cada pieza son los de la propia hoja; la base es el cuerpo dibujado sin las piezas, así que solo difiere de la hoja a unos pocos píxeles del borde de una pieza y donde una pieza proyecta una sombra sobre el cuerpo: desactiva las sombras proyectadas (--no-shadow) para que las capas se apilen exactamente. Las filas que un nodo Sprites dibuja con un conjunto de partes pertenecen a la hoja propia de ese nodo, no a las capas. (La app las hace con pxr a partir del proyecto guardado, guardándolo antes si ha cambiado, así que las capas son lo que hay en pantalla).

El equipo que forma parte del modelo (un yelmo, un escudo, una capa modelados con el personaje en lugar de unidos como accesorio) es una pieza:

pxr render knight.glb --clip all --paper-doll --piece helmet:Knight_Helmet --piece gear:Round_Shield,1H_Sword
pxr project set knight.pixor --paper-doll --piece helmet:Knight_Helmet

Cada pieza nombra las partes de las que está hecha (tal como las lista el Esquema) y se convierte en una capa propia, name_helmet.png, exactamente igual que la de un accesorio (en la aplicación, Su propia capa de paper doll de una parte la convierte en una, con su nombre): solo los píxeles suyos que se ven, así que un escudo detrás del cuerpo queda oculto donde el cuerpo lo tapa. La base se renderiza sin ninguna pieza ni accesorio, así que lo que cubría un casco (la cabeza de debajo) se dibuja ahí. --no-pieces las quita de un proyecto. El nodo Capa de un grafo de Asset nombra base o una pieza o accesorio por su nombre como su capa, para disponer las capas como quiera (grafo de Asset).

Prueba lo que describe esta página con tu propio modelo, gratis en tu navegador.

Probar en el navegador Obtener Pixor