Imagem para pixel art animada
O resultado deve permanecer fiel à fonte: corrija o que a redução para tamanho de pixel danificou, nunca invente detalhes. No movimento, o inimigo são quebras: qualquer pixel que salte, rasgue, apareça ou pisque. Claude não pode assistir a um GIF, portanto cada exibição é precedida por verificações medidas, nunca por "parece bom em uma imagem estática".
Se o usuário mantiver preferências de pixel art (em seu CLAUDE.md ou em um arquivo apontado por ele), leia-as primeiro; elas substituem os padrões aqui. Necessita do MCP do Aseprite: references/aseprite-mcp.md. Leia quando chegar nessa etapa: references/still-recipe.md, references/motion-and-breaks.md.
Fluxo de trabalho
Cada checkpoint é uma mensagem: uma imagem lado a lado (fonte | antes | depois, ou um GIF mais um flip-book recortado) e uma pergunta. Copie o arquivo atual para _vN antes de cada alteração, para que uma rodada rejeitada seja revertida a partir dele. Cada rodada faz exatamente a alteração solicitada e nada mais.
- Briefing. Pergunte o que é desejado antes de planejar: quais partes se movem, quanto e quão rápido, o que fica parado, o que é protegido. Escreva um plano curto (meia página) e obtenha um sim. Terminado quando o usuário aprovar o plano.
- Fonte. Corte ou redimensione a fonte para que seu tamanho seja exatamente 3x o sprite alvo (cerca de 200-260 px de largura). Os scripts assumem 3x.
- Estática (
1_still.lua, depois correções com2_local_rerender.lua,3_join_outline.lua). Meça os parâmetros em still-recipe.md para esta imagem. Checkpoints na ordem: mãos, depois rosto e olhos, depois contornos, metal e fundo. Terminado quando cada parte for aprovada e a estática for salva como*_still_FINAL. - Poses de piscada (
4_blink_poses.lua, traçados de olho manualmente em 14x). Mostre todas as quatro poses lado a lado mais um GIF de piscada em um checkpoint, construído conforme motion-and-breaks.md. Terminado quando aprovado. - Movimento (
5_animation_frames.lua). Preencha seu bloco SETTINGS a partir das medições na estática, execute comBF_ZERO = trueprimeiro (deve mudar 0 px), depois a execução real, então6_deflicker_metrics.lua. Passe nas verificações abaixo, então mostre o GIF completo mais um flip-book recortado da parte em movimento. - Efeitos (
8_effects.lua, apenas cor, após de-flicker). Verifique, depois mostre. - Extras um pedido de cada vez (braços, água, ...), cada um com seu próprio checkpoint.
- Final. Copie para
*_FINAL(.aseprite+ GIF 3x), mantendo os finais anteriores.
Verificações antes de cada checkpoint de animação
| Verificação | Aprovação | Onde |
|---|---|---|
| Renderização com deslocamento zero igual à pose | 0 px alterados com BF_ZERO | 5 |
| Partes rígidas (mãos) exatas | cada quadro da caixa, deslocado de volta por seu levantamento de pixels inteiros, igual à estática: 0 px | comparação própria em Lua |
| Pops de um quadro (A→B→A) | nenhum fora da piscada e efeitos | 6 os imprime |
| Saltos | quadros de passo listados em BA_STEPS são excluídos; todo outro quadro ≤ ~2x mediana de pixels alterados, e qualquer quadro acima disso tem uma causa nomeada | 6 |
| Mapa de calor | sem vermelho (≥ 8 alterações por loop) em contornos, alças, cílios, olhos | 7_flicker_heatmap.lua |
| Efeitos | cada pixel de efeito segura ≥ 2 quadros; a contagem de pixels alterados está acima de 0 (uma mistura fraca pode voltar à mesma cor de paleta) | 8 imprime contagens |
| Olho fechado | sem cor de íris restante nos quadros fechados | view_sprite em 12x |
| Flip-book | 8-16 quadros de mãos, rosto e cada borda em movimento em 6x+ parecem contínuos | região + quadros do view_sprite |
Scripts (scripts/)
Cada script precisa de PA_DIR (pasta do projeto, terminando no separador de caminho: \ no Windows, / no macOS) e PA_SRC (nome do arquivo de imagem fonte) definidos primeiro, além de suas próprias variáveis globais listadas em seu cabeçalho. Execute-os através de run_lua_script com um lançador curto; <skill> é o diretório base desta skill, fornecido quando a skill é carregada:
PA_DIR, PA_SRC = [[/caminho/para/projeto/]], "reference.jpg"
BF_POSES, BF_OUT, BF_PUSH = "blink_poses.aseprite", "frames", true
dofile([[<skill>/scripts/5_animation_frames.lua]])
| Script | Faz |
|---|---|
1_still.lua | Redução 3x3 preservando linhas, paleta k-means + acentos, passagem de sardas, mesclagem de órfãos |
2_local_rerender.lua | Re-renderiza caixas com outro limite de linha ou com cores extras (mãos, lábios) |
3_join_outline.lua | Une contornos pontilhados onde a fonte tem uma linha fina |
4_blink_poses.lua | Poses aberta, meio, perto, fechada (os traçados de olho no arquivo são por imagem) |
5_animation_frames.lua | Todos os quadros; cada coordenada vive em seu bloco SETTINGS (valores de exemplo incluídos) |
6_deflicker_metrics.lua | De-flicker, pops, verificação de salto (BA_SKIP caixas rígidas, BA_STEPS quadros de passo) |
7_flicker_heatmap.lua | PNG de mapa de calor |
8_effects.lua | Luz squash, brilho, cintilações do mar, brilhos de areia (bloco SETTINGS por imagem) |
checkin_sheet.lua | Folha fonte / antes / depois para uma região |
example_metal_rerender.lua | Exemplo prático apenas: metal re-renderizado com faixas de sombra da fonte |
5_animation_frames.lua contém os tipos de movimento encontrados até agora (faixa de respiração, domos suaves, caixas de balanço, impulso rígido de pixel inteiro, segmentos de membros, mar). Uma nova imagem com partes móveis diferentes adiciona um campo lá.