← Piratas y marObjeto 3Dfogon/caracolas
Caracolas
Arrastrá para girarlo// «Caracolas» · gpt-6-sol (medium)
// A small pile of big colorful seashells on sand: a spiral conch in pink and cream, a fan-shaped scallop shell in orange, and a few small white shells.
// A low, sun-warmed patch of sand.
for (let x = 5; x <= 43; x++) {
for (let y = 7; y <= 40; y++) {
const d = ((x - 24) / 19) ** 2 + ((y - 24) / 17) ** 2;
if (d > 1) continue;
const height = Math.max(0, Math.floor(4 * (1 - d) + 0.8));
for (let z = 0; z <= height; z++) {
const color = z === height
? (rand() < 0.22 ? "#f9dca0" : "#efd093")
: "#d9b67e";
set(x, y, z, color);
}
}
}
// Orange scallop: a broad upright fan behind the conch.
const hingeX = 34;
for (let x = 24; x <= 44; x++) {
for (let z = 6; z <= 24; z++) {
const dx = x - hingeX;
const halfWidth = 1 + (z - 6) * 0.64;
const crown = 24 - 0.075 * dx * dx;
if (Math.abs(dx) > halfWidth || z > crown) continue;
const front = Math.round(28 - (z - 6) * 0.22);
for (let y = front; y <= front + 3; y++) {
let color = y === front ? "#ef9650" : "#c86b36";
if (z > crown - 2) color = y === front ? "#ffd080" : "#ea9955";
if (y === front && rand() < 0.055) color = "#f8b66c";
set(x, y, z, color);
}
// Raised ribs radiate from the narrow hinge.
for (const tip of [-9, -6, -3, 0, 3, 6, 9]) {
const ribX = hingeX + tip * (z - 6) / 17;
if (Math.abs(x - ribX) < 0.48 && z < crown - 1) {
set(x, front - 1, z, tip % 2 === 0 ? "#ffd087" : "#fbb46a");
}
}
}
}
sphere(34, 26, 7, 3, "#d57b3e");
box(32, 22, 6, 36, 23, 8, "#ffcb78");
// The conch's pointed, banded spire.
ellipsoid(25, 25, 11, 6, 5, 5, "#c96782");
ellipsoid(28, 25, 12, 4, 3, 4, "#e78e9c");
ellipsoid(31, 25, 12, 3, 2, 3, "#f4b3b4");
ellipsoid(34, 25, 12, 2, 1, 2, "#ffe0c4");
for (const [x, r] of [[27, 4], [30, 3], [33, 2]]) {
for (let y = 25 - r; y <= 25 + r; y++) {
for (let z = 12 - r; z <= 12 + r; z++) {
if ((y - 25) ** 2 + (z - 12) ** 2 <= r * r &&
rand() < 0.72) set(x, y, z, "#ffe0bd");
}
}
}
// Rounded pink body, shaded underneath and freckled on its sunny surface.
for (let x = 9; x <= 27; x++) {
for (let y = 15; y <= 31; y++) {
for (let z = 4; z <= 19; z++) {
const d = ((x - 18) / 9) ** 2 +
((y - 23) / 8) ** 2 +
((z - 11) / 8) ** 2;
if (d > 1) continue;
let color = z < 8 ? "#b95c78" : z > 14 ? "#f5a7ae" : "#e68198";
if (d > 0.76 && z > 10 && rand() < 0.12) color = "#ffd0bd";
set(x, y, z, color);
}
}
}
// Cream, flared opening at the lower-right front.
ellipsoid(23, 15, 8, 6, 2, 5, "#ffe5c4");
ellipsoid(23, 13, 8, 4, 1, 3, "#a94e69");
ellipsoid(22, 12, 8, 2, 1, 2, "#df8794");
for (let x = 18; x <= 28; x++) {
for (let z = 3; z <= 13; z++) {
const d = ((x - 23) / 5.5) ** 2 + ((z - 8) / 4.5) ** 2;
if (d > 0.66 && d <= 1.08) {
set(x, 12, z, z > 9 ? "#fff0d5" : "#f6cba9");
}
}
}
// A chunky cream spiral sitting on the conch's viewer-facing surface.
let previous = null;
for (let t = 0; t <= 11.2; t += 0.065) {
const radius = 0.5 + 0.48 * t;
const x = 17 + radius * Math.cos(t);
const z = 12 + radius * Math.sin(t);
const profile = 1 - ((x - 18) / 9) ** 2 - ((z - 11) / 8) ** 2;
if (profile <= 0.04) continue;
const y = 23 - 8 * Math.sqrt(profile) - 1;
if (previous) {
line(previous[0], previous[1], previous[2],
x, y, z, 0, "#fff0d4");
}
previous = [x, y, z];
}
sphere(17, 14, 12, 1, "#fff1d9");
// Little white shells scattered across the foreground sand.
function smallShell(cx, cy, cz, scale) {
ellipsoid(cx, cy, cz, scale + 1, scale, scale, "#d8c7ad");
ellipsoid(cx, cy - 1, cz + 1, scale + 1, scale, scale, "#fff8e9");
for (let i = -scale; i <= scale; i++) {
line(cx, cy - 2, cz,
cx + i, cy - 1, cz + scale, 0, "#e6d6bf");
}
set(cx, cy - 2, cz, "#f4c89b");
}
smallShell(11, 13, 3, 2);
smallShell(34, 12, 3, 2);
smallShell(27, 10, 2, 1);
smallShell(8, 26, 2, 1);
// A few warm grains and tiny beach pebbles.
for (let i = 0; i < 115; i++) {
const x = 6 + Math.floor(rand() * 37);
const y = 8 + Math.floor(rand() * 32);
const d = ((x - 24) / 19) ** 2 + ((y - 24) / 17) ** 2;
if (d > 0.94) continue;
const z = Math.max(0, Math.floor(4 * (1 - d) + 0.8)) + 1;
if (get(x, y, z) === undefined) {
set(x, y, z, rand() < 0.2 ? "#fff0c5" : "#dcb987");
}
}import { draw } from "./assets/voxel";
import { caracolas } from "./assets/caracolas";
// En cada cuadro: parado sobre (x, y), el centro de su base.
draw(ctx, caracolas, 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 caracolas
# Con las herramientas de Fogón (conector)
add_assets({ slug: "<tu-juego>", ids: ["caracolas"] })
# Queda en client/assets/caracolas.ts
# https://fogon.page/object/caracolas