← Fantasy3D assetfogon/esqueleto
Esqueleto
Drag to turn it// «Esqueleto» · gpt-6-sol (medium)
// A cartoon skeleton warrior standing: a big skull with dark eye sockets and a toothy grin, visible ribcage, spine and pelvis, thin bone arms and legs with knobby joints, all in bone white with light grey shading. It wears a rusty dented helmet and holds a small round wooden shield in one hand and a short rusty sword in the other.
const bone = "#e8e2cf";
const boneLight = "#f7f0dc";
const boneShade = "#b9b8af";
const boneDark = "#92938d";
const socket = "#292632";
const rust = "#92583f";
const rustLight = "#bd7950";
const rustDark = "#603e36";
const wood = "#76503b";
const woodLight = "#a47550";
const brass = "#b89859";
function joint(x, y, z, r = 2) {
sphere(x, y, z, r, boneShade);
sphere(x, y - 1, z + 1, Math.max(1, r - 1), boneLight);
}
// Feet, shinbones, and knobby knees.
for (const x of [20, 28]) {
ellipsoid(x, 22, 1, 2.6, 4.2, 1.5, boneShade);
ellipsoid(x, 20, 2, 2.2, 2.4, 1.2, boneLight);
joint(x, 24, 4);
line(x, 24, 5, x + (x < 24 ? -1 : 1), 25, 10, 1, bone);
line(x - 1, 23, 5, x + (x < 24 ? -2 : 0), 24, 10, 0, boneLight);
joint(x + (x < 24 ? -1 : 1), 25, 11, 2);
line(x + (x < 24 ? -1 : 1), 25, 12, x, 25, 17, 1, bone);
line(x + (x < 24 ? -2 : 0), 24, 13, x - 1, 24, 16, 0, boneLight);
}
// Pelvis: broad, rounded hip bones with a visible dark opening.
ellipsoid(24, 25, 19, 6, 3, 2.6, boneShade);
ellipsoid(24, 23, 19, 3, 2, 1.7, socket);
for (const x of [19, 29]) {
ellipsoid(x, 24, 19, 3, 3, 2.5, bone);
joint(x + (x < 24 ? 1 : -1), 25, 17, 2);
}
line(20, 22, 18, 28, 22, 18, 1, boneLight);
// Spine and separated, curved ribs.
line(24, 26, 20, 24, 26, 32, 1, boneShade);
for (let z = 21; z <= 31; z += 2) {
box(23, 24, z, 25, 26, z, boneLight);
}
for (const side of [-1, 1]) {
for (const level of [24, 27, 30]) {
line(24, 25, level + 1, 21 + side * 3, 25, level + 2, 1, boneShade);
line(21 + side * 3, 25, level + 2, 24 + side * 8, 23, level + 1, 1, bone);
line(24 + side * 8, 23, level + 1, 24 + side * 7, 20, level, 1, bone);
line(24 + side * 7, 20, level, 24 + side * 3, 19, level - 1, 0, boneLight);
}
line(24, 24, 32, 24 + side * 8, 23, 30, 1, boneLight);
}
ellipsoid(24, 23, 31, 2, 2, 2, boneShade);
line(24, 24, 31, 24, 24, 34, 1, bone);
// Left arm and its small, round wooden shield.
joint(16, 25, 30, 2);
line(16, 25, 29, 12, 23, 25, 1, bone);
joint(12, 23, 25);
line(12, 23, 24, 12, 19, 21, 1, boneLight);
joint(12, 19, 21, 2);
// Shield is held forward, so its painted face remains clearly visible.
for (let x = 6; x <= 17; x++) {
for (let z = 18; z <= 29; z++) {
const d = Math.hypot((x - 11.5) / 5.5, (z - 23.5) / 5.5);
if (d <= 1) {
set(x, 17, z, d > 0.79 ? brass : ((x + z) % 4 === 0 ? woodLight : wood));
if (d < 0.77) set(x, 16, z, (x % 3 === 0) ? woodLight : wood);
}
}
}
line(9, 16, 20, 9, 16, 27, 0, "#b9875c");
line(14, 16, 20, 14, 16, 27, 0, "#583d32");
ellipsoid(11.5, 15, 23.5, 2, 1, 2, brass);
set(11, 14, 24, "#e3c483");
for (const [x, z] of [[11, 19], [7, 23], [16, 24], [11, 28]]) {
set(x, 15, z, "#e0bf7b");
}
// Sword arm: everything after this joint swings together.
part("swordArm", [32, 25, 30]);
joint(32, 25, 30, 2);
line(33, 25, 29, 36, 22, 25, 1, bone);
joint(36, 22, 25);
line(36, 22, 24, 37, 18, 21, 1, boneLight);
joint(37, 18, 21, 2);
// Leather-wrapped grip, brass guard, and short, nicked rusty blade.
line(37, 17, 20, 39, 17, 25, 1, "#493c37");
for (let z = 21; z <= 24; z += 2) set(39, 16, z, brass);
line(35, 17, 25, 42, 17, 25, 1, rustDark);
set(35, 16, 25, brass);
set(42, 16, 25, brass);
for (let z = 26; z <= 34; z++) {
const x = 39 + Math.round((z - 26) * 0.35);
set(x, 17, z, rustDark);
set(x, 16, z, z === 29 || z === 32 ? rustDark : rust);
if (z < 33 && z !== 30) set(x + 1, 16, z, rustLight);
}
set(42, 16, 35, "#c18a5e");
animate("swordArm", { type: "swing", axis: "x", speed: 3, amplitude: 0.5 });
part("body");
// Big cartoon skull pivots at the neck.
part("skull", [24, 24, 34]);
ellipsoid(24, 24, 39, 8, 7, 6.5, boneShade);
ellipsoid(24, 23, 40, 7.6, 6.5, 5.8, bone);
ellipsoid(24, 21, 34.5, 6, 4.2, 2.6, boneShade);
ellipsoid(24, 19, 35, 5.6, 2.6, 1.7, boneLight);
// Huge, dark sockets and tiny magical glints.
for (const x of [20, 28]) {
ellipsoid(x, 17.5, 39, 2.4, 1.8, 2.7, socket);
set(x - 1, 15, 39, "#8669b4");
set(x, 15, 39, "#c184e3");
line(x - 2, 17, 42, x + 2, 17, 42, 0, boneLight);
}
ellipsoid(24, 16, 36.5, 1.4, 1, 1, boneDark);
// Broad grin: dark gap, individually readable teeth, and a chunky chin.
box(20, 16, 33, 28, 17, 34, socket);
for (const x of [20, 22, 24, 26, 28]) {
set(x, 15, 34, boneLight);
set(x, 16, 33, boneLight);
}
line(19, 17, 32, 29, 17, 32, 1, bone);
set(18, 17, 34, boneLight);
set(30, 17, 34, boneLight);
// A dented, rusty helmet, kept above the expressive eyes.
for (let x = 15; x <= 33; x++) {
for (let y = 16; y <= 32; y++) {
for (let z = 42; z <= 46; z++) {
const d = ((x - 24) / 9) ** 2 + ((y - 24) / 8) ** 2 +
((z - 42.5) / 4.5) ** 2;
if (d <= 1 && (z >= 43 || y >= 20)) {
set(x, y, z, rand() < 0.13 ? rustLight : rust);
}
}
}
}
// Turned-up brim, raised brow ridge, and a few visible dents.
for (let x = 16; x <= 32; x++) {
const edge = Math.abs(x - 24);
const y = 16 + Math.round(edge * 0.14);
box(x, y, 42, x, y + 1, 43, edge > 6 ? rustDark : rustLight);
}
line(17, 19, 43, 19, 19, 44, 0, rustDark);
line(29, 18, 44, 31, 19, 43, 0, rustDark);
set(25, 17, 45, rustDark);
set(26, 17, 44, rustDark);
set(21, 17, 43, brass);
set(27, 17, 43, brass);
animate("skull", { type: "swing", axis: "z", speed: 1.6, amplitude: 0.25 });
part("body");import { draw } from "./assets/voxel";
import { esqueleto } from "./assets/esqueleto";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, esqueleto, x, y, { size: 64, angle: 0, t: performance.now() / 1000 });
// size: its longest side, in px
// angle: turn on the floor, in radians
// t: seconds; if it moves, that animates it# In a terminal, in the game's folder
fogon assets add esqueleto
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["esqueleto"] })
# It lands in client/assets/esqueleto.ts
# https://fogon.page/object/esqueleto