← Piratas y marObjeto 3Dfogon/ancla
Ancla
Arrastrá para girarlo// «Ancla» · gpt-6-sol (medium)
// A huge dark iron ship anchor standing upright on its two curved flukes, a thick vertical shank with a crossbar at the top and a big ring, with a thick rope wrapped around it.
// Dark iron anchor with broad, upturned flukes.
const iron = "#303b43";
const shadow = "#1e2931";
const light = "#53636a";
const gleam = "#728087";
const rust = "#81543a";
// Thick shank, with brighter edges on its front face.
box(21, 21, 5, 27, 27, 38, iron);
box(22, 20, 7, 26, 20, 37, shadow);
box(21, 21, 8, 21, 26, 36, light);
box(22, 20, 10, 22, 20, 35, light);
box(21, 21, 5, 27, 27, 7, shadow);
box(22, 20, 7, 26, 20, 8, light);
// Curved arms rise from the crown toward the flukes.
sphere(24, 24, 6, 4, shadow);
for (const side of [-1, 1]) {
const points = [
[24, 6], [20, 4], [16, 2], [12, 2],
[9, 4], [7, 7], [6, 10]
];
for (let i = 0; i < points.length - 1; i++) {
const [ax, az] = points[i];
const [bx, bz] = points[i + 1];
line(24 + side * (ax - 24), 24, az,
24 + side * (bx - 24), 24, bz, 3, iron);
}
// A glint follows the visible front of each curved arm.
for (let i = 0; i < points.length - 1; i++) {
const [ax, az] = points[i];
const [bx, bz] = points[i + 1];
line(24 + side * (ax - 24), 20, az + 1,
24 + side * (bx - 24), 20, bz + 1, 0, light);
}
// Broad, solid triangular fluke. Its outer point hooks upward.
for (let z = 0; z <= 17; z++) {
let lo, hi;
if (z <= 5) {
lo = Math.round(9 - z * 0.8);
hi = Math.round(12 - z * 0.2);
} else {
lo = Math.max(4, Math.round(5 - (z - 5) * 0.10));
hi = Math.round(11 - (z - 5) * 0.5);
}
const halfDepth = z > 13 ? 2 : z > 9 ? 3 : 4;
for (let a = lo; a <= hi; a++) {
const x = 24 + side * (a - 24);
for (let y = 24 - halfDepth; y <= 24 + halfDepth; y++) {
const c = y === 24 - halfDepth ? light :
y === 24 + halfDepth ? shadow :
a === lo ? "#46565d" : iron;
set(x, y, z, c);
}
}
}
// Polished leading edge and a few warm, weathered nicks.
for (let z = 7; z <= 15; z++) {
const a = Math.max(4, Math.round(5 - (z - 5) * 0.10));
const x = 24 + side * (a - 24);
set(x, z > 13 ? 22 : z > 9 ? 21 : 20, z, gleam);
}
for (const [a, z] of [[9, 3], [7, 6], [6, 10]]) {
set(24 + side * (a - 24), 19 + (z > 9 ? 2 : 1), z, rust);
}
}
// Heavy crossbar and capped ends.
box(9, 22, 32, 39, 26, 35, iron);
box(10, 21, 33, 38, 21, 34, light);
box(10, 22, 35, 38, 25, 35, light);
for (const x of [9, 39]) {
box(x - 1, 20, 31, x + 1, 27, 36, shadow);
box(x - 1, 20, 33, x + 1, 20, 35, light);
box(x - 1, 22, 36, x + 1, 25, 36, gleam);
set(x, 19, 34, "#b8884c");
}
for (const x of [15, 33]) {
box(x - 1, 21, 32, x + 1, 21, 35, shadow);
set(x, 20, 34, "#a87442");
}
// Large iron ring, in the same plane as the anchor.
for (let i = 0; i < 80; i++) {
const t = i * Math.PI * 2 / 80;
const x = 24 + 3.9 * Math.cos(t);
const z = 40 + 3.9 * Math.sin(t);
sphere(x, 24, z, 1.35, shadow);
}
for (let i = 0; i < 80; i++) {
const t = i * Math.PI * 2 / 80;
const x = 24 + 3.9 * Math.cos(t);
const z = 40 + 3.9 * Math.sin(t);
sphere(x, 22.8, z, 0.8, t > 0.1 && t < Math.PI ? gleam : light);
}
// Chunky golden-tan rope: several turns around the shaft.
for (let i = 0; i <= 180; i++) {
const t = i / 180;
const angle = t * Math.PI * 7.5;
const x = 24 + 5.1 * Math.cos(angle);
const y = 24 + 5.1 * Math.sin(angle);
const z = 16 + t * 14;
sphere(x, y, z, 1.15, y < 24 ? "#e0ac64" : "#aa713c");
if (y < 22 && i % 3 === 0) {
set(x, y - 1, z + 1, "#f4ce83");
}
}
// A short loose rope end hangs from the lower wrap.
line(29, 21, 16, 31, 18, 12, 1.3, "#bd8246");
line(31, 18, 12, 34, 18, 9, 1.2, "#bd8246");
line(34, 18, 9, 35, 19, 7, 1, "#e0ac64");
sphere(29, 20, 16, 1.5, "#f0c477");
// Sparse scuffs on the shank, kept clear of the rope's silhouette.
for (let i = 0; i < 22; i++) {
const x = 22 + Math.floor(rand() * 5);
const z = 9 + Math.floor(rand() * 23);
if (z < 15 || z > 30) {
set(x, 20, z, rand() < 0.65 ? "#46535a" : rust);
}
}import { draw } from "./assets/voxel";
import { ancla } from "./assets/ancla";
// En cada cuadro: parado sobre (x, y), el centro de su base.
draw(ctx, ancla, 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 ancla
# Con las herramientas de Fogón (conector)
add_assets({ slug: "<tu-juego>", ids: ["ancla"] })
# Queda en client/assets/ancla.ts
# https://fogon.page/object/ancla