← AnimalesObjeto 3Dfogon/tiburon
Tiburón
Arrastrá para girarlo// «Tiburón» · gpt-6-sol (medium)
// A cartoon shark, horizontal along y, head at the front (-y): a grey streamlined body with a white belly, a big pointed snout, a wide mouth with rows of white triangular teeth, black eyes, a tall triangular dorsal fin, two pectoral fins and a tall vertical tail fin at the back.
const grey = "#718b99";
const lightGrey = "#8fa7b2";
const darkGrey = "#58717f";
const white = "#f4f3e9";
const bellyShade = "#d9e2df";
const mouth = "#293b46";
// A rounded head, tapering body, and projecting pointed snout.
ellipsoid(24, 20, 16, 11, 14, 10, grey);
ellipsoid(24, 30, 15, 8, 11, 8, grey);
for (let y = 5; y <= 16; y++) {
const t = (y - 5) / 11;
const rx = 2 + 8.5 * Math.sqrt(t);
const rz = 3 + 5.5 * Math.sqrt(t);
for (let x = Math.floor(24 - rx); x <= Math.ceil(24 + rx); x++) {
for (let z = Math.floor(16 - rz); z <= Math.ceil(16 + rz); z++) {
if (((x - 24) / rx) ** 2 + ((z - 16) / rz) ** 2 <= 1) {
set(x, y, z, grey);
}
}
}
}
// Pale underside and subtle variation across the broad grey surfaces.
forEach((x, y, z, color) => {
if (color !== grey) return;
if (z <= 12 + (Math.abs(x - 24) > 6 ? 1 : 0)) {
set(x, y, z, rand() < 0.17 ? bellyShade : white);
} else if (z >= 21) {
set(x, y, z, rand() < 0.13 ? grey : lightGrey);
} else if (rand() < 0.07) {
set(x, y, z, darkGrey);
}
});
// A broad smiling mouth beneath the overhanging snout.
ellipsoid(24, 10, 10, 8, 4, 2.8, mouth);
ellipsoid(24, 11, 7, 8, 5, 2.5, bellyShade);
ellipsoid(24, 10, 6, 6, 3, 1.5, white);
// Two staggered rows of little triangular teeth.
for (const tx of [18, 21, 24, 27, 30]) {
const fy = 7 + Math.floor(Math.abs(tx - 24) / 3);
for (let dx = -1; dx <= 1; dx++) {
set(tx + dx, fy, 12, white);
set(tx + dx, fy + 1, 12, white);
}
set(tx, fy, 11, white);
set(tx, fy, 10, white);
}
for (const tx of [19, 22, 25, 28, 31]) {
const fy = 7 + Math.floor(Math.abs(tx - 24) / 3);
for (let dx = -1; dx <= 1; dx++) set(tx + dx, fy, 8, white);
set(tx, fy, 9, white);
}
// Simple shiny dot eyes, one on each side.
for (const side of [-1, 1]) {
ellipsoid(24 + side * 9.4, 14, 21, 1.5, 1.8, 1.8, "#192b34");
set(Math.round(24 + side * 10.5), 13, 22, "#ffffff");
}
// Tall swept-back dorsal fin.
for (let z = 23; z <= 38; z++) {
const t = (z - 23) / 15;
const y0 = Math.ceil(21 + 4 * t);
const y1 = Math.floor(34 - 9 * t);
const halfWidth = t < 0.45 ? 2 : 1;
for (let y = y0; y <= y1; y++) {
for (let x = 24 - halfWidth; x <= 24 + halfWidth; x++) {
set(x, y, z, x < 24 || z > 34 ? lightGrey : grey);
}
}
}
// Broad pectoral fins slope down to the floor at z = 0.
for (const side of [-1, 1]) {
const finLength = 11;
for (let d = 0; d <= finLength; d++) {
const x = 24 + side * (9 + d);
const t = d / finLength;
const cy = 23 + 9 * t;
const halfLength = Math.max(0, Math.round(5 * (1 - t)));
const cz = Math.round(12 * (1 - t));
const thickness = t < 0.55 ? 1 : 0;
for (let y = Math.round(cy) - halfLength; y <= Math.round(cy) + halfLength; y++) {
for (let z = cz; z <= cz + thickness; z++) {
set(x, y, z, z > cz ? lightGrey : darkGrey);
}
}
}
}
// The entire tail swings sideways from its joint.
part("tail", [24, 37, 16]);
for (let y = 37; y <= 43; y++) {
const r = Math.max(2, 5 - (y - 37) * 0.48);
for (let x = Math.floor(24 - r); x <= Math.ceil(24 + r); x++) {
for (let z = Math.floor(16 - r); z <= Math.ceil(16 + r); z++) {
if (((x - 24) / r) ** 2 + ((z - 16) / r) ** 2 <= 1) {
set(x, y, z, z < 14 ? bellyShade : grey);
}
}
}
}
// Chunky vertical tail fin, with a taller upper lobe.
for (let z = 3; z <= 33; z++) {
const distance = Math.abs(z - 16);
const upper = z >= 16;
const t = distance / (upper ? 17 : 13);
const y0 = Math.ceil(40 + 5 * t);
const y1 = Math.floor(46 - t);
const width = t < 0.65 ? 2 : 1;
for (let y = y0; y <= y1; y++) {
for (let x = 24 - width; x <= 24 + width; x++) {
set(x, y, z, x < 24 ? lightGrey : grey);
}
}
}
animate("tail", { type: "swing", axis: "z", speed: 4, amplitude: 0.35 });
part("body", [24, 24, 16]);import { draw } from "./assets/voxel";
import { tiburon } from "./assets/tiburon";
// En cada cuadro: parado sobre (x, y), el centro de su base.
draw(ctx, tiburon, 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 tiburon
# Con las herramientas de Fogón (conector)
add_assets({ slug: "<tu-juego>", ids: ["tiburon"] })
# Queda en client/assets/tiburon.ts
# https://fogon.page/object/tiburon