← FantasíaObjeto 3Dfogon/libro-de-hechizos
Libro de hechizos
Arrastrá para girarlo// «Libro de hechizos» · gpt-6-sol (medium)
// A big thick spellbook lying open on a small wooden lectern with a slanted top: dark purple leather cover with gold corner guards and a gold clasp, cream pages with tiny dark rune lines. Above the open pages floats a glowing magenta-and-gold rune symbol and a few sparkles.
const wood = "#493329", woodLight = "#73503a", woodDark = "#302525";
const leather = "#352044", leatherLight = "#583469", leatherDark = "#25172f";
const gold = "#e7b851", goldLight = "#ffe18a", goldDark = "#a87735";
const cream = "#f6e9bf", pageShade = "#dfcda0", ink = "#62516d";
const deskZ = y => 17 + Math.floor((y - 11) * 0.27);
const bookZ = y => deskZ(y) + 2;
// Broad, sturdy feet and a tapered wooden pedestal.
box(13, 17, 0, 35, 33, 2, woodDark);
box(15, 18, 2, 33, 32, 3, wood);
box(17, 17, 1, 19, 33, 2, woodLight);
box(29, 17, 1, 31, 33, 2, woodLight);
box(21, 21, 4, 27, 28, 15, wood);
box(22, 20, 5, 23, 21, 14, woodLight);
box(25, 20, 5, 26, 21, 14, woodLight);
box(19, 19, 14, 29, 31, 16, woodDark);
box(20, 20, 15, 28, 30, 17, woodLight);
line(20, 19, 8, 12, 15, 18, 1, wood);
line(28, 19, 8, 36, 15, 18, 1, wood);
line(21, 29, 9, 15, 34, 21, 1, wood);
line(27, 29, 9, 33, 34, 21, 1, wood);
// Slanted, thick reading board, with visible grain and brass pegs.
for (let y = 11; y <= 37; y++) {
const z = deskZ(y);
box(6, y, z - 2, 42, y, z, y % 5 === 0 ? woodLight : wood);
for (let x = 8; x <= 40; x++)
if (rand() < 0.10) set(x, y, z, rand() < 0.5 ? woodLight : woodDark);
set(6, y, z, woodDark);
set(42, y, z, woodDark);
}
for (let x = 6; x <= 42; x++) {
set(x, 11, deskZ(11) + 1, woodLight);
set(x, 37, deskZ(37) + 1, woodDark);
}
for (const x of [9, 39])
for (const y of [13, 35])
set(x, y, deskZ(y) + 1, goldDark);
// A little retaining lip at the low edge.
box(7, 11, 18, 41, 12, 19, woodDark);
box(9, 11, 19, 39, 11, 19, woodLight);
for (const x of [10, 38]) set(x, 11, 20, gold);
// Spine and the left half of the open book.
for (let y = 14; y <= 35; y++) {
const b = bookZ(y);
box(22, y, b, 26, y, b + 2, leatherDark);
box(23, y, b + 2, 25, y, b + 3, leatherLight);
box(8, y, b, 23, y, b + 1, leather);
set(8, y, b + 2, leatherLight);
set(9, y, b + 1, leatherLight);
}
for (let y = 16; y <= 33; y++) {
const b = bookZ(y);
for (let x = 10; x <= 22; x++) {
const top = b + 6 + (x <= 12 ? 1 : 0);
box(x, y, b + 2, x, y, top - 1,
y % 3 === 0 ? pageShade : cream);
set(x, y, top, cream);
if (x === 10) set(x, y, b + 3, pageShade);
}
}
for (let y = 17; y <= 32; y += 3) {
const z = bookZ(y) + 6;
for (let x = 14; x <= 20; x++)
if ((x + y) % 4 !== 0) set(x, y, z, ink);
set(12, y, z + 1, goldDark);
set(13, y + 1, bookZ(y + 1) + 6, ink);
}
for (const y of [14, 33]) {
const b = bookZ(y);
box(8, y, b + 1, 10, y + 2, b + 2, goldDark);
set(8, y, b + 3, goldLight);
set(9, y + 1, b + 3, gold);
}
for (let y = 18; y <= 31; y += 4)
set(8, y, bookZ(y) + 2, goldDark);
// The clasp buckles across the front edges.
box(20, 13, bookZ(14) + 1, 24, 14, bookZ(14) + 2, goldDark);
box(21, 13, bookZ(14) + 2, 24, 13, bookZ(14) + 3, gold);
set(23, 12, bookZ(14) + 3, goldLight);
// Stationary magical motes surrounding the sigil.
for (const [x, y, z, c] of [
[15, 22, 39, "#ff70df"], [33, 25, 39, "#ffe38b"],
[19, 28, 35, "#b46bff"], [30, 16, 35, "#ff84e4"],
[13, 25, 34, "#f8bdef"], [35, 23, 42, "#ffeaa0"]
]) {
set(x, y, z, c);
set(x - 1, y, z, "#773968");
set(x + 1, y, z, "#773968");
set(x, y, z - 1, "#773968");
set(x, y, z + 1, c);
}
// Right cover, pages, and their ink all swing together at the spine.
part("right cover and pages", [24, 24, 26]);
for (let y = 14; y <= 35; y++) {
const b = bookZ(y);
box(25, y, b, 40, y, b + 1, leather);
set(40, y, b + 2, leatherLight);
set(39, y, b + 1, leatherLight);
}
for (let y = 16; y <= 33; y++) {
const b = bookZ(y);
for (let x = 26; x <= 38; x++) {
const top = b + 6 + (x >= 36 ? 1 : 0);
box(x, y, b + 2, x, y, top - 1,
y % 3 === 0 ? pageShade : cream);
set(x, y, top, cream);
if (x === 38) set(x, y, b + 3, pageShade);
}
}
for (let y = 17; y <= 32; y += 3) {
const z = bookZ(y) + 6;
for (let x = 28; x <= 34; x++)
if ((x + y) % 5 !== 0) set(x, y, z, ink);
set(36, y, z + 1, goldDark);
set(35, y + 1, bookZ(y + 1) + 6, ink);
}
for (const y of [14, 33]) {
const b = bookZ(y);
box(38, y, b + 1, 40, y + 2, b + 2, goldDark);
set(40, y, b + 3, goldLight);
set(39, y + 1, b + 3, gold);
}
for (let y = 18; y <= 31; y += 4)
set(40, y, bookZ(y) + 2, goldDark);
box(24, 13, bookZ(14) + 1, 28, 14, bookZ(14) + 2, goldDark);
box(24, 13, bookZ(14) + 2, 27, 13, bookZ(14) + 3, gold);
set(25, 12, bookZ(14) + 3, goldLight);
animate("right cover and pages",
{ type: "swing", axis: "y", speed: 0.8, amplitude: 0.25 });
// A hovering, double-thick luminous rune, readable from the front.
part("floating rune", [24, 23, 40]);
const points = [
[24, 45], [27, 43], [29, 40], [27, 37],
[24, 35], [21, 37], [19, 40], [21, 43]
];
for (const y of [22, 23, 24])
for (let i = 0; i < points.length; i++) {
const a = points[i], b = points[(i + 1) % points.length];
line(a[0], y, a[1], b[0], y, b[1], 0,
i % 2 ? "#ff61ce" : "#e4a8ff");
}
line(24, 22, 36, 24, 22, 44, 0, goldLight);
line(20, 22, 40, 28, 22, 40, 0, gold);
line(22, 21, 38, 26, 21, 42, 0, "#ffdc75");
line(26, 21, 38, 22, 21, 42, 0, "#ff78d8");
set(24, 20, 40, "#fff2ad");
set(24, 21, 40, "#fff2ad");
set(24, 23, 40, "#fff2ad");
animate("floating rune", { type: "spin", axis: "z", speed: 1.5 });
animate("floating rune", {
type: "colors",
palette: ["#ff43c9", "#ffd269", "#ad65ff"],
pattern: "pulse",
glow: 0.9
});import { draw } from "./assets/voxel";
import { libroDeHechizos } from "./assets/libro-de-hechizos";
// En cada cuadro: parado sobre (x, y), el centro de su base.
draw(ctx, libroDeHechizos, 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 libro-de-hechizos
# Con las herramientas de Fogón (conector)
add_assets({ slug: "<tu-juego>", ids: ["libro-de-hechizos"] })
# Queda en client/assets/libro-de-hechizos.ts
# https://fogon.page/object/libro-de-hechizos