← MedievalObjeto 3Dfogon/dragon-medieval
Dragón
Arrastrá para girarlo// «Dragón» · gpt-6-sol (medium)
// A chunky cute European dragon in 3/4 view, body oriented left-to-right: a compact bulky green scaled body on four short thick legs with pale claws, a pale yellow belly with horizontal stripes, a short thick neck forward to a big rounded head with two backward cream horns, yellow eyes, nostrils and an open jaw with white teeth, a row of small triangular spikes down the back and a thick tail curling behind ending in a spade tip. Two bat wings at the shoulders, folded half-open and angled up and outward to the sides: each wing is a solid triangular membrane in lighter green with 3 dark green finger bones radiating from the shoulder joint, about as long as the body, not taller than the head by much. Solid, clean silhouette, no thin scattered spikes.
const green = "#4d8f46";
const light = "#67a858";
const dark = "#326d3b";
const deep = "#285c37";
const belly = "#f2d88e";
const stripe = "#d7b96d";
const cream = "#f5e5b7";
// Four sturdy legs and broad, forward-pointing paws.
for (const x of [17, 29]) {
for (const y of [17, 29]) {
const near = y === 17;
ellipsoid(x, y, 11, 4, 4, 6, near ? green : dark);
box(x - 3, y - 3, 3, x + 2, y + 2, 10, near ? green : dark);
ellipsoid(x + 1, y - 1, 3, 4, 3, 3, near ? light : green);
for (const dy of [-2, 0, 2]) {
box(x + 4, y + dy - 1, 0, x + 5, y + dy, 2, cream);
set(x + 6, y + dy, 0, "#fff1ce");
}
}
}
// Compact, rounded body.
ellipsoid(23, 24, 19, 12, 9, 10, dark);
ellipsoid(23, 23, 20, 12, 8, 9, green);
forEach((x, y, z, color) => {
if (color === green && x >= 11 && x <= 35 && z >= 23 && rand() < 0.28)
set(x, y, z, light);
});
// The belly is on the visible, front-facing side.
ellipsoid(27, 17, 16, 8, 3, 9, belly);
ellipsoid(32, 18, 22, 4, 3, 7, belly);
forEach((x, y, z, color) => {
if (color === belly && y <= 19 && z >= 10 && z <= 25 && z % 4 === 1)
set(x, y, z, stripe);
});
// Short thick neck rising into the oversized head.
ellipsoid(31, 22, 24, 6, 6, 7, green);
ellipsoid(36, 21, 29, 6, 6, 6, dark);
ellipsoid(36, 20, 30, 6, 6, 6, green);
ellipsoid(40, 19, 27, 5, 4, 4, light);
ellipsoid(41, 19, 27, 4, 4, 3, green);
// Open mouth: a dark, recessed gap between chunky jaws.
box(39, 16, 22, 44, 22, 24, "#392e31");
box(40, 17, 22, 44, 21, 22, "#a75255");
ellipsoid(41, 19, 20, 5, 4, 2, green);
box(39, 16, 20, 44, 22, 21, light);
for (const y of [17, 20, 22]) {
box(42, y, 23, 43, y, 24, "#fff3d6");
set(41, y, 22, cream);
}
set(44, 18, 23, cream);
// Bright eyes, heavy brows and two nostrils.
box(34, 14, 30, 36, 14, 32, "#f4cf62");
box(35, 13, 30, 36, 13, 31, "#293b29");
box(39, 15, 30, 41, 15, 32, "#f4cf62");
box(40, 14, 30, 41, 14, 31, "#293b29");
line(33, 14, 33, 37, 14, 33, 1, dark);
line(38, 15, 33, 42, 16, 33, 1, dark);
box(43, 15, 27, 44, 15, 28, deep);
box(44, 20, 27, 44, 21, 28, deep);
set(43, 14, 29, light);
// Backward-sweeping cream horns.
line(34, 18, 34, 31, 17, 37, 2, stripe);
line(31, 17, 37, 28, 16, 39, 1, cream);
line(36, 24, 34, 33, 26, 37, 2, stripe);
line(33, 26, 37, 30, 27, 39, 1, cream);
// Rounded triangular plates follow the spine.
for (let x = 14; x <= 30; x += 3) {
const base = x < 18 ? 26 : x < 27 ? 29 : 28;
box(x, 23, base, x + 2, 25, base + 1, dark);
box(x + 1, 23, base + 2, x + 2, 24, base + 3, light);
set(x + 1, 23, base + 4, "#84b769");
}
// A few large, readable scale marks on the visible flank.
for (let x = 15; x <= 30; x += 4) {
for (let z = 16; z <= 24; z += 4) {
const y = x > 27 ? 15 : 16;
if (get(x, y, z) === green || get(x, y, z) === dark) {
set(x, y - 1, z, light);
set(x + 1, y - 1, z, light);
}
}
}
// Thick tail curls behind the body, with a broad spade at its end.
part("tail", [14, 27, 19]);
const tail = [
[15, 27, 19, 5], [12, 29, 17, 4], [9, 32, 15, 3],
[7, 35, 15, 3], [7, 37, 17, 2]
];
for (let i = 0; i < tail.length - 1; i++) {
const a = tail[i], b = tail[i + 1];
line(a[0], a[1], a[2], b[0], b[1], b[2], Math.min(a[3], b[3]), dark);
sphere(b[0], b[1], b[2], b[3], green);
}
ellipsoid(7, 39, 18, 4, 4, 3, dark);
ellipsoid(7, 40, 19, 3, 3, 3, green);
set(7, 43, 19, light);
animate("tail", { type: "swing", axis: "z", speed: 2, amplitude: 0.3 });
// Fill a thick triangular wing panel using barycentric samples.
function panel(a, b, c, color, side) {
const n = 52;
for (let i = 0; i <= n; i++) {
for (let j = 0; j <= n - i; j++) {
const u = i / n, v = j / n, w = 1 - u - v;
const x = Math.round(a[0] * w + b[0] * u + c[0] * v);
const y = Math.round(a[1] * w + b[1] * u + c[1] * v);
const z = Math.round(a[2] * w + b[2] * u + c[2] * v);
set(x, y, z, color);
set(x, y + side, z, color);
}
}
}
function wing(name, front) {
const side = front ? -1 : 1;
const shoulder = [25, front ? 16 : 32, 27];
part(name, shoulder);
const tips = [
[16, shoulder[1] + side * 13, 37],
[20, shoulder[1] + side * 17, 34],
[31, shoulder[1] + side * 14, 30]
];
panel(shoulder, tips[0], tips[1], front ? "#80b96c" : "#669f58", side);
panel(shoulder, tips[1], tips[2], front ? "#70ad5e" : "#598e51", side);
sphere(...shoulder, 2, dark);
for (const tip of tips) {
line(...shoulder, ...tip, 1, dark);
sphere(...tip, 1, dark);
}
line(...tips[0], ...tips[1], 0, dark);
line(...tips[1], ...tips[2], 0, dark);
animate(name, {
type: "swing", axis: "y", speed: front ? 3 : -3, amplitude: 0.4
});
}
wing("far wing", false);
wing("near wing", true);
part("body", [24, 24, 20]);import { draw } from "./assets/voxel";
import { dragonMedieval } from "./assets/dragon-medieval";
// En cada cuadro: parado sobre (x, y), el centro de su base.
draw(ctx, dragonMedieval, 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 dragon-medieval
# Con las herramientas de Fogón (conector)
add_assets({ slug: "<tu-juego>", ids: ["dragon-medieval"] })
# Queda en client/assets/dragon-medieval.ts
# https://fogon.page/object/dragon-medieval