← FantasíaObjeto 3Dfogon/carruaje-de-calabaza
Carruaje de calabaza
Arrastrá para girarlo// «Carruaje de calabaza» · gpt-6-sol (medium)
// A fairy-tale pumpkin carriage: a big round orange pumpkin body with a small door and window on the side, curly gold vine decorations, a gold crown on top, and four big ornate gold wheels, oriented along y with the front at -y.
const orange = ["#b94b19", "#d76520", "#ed8129", "#f39a37"];
const gold = "#efbd55", goldLight = "#ffe090", goldDark = "#a66a2e";
const wood = "#49312c", plum = "#492a61", glass = "#16cbd0";
// Pumpkin body: softly shaded, with subtle vertical lobes.
ellipsoid(24, 24, 22, 14, 13, 13, orange[2]);
forEach((x, y, z) => {
const angle = Math.atan2(y - 24, x - 24);
const rib = Math.cos(angle * 10);
let shade = z < 17 ? 1 : z > 28 ? 3 : 2;
if (rib < -0.83) shade = Math.max(0, shade - 1);
if (rib > 0.92 && z > 19) shade = Math.min(3, shade + 1);
if (rand() < 0.035) shade = Math.max(0, shade - 1);
set(x, y, z, orange[shade]);
});
// Undercarriage, axle beams, and a little front boarding step.
box(14, 12, 9, 34, 36, 11, wood);
box(15, 10, 11, 33, 38, 12, goldDark);
for (const y of [13, 35]) {
box(7, y - 1, 7, 41, y + 1, 9, wood);
box(9, y, 8, 39, y, 8, goldDark);
}
box(20, 7, 10, 28, 10, 11, wood);
box(20, 6, 12, 28, 9, 12, gold);
box(21, 6, 12, 27, 6, 12, goldLight);
// Rounded front doorway and its inset violet door.
box(20, 10, 15, 28, 12, 24, goldDark);
box(21, 9, 15, 27, 10, 24, gold);
box(22, 9, 25, 26, 11, 25, gold);
box(23, 9, 26, 25, 11, 26, goldLight);
box(22, 8, 16, 26, 8, 24, plum);
box(23, 8, 25, 25, 8, 25, plum);
for (const x of [22, 26]) box(x, 7, 17, x, 7, 23, "#b578b3");
box(23, 7, 18, 25, 7, 18, goldDark);
box(23, 7, 22, 25, 7, 23, goldDark);
set(25, 6, 20, goldLight);
set(25, 6, 21, gold);
// Two small glowing windows flanking the door.
for (const cx of [17, 31]) {
box(cx - 2, 11, 22, cx + 2, 12, 26, goldDark);
box(cx - 1, 10, 23, cx + 1, 10, 25, glass);
set(cx, 9, 24, "#a2ffff");
box(cx - 2, 9, 22, cx + 2, 9, 22, gold);
box(cx - 2, 9, 26, cx + 2, 9, 26, goldLight);
for (const x of [cx - 2, cx + 2]) box(x, 9, 23, x, 9, 25, gold);
set(cx, 8, 25, "#b5ffff");
}
// Larger arched window on the right side.
box(38, 20, 19, 39, 28, 27, goldDark);
box(39, 21, 20, 39, 27, 25, plum);
box(40, 22, 21, 40, 26, 25, glass);
box(40, 23, 22, 40, 25, 24, "#52f2ed");
box(40, 24, 20, 40, 24, 26, gold);
box(40, 21, 26, 40, 27, 26, goldLight);
for (const y of [20, 28]) box(40, y, 20, 40, y, 25, gold);
box(40, 22, 19, 40, 26, 19, goldLight);
// Curly gilded vines follow the pumpkin's front surface.
function frontY(x, z) {
const q = 1 - ((x - 24) / 14) ** 2 - ((z - 22) / 13) ** 2;
return Math.round(24 - 13 * Math.sqrt(Math.max(0, q)) - 1);
}
for (const side of [-1, 1]) {
let previous;
for (let i = 0; i <= 65; i++) {
const t = i / 65;
const a = t * Math.PI * 3.1;
const r = 4.2 * (1 - t) + 0.3;
const x = 24 + side * (8.8 + r * Math.cos(a));
const z = 27 + r * Math.sin(a);
const y = frontY(x, z);
if (previous) line(previous[0], previous[1], previous[2], x, y, z, 0, i % 9 < 3 ? goldLight : gold);
previous = [x, y, z];
}
for (const [x, z] of [[24 + side * 11, 19], [24 + side * 9, 32]]) {
sphere(x, frontY(x, z), z, 1, goldLight);
}
}
// Stem and little storybook crown.
cylinder(24, 24, 34, 3, 4, "#5c6532");
cylinder(24, 24, 36, 4, 2, goldDark);
cylinder(24, 24, 38, 5, 2, gold);
cylinder(24, 24, 40, 3, 1, plum);
sphere(24, 24, 41, 2, "#c333dc");
set(24, 22, 42, "#ff9cff");
for (let i = 0; i < 8; i++) {
const a = i * Math.PI / 4;
const x = Math.round(24 + 4 * Math.cos(a));
const y = Math.round(24 + 4 * Math.sin(a));
line(x, y, 39, x, y, i % 2 ? 42 : 43, 0, goldLight);
sphere(x, y, i % 2 ? 42 : 43, 1, i % 2 ? "#eb80ec" : goldLight);
}
// Four independently spinning wheels, each in the yz plane.
for (const x of [7, 41]) {
for (const y of [13, 35]) {
const name = `wheel_${x}_${y}`;
part(name, [x, y, 8]);
const outerX = x < 24 ? 5 : 43;
for (let xx = x - 2; xx <= x + 2; xx++) {
if (xx < 5 || xx > 43) continue;
for (let dy = -8; dy <= 8; dy++) {
for (let dz = -8; dz <= 8; dz++) {
const d = Math.hypot(dy, dz);
if (d >= 6.25 && d <= 8.15) {
const c = xx === outerX ? goldLight :
dz > 2 ? gold : goldDark;
set(xx, y + dy, 8 + dz, c);
}
}
}
}
for (let i = 0; i < 8; i++) {
const a = i * Math.PI / 4;
line(outerX, y, 8,
outerX, y + 7 * Math.cos(a), 8 + 7 * Math.sin(a),
0, i % 2 ? gold : goldLight);
const py = Math.round(y + 7 * Math.cos(a));
const pz = Math.round(8 + 7 * Math.sin(a));
sphere(outerX, py, pz, 1, i % 2 ? gold : goldLight);
}
sphere(outerX, y, 8, 2, goldDark);
sphere(outerX < x ? outerX - 1 : outerX + 1, y, 8, 1, goldLight);
set(outerX < x ? outerX - 2 : outerX + 2, y, 8, "#a94dd4");
animate(name, { type: "spin", axis: "x", speed: 3 });
}
}
part("body", [24, 24, 22]);import { draw } from "./assets/voxel";
import { carruajeDeCalabaza } from "./assets/carruaje-de-calabaza";
// En cada cuadro: parado sobre (x, y), el centro de su base.
draw(ctx, carruajeDeCalabaza, 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 carruaje-de-calabaza
# Con las herramientas de Fogón (conector)
add_assets({ slug: "<tu-juego>", ids: ["carruaje-de-calabaza"] })
# Queda en client/assets/carruaje-de-calabaza.ts
# https://fogon.page/object/carruaje-de-calabaza