← AnimalesObjeto 3Dfogon/caballito-de-mar
Caballito de mar
Arrastrá para girarlo// «Caballito de mar» · gpt-6-sol (medium)
// A cartoon seahorse standing upright facing sideways (snout toward -y): a curved yellow-orange body with ridged segments, a horse-like head with a long tube snout and a little crown, a big eye, a small back fin and a tail curling into a spiral at the bottom.
part("body", [24, 24, 22]);
const gold = "#f6ad32";
const light = "#ffd257";
const shadow = "#d98122";
// Curled tail: a thick outer coil narrowing into a little spiral tip.
const tail = [
[28, 17, 3.5], [32, 14, 3.2], [37, 12, 3.0],
[40, 9, 2.8], [40, 5, 2.6], [37, 2, 2.4],
[32, 2, 2.2], [28, 5, 2.0], [28, 9, 1.9],
[32, 11, 1.7], [35, 9, 1.5], [35, 6, 1.3],
[33, 6, 1.2]
];
for (let i = 0; i < tail.length - 1; i++) {
const a = tail[i], b = tail[i + 1];
line(24, a[0], a[1], 24, b[0], b[1], a[2] + 0.5, shadow);
line(24, a[0], a[1] + 0.5, 24, b[0], b[1] + 0.5, a[2], gold);
}
// Fan-shaped dorsal fin, tucked behind the body.
const fin = [
[29, 23], [37, 22], [35, 26], [41, 27],
[36, 29], [39, 33], [32, 31], [29, 29]
];
function inFin(y, z) {
let inside = false;
for (let i = 0, j = fin.length - 1; i < fin.length; j = i++) {
const a = fin[i], b = fin[j];
if ((a[1] > z) !== (b[1] > z) &&
y < (b[0] - a[0]) * (z - a[1]) / (b[1] - a[1]) + a[0]) {
inside = !inside;
}
}
return inside;
}
for (let x = 21; x <= 27; x++)
for (let y = 29; y <= 41; y++)
for (let z = 22; z <= 33; z++)
if (inFin(y, z)) set(x, y, z, x === 27 ? "#ffbd49" : "#e88934");
for (const tip of [[37, 23], [40, 27], [38, 32]]) {
line(27, 29, 27, 27, tip[0], tip[1], 0, "#ffd06a");
}
// Rounded, forward-curving torso and narrow neck.
ellipsoid(24, 26, 22, 7.5, 7.5, 10, shadow);
ellipsoid(24, 25, 25, 7.6, 7.1, 9.5, gold);
ellipsoid(24, 25, 31, 6, 5.5, 7, gold);
ellipsoid(24, 22, 35, 5.5, 5, 5.5, gold);
// A few subtle speckles on the large golden surfaces.
forEach((x, y, z, color) => {
if (color === gold && rand() < 0.035)
set(x, y, z, rand() < 0.5 ? "#f9b840" : "#e99a2b");
});
// Pale rounded belly; the raised ribs remain visible along both sides.
ellipsoid(24, 20, 23, 5.4, 3.8, 8.3, "#ffcf64");
for (const z of [18, 21, 24, 27, 30]) {
for (const x of [17, 31]) {
line(x, 23, z + 1, x, 29, z - 1, 0.8, "#dc8727");
line(x + (x < 24 ? -1 : 1), 24, z + 2,
x + (x < 24 ? -1 : 1), 28, z, 0, "#ffc149");
}
}
// Oversized horse-like head and long tubular muzzle.
ellipsoid(24, 20, 38, 6.5, 6.5, 5.2, shadow);
ellipsoid(24, 19, 38.5, 6.3, 6.2, 5, gold);
ellipsoid(24, 18, 35, 5, 5.5, 3.5, "#f8b63e");
cylinder(24, 11, 34, 2.7, 9, gold, "y");
ellipsoid(24, 10, 33.5, 3.8, 2.4, 2.8, light);
box(22, 8, 31, 26, 9, 31, "#db8730");
set(21, 8, 34, "#aa6229");
set(27, 8, 34, "#aa6229");
// A tiny fin beside each cheek.
for (const x of [17, 31]) {
ellipsoid(x, 27, 32, 1.6, 3.4, 2.2, "#ef9130");
line(x, 27, 32, x, 30, 33, 0, "#ffd064");
}
// Crown-shaped crest with three distinct points.
box(22, 17, 41, 26, 26, 42, "#e98929");
box(22, 16, 42, 26, 18, 44, "#ffc34b");
box(22, 20, 42, 26, 22, 46, "#ffd65b");
box(22, 24, 42, 26, 26, 44, "#ffc34b");
box(23, 20, 46, 25, 22, 46, "#fff09b");
// Big, simple toy eyes, visible from either side.
for (const side of [-1, 1]) {
const eyeX = 24 + side * 6;
ellipsoid(eyeX, 17, 39, 1.5, 2.1, 2.1, "#fff1ba");
ellipsoid(eyeX + side, 16, 39, 1.2, 1.5, 1.6, "#29272b");
set(eyeX + side * 2, 15, 40, "#ffffff");
ellipsoid(24 + side * 6, 19, 35, 1, 1.6, 0.8, "#ef8a39");
}
animate("body", { type: "bob", axis: "z", speed: 2, amplitude: 1.5 });import { draw } from "./assets/voxel";
import { caballitoDeMar } from "./assets/caballito-de-mar";
// En cada cuadro: parado sobre (x, y), el centro de su base.
draw(ctx, caballitoDeMar, x, y, { size: 64, angle: 0, t: performance.now() / 1000 });
// size: lo que mide en px su lado más largo
// angle: giro sobre el piso, en radianes
// t: segundos; si se mueve, se anima solo con eso# En una terminal, en la carpeta del juego
fogon assets add caballito-de-mar
# Con las herramientas de Fogón (conector)
add_assets({ slug: "<tu-juego>", ids: ["caballito-de-mar"] })
# Queda en client/assets/caballito-de-mar.ts
# https://fogon.page/object/caballito-de-mar