Español
Cómo crear personajes y objetos
Un PNG por acción, con los cuadros pegados en fila horizontal.
Usar la skill · lo más fácil
Sube el zip de la skill a Claude, ChatGPT o Gemini junto con una foto. Te muestra el dibujo, lo corrige contigo y te devuelve un zip listo para usar.
Cómo conseguir y usar la skillCopiar la especificación y pedirlo
Copia esta página en markdown, pégala en ChatGPT o Claude y seguirá la especificación.
Subir
En el menú de la bandeja entra a "Personaje > Crear…", elige la pestaña Personajes, Objetos o Emotes y pulsa "+ Crear". Ponle un nombre (hasta 20 caracteres) y elige un PNG para cada acción, o arrástralo a la casilla. Los campos de fps vienen con los valores recomendados. En los objetos también eliges el tipo (para lanzar, comida, caca) y un wav de sonido. Al guardar aparece en tu lista, y ahí mismo lo editas o lo borras. La tarjeta + al inicio de las ventanas de personajes, objetos y emotes abre el mismo editor.
Les llega a tus amigos cuando abren la ventana "Personaje > Cambiar…" de la bandeja o pulsan "Traer personajes y objetos nuevos". El personaje que elegiste se ve de inmediato.
Para la comida, haz clic derecho en un amigo, elige una en "Comida" y luego haz clic en él para lanzarla. Cada clic le da de comer hasta que vuelvas a elegir algo para lanzar.
En la caca, la imagen fly se dibuja como caca puesta en el suelo (no se lanza ni se come). Tu personaje deja la caca que elegiste cuando está lleno. Los amigos que todavía no la han recibido ven la caca por defecto.
Emotes
En la pestaña "Emotes" elige un GIF, WebP, APNG, PNG o JPG. La app lo reduce a 64px, toma hasta 16 cuadros y lo guarda a su velocidad original (el original, hasta 20MB y 2048px por lado). El nombre admite hasta 20 caracteres y no puede repetirse dentro del grupo. : y los espacios no se permiten porque cortarían :nombre: dentro del mensaje, y los nombres de los emotes básicos (heart·question·exclamation·angry·lol·note) ya están tomados.
Dónde se usan: 'Emotes' en el menú que sale al hacer clic en tu personaje (⌃⌥⌘E, Ctrl+Alt+E en Windows) abre la ventana sobre tu cabeza. Escribe : en un mensaje para ver los nombres, y al elegir uno entra como :nombre: en el globo. Con el botón de emoji de la pestaña 'Estado' lo pones en tu estado. También puedes reaccionar con uno a un mensaje del chat. Solo lo ven los amigos del mismo grupo.
Especificaciones
- Cuadros de 48×48, hasta 8 por acción (4 cuadros dan 192×48)
- Fondo transparente, 200KB por archivo (si pesa más, la app lo vuelve a guardar más chico. El wav de sonido, 50KB)
- Dibújalo mirando a la derecha (la app lo voltea para el otro lado)
- Los personajes y la caca tocan la fila de abajo y van centrados. Lo que se lanza y la comida van al centro del cuadro
- Aprovecha bien la cuadrícula de 48 (de 800 a 1200 píxeles pintados, de 30 a 46 de alto, más si el cuerpo es delgado). La app no amplía nada, así que un dibujo chico se verá chico junto a los de tus amigos
Acciones del personaje
Basta con idle, walk y sleep. Las demás, si faltan, se reemplazan por otra acción. Sin offline, al desconectarse se convierte en piedra.
| Acción | Cuándo | Recomendado | Si falta |
|---|---|---|---|
idle obligatorio | Quieto | 2 cuadros, 2fps | |
walk obligatorio | Al caminar | 4 cuadros, 6fps | |
sleep obligatorio | 30 minutos ausente o pantalla bloqueada (la app dibuja el Zzz) | 2 cuadros, 1fps | |
poked | Al picarlo | 2 cuadros, 8fps | idle |
throw | Al lanzar | 3 cuadros, 10fps | idle |
hit | Al recibir el golpe | 2 cuadros, 8fps | poked |
jump | Al esquivar, acción de salto | 2 cuadros, 8fps | idle |
eat | Al recibir comida, acción de ñam | 3 cuadros, 6fps | happy |
wave | Saludo a un amigo que se conecta, acción de saludo | 3 cuadros, 6fps | happy |
happy | Al recibir caricias, acción de alegría | 2 cuadros, 4fps | idle |
offline | Desconectado (caído) | 1 cuadro, 1fps | Piedra |
Acciones del objeto
| Acción | Cuándo | Recomendado | Si falta |
|---|---|---|---|
fly obligatorio | Mientras vuela. Activa 'Girar al volar' en la ventana de creación y la app lo gira por ti (en lo nuevo viene apagado). Con el giro apagado, lo que se lanza vuela derecho mirando hacia donde va, así que dibújalo mirando a la derecha; la comida con el giro apagado vuela tal como la dibujaste, así que dibújala derecha. Dale movimiento con varios cuadros para que no se vea congelada (que rebote, que brille). La caca se dibuja puesta en el suelo | 1 cuadro para lanzar, de 1 a 4 para comida, 12fps (la caca, 1 cuadro) | |
impact | El momento del impacto (solo para lanzar; la comida se come al llegar) | 3 cuadros, 12fps | El estallido de estrellas que dibuja la app |
El wav suena en el momento del impacto (en la caca, al caer). Sin él, lo que se lanza y la comida no suenan, y la caca usa el 'pum' de la app.
Ejemplo: martillo de juguete
Es un objeto básico. fly es un solo cuadro, pero gira mientras vuela (la comida no gira).
| Acción | Movimiento | Lo que subes (4x) |
|---|---|---|
flyMientras vuela | ![]() | ![]() |
impactEl momento del impacto | ![]() | ![]() |
Descargar a tamaño real: fly, impact, Descargar todo (zip)
Caca
Un objeto de caca solo necesita un cuadro fly. Se dibuja puesto en el suelo, sin girar. La app no lo reduce: dibuja la cuadrícula de 48×48 tal cual, así que hazlo chiquito abajo al centro (la caca por defecto mide 17 de ancho y 12 de alto) y deja la parte de arriba vacía. No tiene que parecer caca. También sirve cualquier objetito que le quede a tu personaje (una calabacita, un ataúd, un ovillo de lana) siempre que entre en el área de 24×24 de abajo al centro. Abajo está la caca por defecto.
| Acción | Movimiento | Lo que subes (4x) |
|---|---|---|
flyPuesta en el suelo | ![]() | ![]() |
Descargar a tamaño real: fly
Ejemplo: Ddeoggi
Todas las acciones de Ddeoggi, dibujado a partir de un pingüino de peluche. Usa la misma cantidad de cuadros de la tabla de arriba y, como todas las poses reutilizan el mismo cuerpo, las acciones no se desalinean entre sí.
| Acción | Movimiento | Lo que subes (4x) |
|---|---|---|
idleQuieto | ![]() | ![]() |
walkAl caminar | ![]() | ![]() |
sleepDormido | ![]() | ![]() |
pokedAl picarlo | ![]() | ![]() |
throwAl lanzar | ![]() | ![]() |
hitAl recibir el golpe | ![]() | ![]() |
jumpAl esquivar y saltar | ![]() | ![]() |
eatAl recibir comida | ![]() | ![]() |
waveSaludo | ![]() | ![]() |
happyCaricias | ![]() | ![]() |
offlineDesconectado | ![]() | ![]() |
Descargar a tamaño real: idle, walk, sleep, poked, throw, hit, jump, eat, wave, happy, offline, Descargar todo (zip)
Plantillas
Con "Bajar plantilla" en la ventana de creación obtienes una plantilla con el hámster de la app dibujado en cada acción (una bellota para los objetos). Las plantillas vacías están aquí: 2 cuadros, 4 cuadros, 8 cuadros, Descargar todo (zip)
Ponla en una capa de abajo, dibuja encima y apaga la capa de la plantilla antes de guardar. La línea roja marca dónde van los pies.
Programas para dibujar: Piskel(web, gratis), LibreSprite(gratis), Aseprite(de pago)
Crear con IA
Las IA de imagen no aciertan exactamente los 48 píxeles. Genera en grande, reduce y después retoca.
- Generar con el prompt de abajo
- Reducir cada cuadro a 48×48. La interpolación tiene que ser vecino más cercano (Nearest Neighbor), si no queda borroso.
- Dejar el fondo transparente y alinear los cuadros
En el navegador, sin instalar nada:
- Photopea(gratis, parecido a Photoshop): para reducir, usa "Imagen > Tamaño de imagen" y pon la interpolación en Nearest Neighbor. Para el fondo, usa la varita mágica (tolerancia 0, sin suavizado), haz clic en el fondo, pulsa Delete y exporta como PNG.
- remove.bg(gratis): solo para quitar el fondo. Puede suavizar los bordes, así que úsalo en la imagen grande antes de reducir.
El aspecto base
Pixel art sprite of a cute [animal], side view facing right, full body, match the body shape, proportions and features of the attached picture if any (otherwise the real proportions of that animal or character), on a 48x48 pixel grid, upscaled so one art pixel is a clean 16x16 block (768x768 per frame), hard edges, no anti-aliasing, no gradients, no dithering, about 8 colors, 1px dark outline, flat shading, transparent background, fills most of the grid (about 30-46 pixels tall), feet on the bottom row, horizontally centered, nothing touching the top or side edges, no shadow, no text
Hoja de acciones (adjunta el resultado anterior como referencia)
Pixel art sprite sheet of the same character, [N] frames in one horizontal row, no gaps, facing right, animation: [motion], each frame on a 48x48 pixel grid, upscaled so one art pixel is a clean 16x16 block (768x768 per frame), hard edges, no anti-aliasing, no gradients, no dithering, same palette (about 8 colors) as the reference, 1px dark outline, same size and position in every frame, feet on the bottom row, transparent background, the 4 corner pixels of every frame transparent, nothing touching the top or side edges, no shadow, no text
| Acción | [N] | [motion] | Ddeoggi |
|---|---|---|---|
idle | 2 | gentle breathing, body down 1px in frame 2 | ![]() |
walk | 4 | walk cycle: left foot forward, body up, right foot forward, body up | ![]() |
sleep | 2 | eyes closed, body rises and falls 1px | ![]() |
poked | 2 | squashed flat, then back to normal | ![]() |
throw | 3 | wind up, then swing one arm forward | ![]() |
hit | 2 | knocked back, dizzy swirl eyes | ![]() |
jump | 2 | crouch, then stretch up | ![]() |
eat | 3 | mouth open, chewing, cheeks puffed | ![]() |
wave | 3 | one paw raised, waving | ![]() |
happy | 2 | smiling closed eyes, tiny heart | ![]() |
offline | 1 | knocked out, squashed flat on the ground, X eyes | ![]() |
Objetos
Pixel art game item, [item], one single frame on a 48x48 pixel grid, upscaled so one art pixel is a clean 16x16 block (768x768), hard edges, no anti-aliasing, no gradients, no dithering, centered in the frame, about 8 colors, 1px dark outline, transparent background, the 4 corner pixels transparent, no shadow, no text
Lo que se lanza necesita su propio impact (la comida y la caca no lo tienen):
Pixel art impact effect sprite sheet, 3 frames in one horizontal row, no gaps, a star bursting from the center of the frame and breaking into pieces, each frame on a 48x48 pixel grid, upscaled so one art pixel is a clean 16x16 block (768x768 per frame), hard edges, no anti-aliasing, no gradients, no dithering, centered in every frame, about 8 colors, 1px dark outline, transparent background, the 4 corner pixels of every frame transparent, no shadow, no text
Con 'Girar al volar' apagado, la comida vuela derecha. Usa varios cuadros para darle movimiento:
Pixel art food item, [item], [N] frames in one horizontal row, no gaps, upright in every frame (not spinning), gently bobbing up and down with a small sparkle, each frame on a 48x48 pixel grid, upscaled so one art pixel is a clean 16x16 block (768x768 per frame), hard edges, no anti-aliasing, no gradients, no dithering, centered in every frame, about 8 colors, 1px dark outline, transparent background, the 4 corner pixels of every frame transparent, no shadow, no text
Caca
[character] es el nombre y el aspecto de tu personaje (por ejemplo "Ddeoggi, un pingüino gris de pico amarillo").
Pixel art of a cute squat swirl poop with a tiny face colored and decorated like [character] (one feature such as ears or beak), or a small prop that matches [character] (for example a mini pumpkin or a coffin), one single frame on a 48x48 pixel grid, upscaled so one art pixel is a clean 16x16 block (768x768), hard edges, no anti-aliasing, no gradients, no dithering, small (about 17x12 pixels), horizontally centered, sitting on the bottom row, entirely inside the bottom-center 24x24 area of the grid (x 12-35, y 24-47), about 8 colors, 1px dark outline, transparent background, no shadow, no text
Usar la skill (lo más fácil)
Descarga huggybugi-character.zip, súbelo a Claude, ChatGPT o Gemini junto con una foto y dile "sigue SKILL.md y crea un personaje de Huggybugi con esta foto". Dibuja las 11 acciones (y también caca, algo para lanzar o comida si se lo pides) y te devuelve un zip listo para 'Subir todo de una vez', aquí abajo. La IA tiene que poder ejecutar código (en Claude y ChatGPT, usa un modelo que lo haga). Si te cansa subirlo cada vez, regístralo como skill. Después basta con darle una foto y decir "créame un personaje de Huggybugi".
- Claude (web y app): ajustes → Capabilities (o Customize > Skills) → "Upload skill" y sube el zip tal cual. Hace falta un plan de pago con la ejecución de código activada
- ChatGPT: si tu plan tiene Skills, ve a Skills → subir y dale el zip. Si no, sube el zip en cada conversación
- Gemini (web y app): sube el zip en Skills (cuenta personal)
- Gemini CLI: descomprime el zip y pon la carpeta
huggybugi-characteren~/.gemini/skills/
Claude Code y Codex lo instalan como plugin, sin zip, y al actualizar el plugin llegan las versiones nuevas. Estos comandos y la especificación también se copian desde "Crear con IA" en la ventana de creación de la app.
# Claude Code /plugin marketplace add Zaehyeon2/huggybugi /plugin install huggybugi@huggybugi # Codex codex plugin marketplace add Zaehyeon2/huggybugi codex plugin add huggybugi@huggybugi
Los nombres de los menús cambian de vez en cuando. Los detalles están en el README.md dentro del zip.
IA que ejecuta código (ChatGPT, Claude y similares)
La cuadrícula sale exacta. Define el cuerpo, los ojos y los pies con figuras simples como elipses, y arma todas las acciones con una sola función que reciba los valores de la pose (alto del cuerpo, forma del ojo, pie levantado) y dibuje un cuadro. Así las acciones nunca se desalinean. Si le das una foto o un dibujo, copia los colores y el aspecto. Sin foto, pídele que primero busque algunos pixel art bonitos de ese animal u objeto y queda mucho mejor.
Write and run a Python (Pillow) script that draws a pixel art [animal] (see the attached picture) for a 48x48 desktop pet. Match the picture's body shape, proportions and features as closely as the grid allows (no picture: first look up a few cute pixel art references of that animal or item and follow their proportions, without copying any one of them). Build each frame from simple shapes (ellipses for body, face, feet) in ONE function draw(pose) that takes pose values like bob, eyes, foot lift, so every animation reuses the same shapes. Add a 1px dark outline automatically around the filled pixels. Facing right, feet touching row 47, the 4 corner pixels transparent. Save one horizontal strip PNG per animation (1x, frames 48x48, no gaps), each file named exactly after the animation (idle.png, walk.png, ...): idle 2, walk 4, sleep 2, poked 2, throw 3, hit 2, jump 2, eat 3, wave 3, happy 2, offline 1. Put all the PNGs in one zip file for download. Show me an 8x preview, then let me ask for changes.
Los objetos y la caca tienen otras acciones, así que usa esto en lugar del prompt de arriba. Deja solo la línea de tu tipo, para lanzar o comida, y borra la otra.
Write and run a Python (Pillow) script that draws a pixel art [item] (see the attached picture) for a 48x48 desktop pet app. Build it from simple shapes with a 1px dark outline, transparent background, centered in the frame, the 4 corner pixels of every frame transparent. Save horizontal strip PNGs (1x, frames 48x48, no gaps), keeping only the line for your item kind: thrown item: fly 1 facing right (with 'spin while flying' on, the app spins it, so do not draw spin frames) and impact 3 (the moment it hits). food: fly 1-4 drawn upright (it is not spun), gently bobbing with a small sparkle, no impact (food is eaten on arrival). Name the files exactly fly.png and impact.png and put them in one zip file. Show me an 8x preview, then let me ask for changes.
Write and run a Python (Pillow) script that draws a pixel art poop for a 48x48 desktop pet, colored and decorated like [character] (one feature such as ears or beak), or a small prop that matches [character] instead of a poop. One 48x48 frame saved as fly.png: small (about 17x12 pixels), horizontally centered, sitting on the bottom row, entirely inside the bottom-center 24x24 area (x 12-35, y 24-47), flat and cute, 1px dark outline, transparent background. Show me an 8x preview.
El código de un objeto se ve más o menos así (el fly y el impact del martillo, y la caca por defecto). Las imágenes del martillo y de la caca de los ejemplos de arriba salieron de este código. Los archivos se llaman igual que la acción, fly.png e impact.png; el ejemplo de abajo dibuja dos objetos a la vez, así que les pone un prefijo.
import math
COLORS = {'K': '#2b2233', 'Y': '#ffd23f', 'R': '#ff5a6e', 'F': '#9a6a48', 'N': '#7a4a24',
'E': '#1b1420', 'P': '#ff9fb0'}
N = 48 # cuadros de 48x48
def oval(x, y, cx, cy, rx, ry): # true si el centro del píxel (+0.5) queda dentro de la elipse
return ((x + 0.5 - cx) / rx) ** 2 + ((y + 0.5 - cy) / ry) ** 2 <= 1
# arma un cuadro con una letra de color por píxel y convierte el borde exterior en una línea oscura de 1px (K).
def render(fill):
g = [[fill(x, y) for x in range(N)] for y in range(N)]
solid = lambda x, y: 0 <= x < N and 0 <= y < N and g[y][x] != '.'
return [''.join('K' if c != '.' and not (solid(x - 1, y) and solid(x + 1, y)
and solid(x, y - 1) and solid(x, y + 1)) else c
for x, c in enumerate(row)) for y, row in enumerate(g)]
# martillo de juguete: un cuadro fly (con 'girar al volar' activado, la app lo gira)
def hammer(x, y):
if 12 <= x <= 35 and 10 <= y <= 21:
return 'Y' if x <= 14 or x >= 33 else 'R'
if 21 <= x <= 26 and 22 <= y <= 41:
return 'Y'
return '.'
# impact: una estrella crece y se rompe en pedazos (3 cuadros)
def star(r):
def fill(x, y):
dx, dy = x + 0.5 - 24, y + 0.5 - 24
a = math.atan2(dy, dx) + math.pi / 2
edge = r * (0.55 + 0.45 * abs(math.cos(a * 5 / 2)))
return 'Y' if math.hypot(dx, dy) <= edge else '.'
return fill
def burst(color, k, n=6):
def fill(x, y):
r, s = 10 + k * 5, 4.4 - k * 0.45
for i in range(n):
a = i / n * math.pi * 2 + k * 0.2
if oval(x, y, 24 + math.cos(a) * r, 24 + math.sin(a) * r, s, s):
return color
return '.'
return fill
# caca: un cuadro fly. tres rollos que tocan la fila de abajo, con ojos, cachetes y boca en el de más abajo
TIERS = [(23.5, 38.8, 3.4, 1.9), (23.5, 41.9, 5.8, 2.2), (23.5, 44.9, 8.1, 3.1)]
DOTS = {(22, 36): 'F', (23, 36): 'F', (24, 36): 'F', (20, 44): 'E', (26, 44): 'E',
(18, 45): 'P', (19, 45): 'P', (27, 45): 'P', (28, 45): 'P',
(22, 46): 'N', (23, 46): 'N', (24, 46): 'N'}
def poop(x, y):
if (x, y) in DOTS:
return DOTS[(x, y)]
for i, (cx, cy, rx, ry) in enumerate(TIERS):
if oval(x, y, cx, cy, rx, ry):
# la parte baja de cada rollo es la ranura donde se apoya sobre el de abajo
return 'N' if i < len(TIERS) - 1 and y >= cy + ry - 1.1 else 'F'
return '.'
ANIMS = {
'hammer-fly': [render(hammer)],
'hammer-impact': [render(star(9)), render(star(15)), render(burst('Y', 2))],
'poop-fly': [render(poop)],
}
# un PNG en tira horizontal por acción (1x, cuadros de 48x48)
def save(name, frames):
from PIL import Image, ImageColor
img = Image.new('RGBA', (N * len(frames), N))
for i, g in enumerate(frames):
for y, row in enumerate(g):
for x, c in enumerate(row):
if c != '.':
img.putpixel((i * N + x, y), ImageColor.getrgb(COLORS[c]))
img.save(name + '.png')
if __name__ == '__main__':
for name, frames in ANIMS.items():
save(name, frames)
El código que escribe una IA se ve más o menos así (Ddeoggi, las 11 acciones). Las imágenes de Ddeoggi de los ejemplos de arriba salieron de este código. Si tienes Pillow, lo ejecutas y se guarda un PNG por acción.
import math
COLORS = {'K': '#3a3640', 'G': '#9a98a3', 'g': '#7f7d88', 'W': '#fbf9f4', 'Y': '#f7c535',
'y': '#e2a51f', 'E': '#2a1c18', 'P': '#ffb3c0', 'R': '#e8586a'}
N = 48 # cuadros de 48x48
S = 1.5 # pasa a 48 las medidas definidas para 32
def rnd(v): # redondea .5 hacia arriba (round de python va al par, así que no se usa)
return math.floor(v + .5)
def u(v): # los desplazamientos de la pose, en píxeles enteros de la cuadrícula de 48
return int(math.copysign(rnd(abs(v) * S), v)) if v else 0
def oval(x, y, cx, cy, rx, ry):
return ((x + .5 - cx) / rx) ** 2 + ((y + .5 - cy) / ry) ** 2 <= 1
def tri(x, y, a, b, c):
px, py = x + .5, y + .5
s = lambda p, q: (px - q[0]) * (p[1] - q[1]) - (p[0] - q[0]) * (py - q[1])
d = (s(a, b), s(b, c), s(c, a))
return not (min(d) < 0 and max(d) > 0)
# un ojo (base 3x3). dx, dy se miden desde la esquina superior izquierda del ojo
def eye(dx, dy, kind):
if kind == 'open':
return ('W' if dx == dy == 0 else 'E') if 0 <= dx <= 2 and 0 <= dy <= 2 else None
if kind == 'wide': # sorpresa: 4x4 con un brillo
return ('W' if dx == dy == -1 else 'E') if -1 <= dx <= 2 and -1 <= dy <= 2 else None
hit = {'closed': (dy == 1 and dx in (-1, 3)) or (dy == 2 and 0 <= dx <= 2),
'happy': (dy == 0 and 0 <= dx <= 2) or (dy == 1 and dx in (-1, 3)),
'hurt': -1 <= dx <= 3 and -1 <= dy <= 3 and (dx == dy or dx == 2 - dy)}[kind]
return 'E' if hit else None
# dibuja un cuadro solo con los valores de la pose. todas las acciones usan las mismas figuras.
# squash: + achatado, - alargado. feet: pie levantado. flip: ala levantada. lean: cuerpo movido a los lados
def draw(bob=0, squash=0, feet=(0, 0), flip=(0, 0), eyes='open', mouth='', blush=False, lean=0):
ry = (9 - squash) * S
rx = min((13 + squash * .8) * S, 22.4) # que el cuerpo achatado no se salga de la cuadrícula
by = (30.4 + min(bob, 1)) * S - ry + max(bob - 1, 0) * S
cx = min(max((16 + lean) * S, rx + 1.4), 46.6 - rx)
wl, wr = max(cx - rx + .3 * S, 4.5), min(cx + rx - .3 * S, 43.5)
fy = by + 1.5 * S
ey = rnd(by - 3 * S)
shift = 3 + u(lean) # la cara mira 3 píxeles a la derecha
gy = rnd((30 + min(bob, 0)) * S) - u(max(feet))
def foot(fcx, x, y, up):
b = 47 - u(up)
return b - 2 + min(0, u(bob + up)) <= y <= b and abs(x + .5 - fcx) <= (3.5 if y == b else 4.8)
def pixel(x, y):
body = oval(x, y, cx, by, rx, ry) or tri(
x, y, (cx - 3.5 * S, by - ry + 2 * S), (cx + 3.5 * S, by - ry + 2 * S), (cx, by - ry - .8 * S))
fin = oval(x, y, wl, fy - flip[0] * S, 2.6 * S, 1.8 * S) or oval(x, y, wr, fy - flip[1] * S, 2.6 * S, 1.8 * S)
paw = foot(18.5, x, y, feet[0]) or foot(31.5, x, y, feet[1])
# pinta los pies antes del cuerpo para que queden por delante, como en un peluche
if paw and y >= gy:
return 'Y'
if not body:
return 'g' if fin else 'Y' if paw else '.'
fx = x - shift
e = eye(fx - 14, y - ey, eyes) or eye(fx - 31, y - ey, eyes)
if e:
return e
if y in (ey + 2, ey + 3) and 21 <= fx <= 26: # pico
return 'Y'
if mouth == 'open': # al comer se abre y se ve el interior de la boca
if ey + 4 <= y <= ey + 5 and 22 <= fx <= 25:
return 'R'
if y == ey + 6 and 22 <= fx <= 25:
return 'Y'
elif y == ey + 4 and (21 if mouth == 'chew' else 22) <= fx <= (26 if mouth == 'chew' else 25):
return 'y'
if blush and y in (ey + 3, ey + 4) and (11 <= fx <= 13 or 34 <= fx <= 36):
return 'P'
face = (oval(fx, y, 11 * S + .5, by - 2 * S, 3.8 * S, 3.6 * S)
or oval(fx, y, 21 * S + .5, by - 2 * S, 3.8 * S, 3.6 * S)
or oval(fx, y, 16 * S + .5, by + 3 * S, 8.2 * S, 5.2 * S))
return 'W' if face else 'G'
g = [[pixel(x, y) for x in range(N)] for y in range(N)]
solid = lambda x, y: 0 <= x < N and 0 <= y < N and g[y][x] != '.'
edge = lambda x, y: not all(solid(x + a, y + b) for a, b in ((1, 0), (-1, 0), (0, 1), (0, -1)))
return [''.join('K' if c != '.' and edge(x, y) else c for x, c in enumerate(row)) for y, row in enumerate(g)]
ANIMS = {
'idle': [draw(), draw(bob=1)],
'walk': [draw(feet=(1, 0), lean=-1), draw(bob=-1), draw(feet=(0, 1), lean=1), draw(bob=-1)],
'sleep': [draw(eyes='closed', bob=1, squash=1), draw(eyes='closed', bob=2, squash=1)],
'poked': [draw(eyes='wide', squash=3), draw(eyes='wide')],
'throw': [draw(flip=(0, 4), lean=-1), draw(flip=(0, 5), lean=-1, bob=-1), draw(flip=(0, -1), lean=1)],
'hit': [draw(eyes='hurt', lean=-2, squash=1), draw(eyes='hurt', bob=1)],
'jump': [draw(squash=3, flip=(-1, -1)), draw(bob=-3, squash=-1, feet=(2, 2), flip=(3, 3))],
'eat': [draw(mouth='open'), draw(mouth='chew', bob=1, squash=1), draw(eyes='happy', blush=True)],
'wave': [draw(flip=(0, 3), eyes='happy'), draw(flip=(0, 6), eyes='happy'), draw(flip=(0, 3), eyes='happy')],
'happy': [draw(eyes='happy', blush=True, bob=-1), draw(eyes='happy', blush=True)],
'offline': [draw(eyes='hurt', squash=3, bob=1, flip=(-1, -1))],
}
# un PNG en tira horizontal por acción (1x, cuadros de 48x48)
def save(name, frames):
from PIL import Image, ImageColor
img = Image.new('RGBA', (N * len(frames), N))
for i, g in enumerate(frames):
for y, row in enumerate(g):
for x, c in enumerate(row):
if c != '.':
img.putpixel((i * N + x, y), ImageColor.getrgb(COLORS[c]))
img.save(name + '.png')
if __name__ == '__main__':
for name, frames in ANIMS.items():
save(name, frames)
Subir todo de una vez
Junta los PNG en un zip y arrástralo a la ventana de creación, o elige el zip en "Añadir en bloque", y cada casilla se llena de golpe. Si no están en zip, elige la carpeta en "Añadir en bloque". Antes de subir te muestra a qué casilla va cada archivo, y los que no coincidan en el nombre los asignas tú. Los zip de "Descargar todo" de arriba usan estos nombres, así que puedes probarlos tal cual.
Los archivos se llaman igual que la acción. No importan las mayúsculas, y puede haber carpetas dentro del zip.
- Personajes:
idle.pngwalk.pngsleep.pngpoked.pngthrow.pnghit.pngjump.pngeat.pngwave.pnghappy.pngoffline.png - Objetos:
fly.pngimpact.png, sonidosound.wav(la caca, solofly.png)
Revisa antes de subir
- 48 de alto, ancho múltiplo de 48, 8 cuadros o menos
- Fondo transparente, sin líneas de la plantilla
- Que las cuatro esquinas del cuadro no estén todas pintadas (si lo están, se toma como fondo sobrante y se rechaza)
- Mirando a la derecha, pies en la fila de abajo, misma posición en todos los cuadros



























