← MedievalObjeto 3Dfogon/wooden-barrel
Barril de madera
Arrastrá para girarlo// «Barril de madera» · propio
// An oak barrel standing upright: curved staves in warm brown tones, two dark iron hoops, a flat lid with planks.
// An upright oak barrel: curved staves, two iron hoops and a plank lid set a little below the rim.
const staves = ["#7d5029", "#8f5e30", "#a06c38", "#b17a42", "#bf8a50"];
const seam = "#573618";
const iron = ["#2b2928", "#3a3735", "#4b4744"];
const CX = 24, CY = 24, H = 40;
const clampi = (v, lo, hi) => Math.max(lo, Math.min(hi, v));
// Wider in the middle than at the ends.
const radius = (z) => 10.6 + 4.3 * Math.sin((Math.PI * (z + 4)) / (H + 7));
for (let z = 0; z < H; z++) {
const hoop = (z >= 6 && z <= 8) || (z >= 30 && z <= 32);
const r = radius(z) + (hoop ? 0.75 : 0);
for (let x = Math.floor(CX - r - 1); x <= Math.ceil(CX + r + 1); x++)
for (let y = Math.floor(CY - r - 1); y <= Math.ceil(CY + r + 1); y++) {
const d = Math.hypot(x - CX, y - CY);
if (d > r) continue;
// Hollow, except the bottom and the lid.
const lid = z === H - 4 || z === H - 5;
if (d < r - 2.3 && z > 1 && !lid) continue;
if (lid && d < r - 2.3) {
// The lid: planks across, a darker line between them.
const plank = Math.floor((x + 2) / 5);
const line = (x + 2) % 5 === 0;
set(x, y, z, line ? seam : staves[clampi(2 + ((plank * 3) % 3) - (rand() < 0.15 ? 1 : 0), 1, 4)]);
continue;
}
if (z > H - 4 && d < r - 2.3) continue;
if (hoop && d > r - 1.6) {
set(x, y, z, iron[z % 3 === 1 ? 2 : y < CY ? 1 : 0]);
continue;
}
const a = (Math.atan2(y - CY, x - CX) + Math.PI) / (Math.PI * 2);
const s = a * 20;
const k = Math.floor(s);
if (s - k < 0.13 && d > r - 1.3) {
set(x, y, z, seam);
continue;
}
// Each stave its own tone; lighter towards the top and on the side the light comes from.
let tone = 1 + ((k * 5 + 2) % 3);
if (z > 26) tone++;
if (z < 9) tone--;
if (x < CX - 3 && y < CY) tone++;
if (x > CX + 4 && y > CY) tone--;
if (rand() < 0.1) tone--;
set(x, y, z, staves[clampi(tone, 0, 4)]);
}
}
// The rim's top edge, worn pale.
for (let x = 8; x <= 40; x++)
for (let y = 8; y <= 40; y++) {
const d = Math.hypot(x - CX, y - CY);
const r = radius(H - 1);
if (d <= r && d >= r - 2.3 && rand() < 0.75) set(x, y, H - 1, staves[4]);
}
// A bung on the lid and a few rivets on the hoops.
box(27, 20, H - 3, 28, 21, H - 3, seam);
for (let i = 0; i < 10; i++) {
const a = (i / 10) * Math.PI * 2 + 0.3;
for (const z of [7, 31]) {
const r = radius(z) + 1.2;
set(CX + Math.cos(a) * r, CY + Math.sin(a) * r, z, "#6a6560");
}
}import { draw } from "./assets/voxel";
import { woodenBarrel } from "./assets/wooden-barrel";
// En cada cuadro: parado sobre (x, y), el centro de su base.
draw(ctx, woodenBarrel, 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 wooden-barrel
# Con las herramientas de Fogón (conector)
add_assets({ slug: "<tu-juego>", ids: ["wooden-barrel"] })
# Queda en client/assets/wooden-barrel.ts
# https://fogon.gg/object/wooden-barrel