← EquipamientoObjeto 3Dfogon/carcaj
Carcaj con flechas
Arrastrá para girarlo// «Carcaj con flechas» · gpt-6-sol (medium)
// A leather quiver full of arrows: a tall cylindrical brown leather tube with darker stitched bands and a shoulder strap, and seven or eight arrow shafts sticking out of the top with red and white feathers.
const cx = 24, cy = 25;
const leather = ["#794522", "#874d29", "#985a30", "#aa6839"];
const dark = "#49301f";
const stitch = "#d6ae72";
// Solid leather tube, with a dark open mouth at the top.
for (let z = 0; z <= 29; z++) {
for (let x = 13; x <= 35; x++) {
for (let y = 14; y <= 36; y++) {
const r = Math.hypot(x - cx, y - cy);
if (r > 10.1) continue;
if (z >= 26 && r < 7.7) {
set(x, y, z, "#30251f");
continue;
}
let shade = y < 22 ? 2 : y > 29 ? 0 : 1;
if (z > 19 && y < 24) shade++;
if (rand() < 0.07) shade += rand() < 0.5 ? -1 : 1;
set(x, y, z, leather[Math.max(0, Math.min(3, shade))]);
}
}
}
// Heavy base and two stitched reinforcing bands.
for (const [z0, z1] of [[2, 5], [21, 24]]) {
for (let z = z0; z <= z1; z++)
for (let x = 13; x <= 35; x++)
for (let y = 14; y <= 36; y++) {
const r = Math.hypot(x - cx, y - cy);
if (r > 8.5 && r <= 10.2)
set(x, y, z, z === z0 || z === z1 ? "#51301d" :
y < 25 ? "#684025" : "#54321f");
}
for (const x of [17, 21, 25, 29, 33]) {
const yf = Math.round(cy - Math.sqrt(Math.max(0, 100 - (x - cx) ** 2))) - 1;
set(x, yf, z0 + 1, stitch);
set(x + 1, yf, z0 + 2, "#b98c54");
}
}
for (let x = 17; x <= 31; x++)
for (let y = 16; y <= 34; y++)
if (Math.hypot(x - cx, y - cy) > 8.6 &&
Math.hypot(x - cx, y - cy) <= 10.1)
set(x, y, 0, dark);
// Front seam and its large, readable cross-stitches.
for (let z = 7; z <= 20; z++) {
set(24, 14, z, "#57351f");
set(25, 14, z, "#57351f");
}
for (let z = 9; z <= 19; z += 3) {
set(23, 14, z, stitch);
set(26, 14, z + 1, stitch);
}
// Seven staggered arrows. Their broad red-and-white fletchings rise above the rim.
const arrows = [
[18, 22, 39, true], [23, 21, 43, false], [29, 22, 40, true],
[19, 28, 43, false], [24, 27, 41, true], [30, 28, 44, false],
[26, 24, 45, true]
];
for (const [x, y, top, red] of arrows) {
box(x - 1, y - 1, 26, x + 1, y + 1, top - 2, "#967041");
box(x - 1, y - 1, 29, x - 1, y + 1, top - 3, "#b18a56");
box(x - 1, y - 1, top - 7, x + 1, y + 1, top - 6, "#d8c49b");
const main = red ? "#b93230" : "#f2e8d5";
const light = red ? "#e45344" : "#ffffff";
const shadow = red ? "#862b2c" : "#cfc9b7";
for (let z = top - 6; z <= top; z++) {
const wing = z === top || z === top - 6 ? 1 : 2;
box(x - wing, y - 1, z, x + wing, y + 1, z, main);
set(x - wing, y - 1, z, light);
set(x + wing, y + 1, z, shadow);
}
box(x, y - 2, top - 5, x + 1, y - 2, top - 1, light);
}
// Thick rolled lip, laid over the bottoms of the arrows.
for (let z = 28; z <= 30; z++)
for (let x = 12; x <= 36; x++)
for (let y = 13; y <= 37; y++) {
const r = Math.hypot(x - cx, y - cy);
if (r < 7.7 || r > 11.2) continue;
set(x, y, z, z === 30 ? "#b47a42" :
z === 28 ? "#53331e" : y < 25 ? "#945b32" : "#754526");
}
for (let x = 14; x <= 34; x++)
for (let y = 15; y <= 35; y++) {
const r = Math.hypot(x - cx, y - cy);
if (r >= 8.2 && r <= 10.5 && y < 25 && rand() < 0.16)
set(x, y, 30, "#d39a58");
}
// A wide shoulder strap loops free of the left side of the quiver.
const strapPath = [
[15, 21, 26], [9, 20, 34], [5, 19, 35],
[4, 17, 30], [4, 17, 17], [7, 17, 9], [15, 17, 7]
];
for (let i = 1; i < strapPath.length; i++) {
const a = strapPath[i - 1], b = strapPath[i];
line(...a, ...b, 2.4, "#49301f");
line(...a, ...b, 1.5, "#a16b3e");
}
for (let z = 19; z <= 28; z += 3) {
set(4, 14, z, "#d5a877");
set(5, 15, z + 1, "#d5a877");
}
// Brass strap rivets and a small buckle.
for (const [x, y, z] of [[15, 20, 26], [15, 16, 7]]) {
sphere(x, y, z, 2, "#62421f");
set(x, y - 2, z, "#e6bd6a");
set(x + 1, y - 1, z + 1, "#f4d587");
}
box(3, 14, 16, 6, 18, 20, "#66451f");
box(3, 13, 16, 6, 13, 20, "#c18b42");
box(4, 12, 17, 5, 12, 19, "#6d4925");
set(5, 11, 18, "#f1cd78");import { draw } from "./assets/voxel";
import { carcaj } from "./assets/carcaj";
// En cada cuadro: parado sobre (x, y), el centro de su base.
draw(ctx, carcaj, 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 carcaj
# Con las herramientas de Fogón (conector)
add_assets({ slug: "<tu-juego>", ids: ["carcaj"] })
# Queda en client/assets/carcaj.ts
# https://fogon.page/object/carcaj