← EquipamientoObjeto 3Dfogon/escudo-de-caballero
Escudo de caballero
Arrastrá para girarlo// «Escudo de caballero» · gpt-6-sol (medium)
// A knight's heater shield standing upright facing -y: the classic pointed-bottom shield shape, deep royal blue with a gold border, a golden lion or cross emblem in the middle and a few rivets along the rim. It stands upright on the floor (z=0), facing front (-y), centered, chunky and readable.
const blue = ["#173a9e", "#1b45ad", "#2150bd", "#295bc7"];
const gold = ["#93601c", "#b98427", "#d9a83b", "#f2ca65"];
const brassDark = "#785321";
// Classic heater outline: broad shoulders taper to a pointed foot.
function halfWidth(z) {
if (z < 0 || z > 43) return -1;
if (z <= 5) return Math.floor(1 + z * 0.85);
if (z <= 15) return Math.floor(5 + (z - 5) * 0.8);
if (z <= 27) return Math.floor(13 + (z - 15) * 0.42);
if (z <= 40) return 18;
return 18 - (z - 40);
}
// Thick, solid shield with a blue front and gold-bound edges.
for (let z = 0; z <= 43; z++) {
const w = halfWidth(z);
for (let x = 24 - w; x <= 24 + w; x++) {
const edge = w - Math.abs(x - 24);
const rim = edge < 3 || z >= 40;
for (let y = 19; y <= 27; y++) {
let color;
if (y === 27) {
color = rim ? brassDark : "#68452c";
} else if (y >= 22) {
color = rim ? "#9b6c25" : "#283b71";
} else if (rim) {
color = y === 19
? (z >= 40 || x < 24 ? gold[3] : gold[2])
: gold[1];
if (edge === 0 && y > 19) color = gold[0];
} else {
color = blue[z >= 29 ? 2 : 1];
if (rand() < 0.075) color = blue[Math.floor(rand() * blue.length)];
}
set(x, y, z, color);
}
// Raised, narrow highlight just inside the gold binding.
if (edge === 3 && z < 39) set(x, 18, z, "#5376c9");
if (z === 39 && edge >= 3) set(x, 18, z, "#5376c9");
}
}
// Chunky raised heraldic cross, with flared arms and ends.
function crossWidth(z) {
if (z < 10 || z > 35) return -1;
if (z >= 21 && z <= 26) return z === 21 || z === 26 ? 9 : 11;
if (z <= 13 || z >= 32) return 4;
return 2;
}
for (let z = 10; z <= 35; z++) {
const w = crossWidth(z);
for (let x = 24 - w; x <= 24 + w; x++) {
set(x, 18, z, "#946019");
set(x, 17, z, x < 24 || z > 25 ? "#e9bc4d" : "#c48b2c");
if (x === 24 - w || z === 35) set(x, 16, z, "#f6d477");
}
}
// Sapphire cabochon at the heart of the cross.
box(22, 16, 22, 26, 16, 25, "#76521b");
box(23, 15, 22, 25, 15, 25, "#1355bd");
box(23, 14, 24, 14, 25, "#61b5f0");
// Brass rivets marching down both sides of the rim.
for (const z of [11, 19, 28, 36]) {
const w = halfWidth(z);
for (const side of [-1, 1]) {
const x = 24 + side * (w - 1);
box(x - 1, 18, z - 1, x + 1, 18, z + 1, "#9b691e");
set(x, 17, z, "#f7d881");
set(x - 1, 17, z + 1, "#e5b746");
}
}
for (const x of [13, 24, 35]) {
box(x - 1, 18, 41, x + 1, 18, 42, "#a87523");
set(x, 17, 42, "#ffe199");
}import { draw } from "./assets/voxel";
import { escudoDeCaballero } from "./assets/escudo-de-caballero";
// En cada cuadro: parado sobre (x, y), el centro de su base.
draw(ctx, escudoDeCaballero, 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 escudo-de-caballero
# Con las herramientas de Fogón (conector)
add_assets({ slug: "<tu-juego>", ids: ["escudo-de-caballero"] })
# Queda en client/assets/escudo-de-caballero.ts
# https://fogon.page/object/escudo-de-caballero