← Animals3D assetfogon/yaguarete
Yaguareté
Drag to turn it// «Yaguareté» · gpt-6-sol (medium)
// A powerful cartoon jaguar, horizontal along y, head at the front (-y): a muscular golden yellow body covered with black rosette spots (black rings with a dot inside), a white belly, four strong legs, a big round head with small rounded ears, amber eyes and a pink nose. A long spotted tail.
const gold = "#e9a932";
const lightGold = "#f5c34b";
const deepGold = "#cc8426";
const cream = "#fff0c8";
const shadowCream = "#e6d3a9";
const black = "#29221e";
const spotCenter = "#98551e";
// Chunky body and pale underside.
ellipsoid(24, 27, 20, 10, 12, 9, deepGold);
ellipsoid(24, 26, 21, 10, 12, 9, gold);
ellipsoid(24, 26, 16, 8, 10, 5, shadowCream);
ellipsoid(24, 25, 17, 7, 9, 4, cream);
forEach((x, y, z, color) => {
if (y >= 19 && y <= 37 && z >= 24 && color === gold && rand() < 0.13) {
set(x, y, z, lightGold);
}
});
// Rosettes follow the curved top and sides, rather than floating in space.
function topSurface(x, y) {
for (let z = 32; z >= 17; z--) if (get(x, y, z)) return z;
return -1;
}
function sideSurface(y, z, side) {
for (let x = side < 0 ? 12 : 36; side < 0 ? x <= 24 : x >= 24; x -= side) {
if (get(x, y, z)) return x;
}
return -1;
}
function topRosette(cx, cy) {
for (let dx = -2; dx <= 2; dx++) for (let dy = -2; dy <= 2; dy++) {
const d = dx * dx + dy * dy;
if (d > 5) continue;
const x = cx + dx, y = cy + dy;
const z = topSurface(x, y);
if (z < 25 || y < 19) continue;
set(x, y, z + 1, d === 0 ? spotCenter : d >= 2 ? black : lightGold);
}
}
function sideRosette(cy, cz, side) {
for (let dy = -2; dy <= 2; dy++) for (let dz = -2; dz <= 2; dz++) {
const d = dy * dy + dz * dz;
if (d > 5) continue;
const y = cy + dy, z = cz + dz;
if (z < 19) continue;
const x = sideSurface(y, z, side);
if (x < 0 || Math.abs(x - 24) < 5) continue;
set(x + side, y, z, d === 0 ? spotCenter : d >= 2 ? black : gold);
}
}
for (const [x, y] of [
[20, 20], [27, 21], [24, 25], [19, 27], [29, 28],
[23, 32], [28, 34], [19, 34]
]) topRosette(x, y);
for (const side of [-1, 1]) {
for (const [y, z] of [
[20, 23], [25, 21], [30, 23], [35, 21],
[23, 26], [28, 26], [33, 26]
]) sideRosette(y, z, side);
}
// Long, curled tail, with bold dark markings and a black tip.
const tail = [
[24, 37, 21], [25, 40, 19], [27, 42, 19],
[29, 44, 21], [31, 44, 24], [32, 43, 27], [32, 41, 29]
];
for (let i = 1; i < tail.length; i++) {
line(...tail[i - 1], ...tail[i], 2, i % 2 ? gold : deepGold);
}
for (const i of [1, 3, 5]) {
sphere(...tail[i], 2.3, black);
sphere(...tail[i], 1.2, lightGold);
}
sphere(...tail[6], 2.4, black);
// Oversized round head.
ellipsoid(24, 12, 23, 8, 8, 8, deepGold);
ellipsoid(24, 11, 24, 8, 8, 7, gold);
ellipsoid(24, 12, 27, 6, 5, 3, lightGold);
// Little rounded ears, with visible inner ears at the front.
for (const x of [17, 31]) {
sphere(x, 12, 30, 3, deepGold);
sphere(x, 11, 30, 2.5, gold);
ellipsoid(x, 8.5, 30, 1.4, 0.8, 1.5, "#a75c50");
}
// Forehead markings.
for (const x of [20, 24, 28]) {
box(x, 7, 30, x, 9, 31, black);
set(x, 8, 31, spotCenter);
}
for (const x of [17, 31]) {
box(x, 13, 25, x, 15, 26, black);
set(x, 14, 26, spotCenter);
}
// Bright amber eyes with simple black pupils and tiny highlights.
for (const x of [20, 28]) {
ellipsoid(x, 4.6, 25, 2, 1, 2, black);
ellipsoid(x, 3.6, 25, 1.4, 0.8, 1.4, "#f4a936");
box(x, 2.8, 24, x, 3, 25, black);
set(x - 1, 2, 26, "#ffffff");
}
// Rounded white cheeks, whisker freckles, smile and pink nose.
ellipsoid(21, 4.5, 19, 3.4, 2.6, 2.8, cream);
ellipsoid(27, 4.5, 19, 3.4, 2.6, 2.8, cream);
ellipsoid(24, 5, 16, 3, 2, 1.5, shadowCream);
for (const x of [19, 21, 27, 29]) set(x, 2, 19, black);
box(23, 1, 20, 25, 2, 21, "#ee8991");
set(24, 1, 19, "#c86778");
set(24, 2, 17, black);
line(22, 2, 16, 24, 2, 15, 0, black);
line(24, 2, 15, 26, 2, 16, 0, black);
// Each sturdy leg is a separate walking part.
function leg(name, x, y, speed) {
part(name, [x, y, 16]);
ellipsoid(x, y, 12, 3.6, 3.5, 5, deepGold);
ellipsoid(x, y - 0.5, 9, 3, 3, 6, gold);
ellipsoid(x, y - 2, 2, 3.5, 3.5, 2.5, gold);
ellipsoid(x, y - 2, 1, 3, 3, 1, deepGold);
const side = x < 24 ? -1 : 1;
for (const [dy, z] of [[0, 12], [-1, 8]]) {
box(x + side * 3, y + dy, z, x + side * 3, y + dy + 1, z + 1, black);
}
for (const dx of [-2, 0, 2]) {
set(x + dx, y - 5, 2, shadowCream);
}
animate(name, { type: "swing", axis: "x", speed, amplitude: 0.3 });
part("body");
}
leg("front-left", 17, 18, 5);
leg("front-right", 31, 18, -5);
leg("rear-left", 17, 34, -5);
leg("rear-right", 31, 34, 5);import { draw } from "./assets/voxel";
import { yaguarete } from "./assets/yaguarete";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, yaguarete, x, y, { size: 64, angle: 0, t: performance.now() / 1000 });
// size: its longest side, in px
// angle: turn on the floor, in radians
// t: seconds; if it moves, that animates it# In a terminal, in the game's folder
fogon assets add yaguarete
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["yaguarete"] })
# It lands in client/assets/yaguarete.ts
# https://fogon.page/object/yaguarete