← Piratas y marObjeto 3Dfogon/boya
Boya
Arrastrá para girarlo// «Boya» · gpt-6-sol (medium)
// A round floating buoy, red and white with a small light on top, sitting in a small ring of turquoise water.
// A little patch of sea, with an open center beneath the buoy.
part("body", [24, 24, 0]);
for (let x = 3; x <= 45; x++) {
for (let y = 3; y <= 45; y++) {
const dx = x - 24, dy = y - 24;
const r = Math.hypot(dx, dy);
const edge = 20.1 + 0.8 * Math.sin(x * 1.7 + y * 0.8)
+ 0.45 * Math.sin(y * 2.3 - x * 0.5);
if (r < 8.5 || r > edge) continue;
set(x, y, 0, r > edge - 1.5 ? "#087f91" : "#078fa0");
if (r < edge - 0.35) {
set(x, y, 1, rand() < 0.16 ? "#18bfd0" : "#0aaabd");
}
if (r < edge - 1.1 && rand() > 0.09) {
let color = "#25c6cc";
if (rand() < 0.23) color = "#49dad6";
if (dy > 8 && rand() < 0.42) color = "#0eabba";
set(x, y, 2, color);
}
// Broken, bright foam around the buoy and at the outer waterline.
if (r > 11.8 && r < 13.1 && rand() < 0.48)
set(x, y, 3, rand() < 0.5 ? "#c9fff0" : "#87eee3");
if (r > edge - 2.3 && r < edge - 1.3 && rand() < 0.24)
set(x, y, 2, "#b5fff0");
}
}
// The entire striped float rocks around its submerged base.
part("buoy", [24, 24, 4]);
const cx = 24, cy = 24, cz = 14.5;
const rx = 11.7, ry = 11.7, rz = 11.4;
for (let x = 12; x <= 36; x++) {
for (let y = 12; y <= 36; y++) {
for (let z = 3; z <= 26; z++) {
const q = ((x - cx) / rx) ** 2 +
((y - cy) / ry) ** 2 +
((z - cz) / rz) ** 2;
if (q > 1) continue;
const red = z <= 8 || (z >= 13 && z <= 17) || z >= 22;
const shadow = y > 29 || z < 7;
let color;
if (red) {
color = shadow ? "#bd2928" : z >= 20 ? "#ff6450" : "#eb3932";
if (!shadow && rand() < 0.12) color = "#fa5140";
} else {
color = shadow ? "#c6c9ba" : z >= 18 ? "#fff8df" : "#f3eee0";
if (!shadow && rand() < 0.11) color = "#ffffff";
}
set(x, y, z, color);
}
}
}
// A thin golden rope at the boundary of two stripes.
for (let i = 0; i < 128; i++) {
const a = i * Math.PI * 2 / 128;
set(24 + 11.55 * Math.cos(a), 24 + 11.55 * Math.sin(a),
13, i % 9 < 3 ? "#ffe087" : "#d99b37");
}
// Two stout mooring loops, silhouetted at either side.
for (const side of [-1, 1]) {
const x = 24 + side * 11;
box(x, 22, 13, x + side, 26, 14, "#80502d");
line(x + side, 22, 14, x + side * 2, 22, 17, 0, "#e4af55");
line(x + side * 2, 22, 17, x + side * 2, 26, 17, 0, "#e4af55");
line(x + side * 2, 26, 17, x + side, 26, 14, 0, "#b97936");
}
// A small gold anchor on the front of the red middle band.
function frontGold(x, z, color) {
const v = 1 - ((x - 24) / rx) ** 2 - ((z - cz) / rz) ** 2;
if (v > 0) set(x, 24 - ry * Math.sqrt(v) - 0.8, z, color);
}
for (let z = 14; z <= 19; z++) frontGold(24, z, "#ffd36b");
for (let x = 22; x <= 26; x++) frontGold(x, 18, "#ffd36b");
for (let x = 21; x <= 27; x++) {
if (x === 21 || x === 27 || (x >= 22 && x <= 26))
frontGold(x, 14, "#d99b37");
}
frontGold(22, 15, "#ffd36b");
frontGold(26, 15, "#ffd36b");
frontGold(24, 20, "#fff0aa");
// Short mast and a chunky, gold-framed beacon.
cylinder(24, 24, 25, 3, 2, "#ad3930");
cylinder(24, 24, 27, 2, 3, "#fff5dc");
cylinder(24, 24, 30, 3, 1, "#b87931");
cylinder(24, 24, 31, 3, 1, "#ffcd65");
for (const [dx, dy] of [[-3, 0], [3, 0], [0, -3], [0, 3]])
box(24 + dx, 24 + dy, 32, 24 + dx, 24 + dy, 34, "#e9ac46");
cylinder(24, 24, 35, 3, 1, "#ffd36b");
cylinder(24, 24, 36, 2, 1, "#a7652c");
// Only the red glass pulses; the gold housing remains solid.
part("light", [24, 24, 33]);
ellipsoid(24, 24, 33, 2, 2, 2, "#ff4337");
animate("buoy", { type: "swing", axis: "y", speed: 2, amplitude: 0.12 });
animate("light", {
type: "colors",
palette: ["#ff5547", "#a91921"],
pattern: "pulse",
glow: 0.6
});import { draw } from "./assets/voxel";
import { boya } from "./assets/boya";
// En cada cuadro: parado sobre (x, y), el centro de su base.
draw(ctx, boya, 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 boya
# Con las herramientas de Fogón (conector)
add_assets({ slug: "<tu-juego>", ids: ["boya"] })
# Queda en client/assets/boya.ts
# https://fogon.page/object/boya