← BásicoObjeto 3Dfogon/arpa
Arpa
Arrastrá para girarlo// «Arpa» · gpt-6-sol (medium)
// Harp («Arpa»).
const dark = "#69401f";
const shadow = "#805021";
const wood = "#a66a2b";
const amber = "#bf8534";
const gold = "#d5a64c";
const light = "#e5c776";
const ivory = "#f2dda0";
function topZ(x) {
return Math.round(x <= 21 ? 34 + (x - 14) * 0.9 : 40 - (x - 21) * 0.32);
}
function bottomZ(x) {
return Math.round(8 + (x - 16) * 1.36);
}
// Low, irregular carved base.
box(10, 20, 1, 25, 30, 3, shadow);
box(11, 18, 2, 23, 29, 5, wood);
box(12, 17, 4, 20, 28, 7, amber);
box(10, 19, 0, 15, 29, 2, dark);
box(15, 17, 0, 22, 30, 2, dark);
box(11, 17, 3, 24, 19, 4, gold);
box(12, 17, 5, 20, 18, 6, light);
for (let x = 10; x <= 24; x++) {
if (x % 3 !== 0) set(x, 17, 4, x % 2 ? ivory : gold);
if (rand() < 0.65) set(x, 20 + Math.floor(rand() * 9), 5, gold);
}
// Short projecting toes along the front.
for (const x of [13, 18, 23, 27]) {
box(x, 13, 0, x + 2, 18, 1, dark);
box(x, 13, 1, x + 2, 16, 2, gold);
box(x, 13, 2, x + 1, 14, 2, ivory);
}
box(9, 21, 1, 11, 27, 3, wood);
box(23, 22, 1, 27, 28, 3, wood);
box(10, 18, 4, 13, 30, 6, gold);
box(13, 19, 6, 18, 29, 8, amber);
// Tall carved pillar at the left of the strings.
box(11, 21, 8, 16, 28, 32, dark);
box(11, 19, 9, 15, 26, 32, wood);
box(11, 18, 10, 12, 25, 31, amber);
box(12, 18, 10, 13, 19, 31, light);
box(14, 19, 9, 14, 20, 31, gold);
box(15, 20, 9, 16, 22, 31, shadow);
for (let z = 11; z < 31; z++) {
if (rand() < 0.17) set(12, 18, z, gold);
}
box(10, 18, 7, 17, 29, 9, shadow);
box(11, 17, 8, 16, 27, 9, gold);
box(11, 17, 9, 14, 19, 10, ivory);
// Rising diagonal wooden soundboard, thick behind the strings.
for (let x = 16; x <= 38; x++) {
const z = bottomZ(x);
box(x, 22, z - 2, x, 28, z + 1, dark);
box(x, 20, z - 1, x, 24, z + 1, wood);
set(x, 20, z + 1, gold);
if (x % 3 === 0) set(x, 21, z + 2, light);
}
// Curved upper neck, with a substantial dark wooden underside.
for (let x = 13; x <= 38; x++) {
const z = topZ(x);
box(x, 21, z - 3, x, 28, z - 1, shadow);
box(x, 18, z - 2, x, 25, z, amber);
box(x, 19, z, x, 27, z, gold);
set(x, 18, z, x % 3 === 0 ? ivory : light);
if (x % 2 === 0) set(x, 17, z - 1, ivory);
}
// Broader scroll-like bend above the pillar.
box(10, 20, 31, 15, 28, 34, wood);
box(11, 18, 33, 17, 27, 35, gold);
box(13, 19, 35, 20, 27, 37, amber);
box(16, 21, 37, 22, 27, 39, wood);
box(18, 22, 39, 22, 27, 40, gold);
for (const [x, z] of [[10,33],[11,34],[13,35],[15,36],[18,38],[21,40]]) {
box(x, 17, z, x + 1, 20, z, ivory);
}
box(35, 19, 32, 38, 27, 35, wood);
box(37, 17, 33, 39, 25, 34, gold);
box(38, 18, 31, 39, 24, 33, shadow);
// Vertical strings: pale metallic strings interspersed with red and blue windings.
const stringColors = [
"#b4bbb0", "#e5d7a8", "#31505a", "#ded5b2",
"#a94e39", "#eadbb3", "#385560", "#d9caa0",
"#a84839", "#e7d8a8", "#38515a", "#e1d3a8",
"#a5503b", "#d9c99d", "#40585b", "#e8d8ad",
"#b35a3d", "#d6c8a2", "#455c5e"
];
for (let x = 17; x <= 35; x++) {
const upper = topZ(x) - 3;
const lower = bottomZ(x) + 2;
const color = stringColors[x - 17];
for (let z = lower; z <= upper; z++) {
set(x, 18, z, color);
if ([21, 25, 29, 33].includes(x)) set(x, 19, z, color);
}
set(x, 17, upper + 1, ivory);
set(x, 18, lower - 1, gold);
}
// Bright stepped edges and individual tuning pegs along the crown.
for (let x = 15; x <= 37; x++) {
const z = topZ(x);
if (x % 2 === 1) {
box(x, 17, z + 1, x, 20, z + 1, ivory);
set(x, 20, z + 2, light);
}
if (x % 3 === 0) set(x, 27, z, dark);
const b = bottomZ(x);
if (x <= 35 && x % 2 === 0) set(x, 19, b + 1, light);
}
for (let x = 17; x <= 34; x += 3) {
const z = bottomZ(x);
box(x, 19, z - 1, x + 1, 21, z, gold);
set(x, 18, z, ivory);
}import { draw } from "./assets/voxel";
import { arpa } from "./assets/arpa";
// En cada cuadro: parado sobre (x, y), el centro de su base.
draw(ctx, arpa, 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 arpa
# Con las herramientas de Fogón (conector)
add_assets({ slug: "<tu-juego>", ids: ["arpa"] })
# Queda en client/assets/arpa.ts
# https://fogon.page/object/arpa