← MedievalObjeto 3Dfogon/estandarte
Estandarte
Arrastrá para girarlo// «Estandarte» · gpt-6-sol (medium)
// A tall heraldic banner on a pole: a dark wooden pole with a gold spear tip on top standing in a stone base block, a horizontal crossbar near the top, and hanging from it a long vertical cloth banner in deep red with a royal blue border, a gold crown emblem in the middle and a swallow-tail (V-cut) bottom edge. The banner cloth is the moving part.
const stone = ["#918b80", "#a7a094", "#77736b", "#b8afa0"];
const moss = "#66715b";
const wood = "#493022";
const woodLight = "#65442c";
const woodDark = "#301f1b";
const iron = "#292b30";
const gold = "#e3af48";
const goldLight = "#f5d27a";
const goldDark = "#a87530";
const blue = "#243e82";
const blueLight = "#365aa3";
const blueDark = "#192d61";
const red = "#942b39";
const redLight = "#ad3844";
const redDark = "#762332";
// A stepped, weathered stone footing.
box(8, 17, 0, 20, 31, 1, stone[2]);
box(9, 18, 2, 19, 30, 4, stone[0]);
box(10, 19, 5, 18, 29, 6, stone[1]);
forEach((x, y, z, color) => {
if (!stone.includes(color)) return;
if (z === 0 && rand() < 0.18) set(x, y, z, stone[0]);
else if (z >= 2 && rand() < 0.15) set(x, y, z, stone[Math.floor(rand() * stone.length)]);
if ((y === 17 || y === 18) && z < 5 && rand() < 0.055) set(x, y, z, moss);
});
for (let x = 10; x <= 18; x += 4) {
set(x, 17, 1, stone[3]);
set(x + 2, 18, 3, stone[2]);
}
for (let x = 11; x <= 17; x += 3) {
set(x, 19, 6, stone[3]);
if (rand() < 0.5) set(x, 18, 4, moss);
}
// Square timber pole, with a lit edge and black iron collars.
box(13, 23, 6, 15, 25, 41, wood);
box(13, 23, 7, 13, 23, 40, woodLight);
box(15, 25, 7, 15, 25, 40, woodDark);
for (let z = 10; z <= 34; z += 6) {
if (rand() < 0.8) set(14, 23, z, "#704b30");
}
for (const z of [7, 31, 36, 40]) {
box(12, 22, z, 16, 26, z, iron);
set(14, 21, z, "#77746b");
set(16, 23, z, "#77746b");
}
// Sturdy crossbar and its ornamental end caps.
box(12, 23, 37, 40, 25, 39, woodDark);
box(12, 22, 38, 40, 23, 39, wood);
box(16, 22, 39, 39, 22, 39, woodLight);
box(11, 22, 37, 12, 26, 40, goldDark);
box(39, 22, 37, 41, 26, 40, goldDark);
box(11, 22, 39, 12, 25, 40, goldLight);
box(40, 22, 39, 41, 25, 40, gold);
for (const x of [17, 25, 33, 38]) {
set(x, 21, 38, goldDark);
set(x, 21, 39, goldLight);
}
// Gilded spearhead above the pole.
box(12, 22, 41, 16, 26, 42, goldDark);
box(13, 23, 43, 15, 25, 43, gold);
box(14, 23, 44, 14, 25, 44, goldLight);
set(14, 24, 45, goldLight);
set(13, 22, 42, goldLight);
// The entire textile, including its hanging loops, moves as one piece.
part("banner cloth", [29, 23, 38]);
const bottom = x => 9 + Math.floor(7 * (1 - Math.abs(x - 28.5) / 10.5));
for (let x = 18; x <= 39; x++) {
const hem = bottom(x);
for (let z = hem; z <= 35; z++) {
const border = x <= 20 || x >= 37 || z >= 34 || z <= hem + 1;
const front = border
? (rand() < 0.15 ? blueLight : blue)
: (rand() < 0.13 ? redLight : red);
set(x, 20, z, front);
set(x, 21, z, border ? blue : redDark);
set(x, 22, z, border ? blueDark : redDark);
}
// Bright woven piping follows both sides of the V-cut hem.
set(x, 19, hem + 2, goldDark);
if (x > 20 && x < 37) {
set(x, 19, hem + 3, gold);
}
}
for (let z = 16; z <= 33; z++) {
set(21, 19, z, z % 4 === 0 ? goldLight : goldDark);
set(36, 19, z, z % 4 === 0 ? goldLight : goldDark);
}
for (let x = 22; x <= 35; x++) set(x, 19, 33, goldDark);
// Broad gold crown: a solid band, three points, and a blue jewel.
box(23, 19, 21, 35, 19, 23, goldDark);
box(24, 18, 22, 34, 18, 23, gold);
box(24, 18, 24, 34, 18, 25, gold);
line(24, 18, 25, 24, 18, 28, 0, gold);
line(24, 18, 25, 28, 18, 25, 0, gold);
line(29, 18, 25, 29, 18, 30, 0, goldLight);
line(30, 18, 25, 34, 18, 25, 0, gold);
line(34, 18, 25, 34, 18, 28, 0, gold);
for (const x of [24, 29, 34]) {
set(x, 18, x === 29 ? 30 : 28, goldLight);
set(x, 18, 25, goldLight);
}
for (const x of [25, 27, 31, 33]) set(x, 17, 22, goldLight);
set(29, 17, 23, blueLight);
set(29, 17, 24, blueDark);
set(28, 17, 23, blue);
set(30, 17, 23, blue);
// A small embroidered flourish beneath the crown.
line(26, 19, 18, 29, 19, 16, 0, goldDark);
line(29, 19, 16, 32, 19, 18, 0, goldDark);
set(29, 18, 17, goldLight);
// Cloth loops fold over the crossbar.
for (const x of [20, 26, 32, 38]) {
box(x, 20, 35, x + 1, 22, 38, blueDark);
box(x, 21, 38, x + 1, 24, 38, blue);
box(x, 24, 36, x + 1, 24, 38, blueDark);
set(x, 19, 36, gold);
set(x, 21, 39, goldLight);
}
animate("banner cloth", {
type: "swing",
axis: "y",
speed: 2,
amplitude: 0.25
});import { draw } from "./assets/voxel";
import { estandarte } from "./assets/estandarte";
// En cada cuadro: parado sobre (x, y), el centro de su base.
draw(ctx, estandarte, 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 estandarte
# Con las herramientas de Fogón (conector)
add_assets({ slug: "<tu-juego>", ids: ["estandarte"] })
# Queda en client/assets/estandarte.ts
# https://fogon.page/object/estandarte