← Fantasy3D assetfogon/corona-magica
Corona mágica
Drag to turn it// «Corona mágica» · gpt-6-sol (medium)
// A royal magic crown resting on a small red velvet cushion: a gold band with tall points, each tipped with a pearl, a big glowing violet gem in the front (-y) and smaller blue and red gems around.
// A plump velvet cushion beneath a pearl-tipped royal crown.
const cx = 24, cy = 24;
// Rounded, layered cushion.
const cushionLayers = [
[16, 14, "#761b35"],
[18, 16, "#921d40"],
[19, 17, "#a5274c"],
[19, 17, "#b52b53"],
[19, 17, "#bf315a"],
[18, 17, "#ca3962"],
[18, 16, "#d24169"],
[17, 15, "#d94a71"],
[15, 13, "#df5578"]
];
for (let z = 0; z < cushionLayers.length; z++) {
const [rx, ry, base] = cushionLayers[z];
for (let x = cx - rx; x <= cx + rx; x++) {
for (let y = cy - ry; y <= cy + ry; y++) {
if (((x - cx) / rx) ** 2 + ((y - cy) / ry) ** 2 <= 1) {
const shade = rand() < 0.055
? (z < 4 ? "#a6294d" : "#ed6385")
: base;
set(x, y, z, shade);
}
}
}
}
// Warm piping around the cushion's widest seam.
for (let x = 5; x <= 43; x++) {
for (let y = 7; y <= 41; y++) {
const d = ((x - cx) / 19) ** 2 + ((y - cy) / 17) ** 2;
if (d > 0.88 && d <= 1.02) {
set(x, y, 2, rand() < 0.18 ? "#ffe09a" : "#d59642");
}
}
}
// Little corner tassels at the front.
for (const x of [10, 38]) {
sphere(x, 11, 4, 2, "#edb85e");
set(x, 9, 4, "#fff0ab");
for (let i = -1; i <= 1; i++) {
line(x + i, 10, 2, x + i, 10, 0, 0, i === 0 ? "#f6cb72" : "#bf7737");
}
}
// The thick, open gold band. Its center remains hollow.
for (let z = 9; z <= 19; z++) {
for (let x = 8; x <= 40; x++) {
for (let y = 11; y <= 37; y++) {
const dx = x - cx, dy = y - cy;
const outer = (dx / 15.5) ** 2 + (dy / 12.5) ** 2;
const inner = (dx / 11.7) ** 2 + (dy / 8.7) ** 2;
if (outer <= 1 && inner >= 1) {
let gold = y < 22 ? "#e9ac3e" : "#b97d2f";
if (z >= 17) gold = y < 22 ? "#ffcc62" : "#d99c43";
if (z <= 11) gold = "#ad7029";
if (rand() < 0.045) gold = "#ffe08a";
set(x, y, z, gold);
}
}
}
}
// Bold raised rims, following both edges of the band.
for (let z of [10, 19]) {
for (let x = 8; x <= 40; x++) {
for (let y = 11; y <= 37; y++) {
const dx = x - cx, dy = y - cy;
const d = (dx / 15.5) ** 2 + (dy / 12.5) ** 2;
if (d > 0.77 && d <= 1) {
set(x, y, z, z === 19 ? "#ffe084" : "#df9b3e");
}
}
}
}
// Nine broad, tapering points, including three rising at the back.
const points = [
[14, 32, 32], [24, 36, 34], [34, 32, 32],
[11, 18, 33], [17, 14, 35], [24, 12, 37],
[31, 14, 35], [37, 18, 33]
];
for (const [px, py, tip] of points) {
for (let z = 18; z <= tip; z++) {
const t = (z - 18) / (tip - 18);
const halfWidth = Math.max(0, Math.round(4 * (1 - t)));
const halfDepth = t < 0.65 ? 2 : 1;
for (let x = px - halfWidth; x <= px + halfWidth; x++) {
for (let y = py - halfDepth; y <= py + halfDepth; y++) {
const c = y < py ? "#f5bf52" : "#bf8130";
set(x, y, z, x === px && y === py - halfDepth ? "#ffe28a" : c);
}
}
}
// Rounded ivory pearl and a tiny gleam.
sphere(px, py, tip + 2, 1.7, "#e9dce8");
set(px - 1, py - 1, tip + 3, "#ffffff");
}
// Small settings and alternating jewels along the visible front.
for (const [x, y, gem] of [
[13, 16, "#e84965"], [18, 13, "#35d9e6"],
[30, 13, "#e84965"], [35, 16, "#35d9e6"]
]) {
box(x - 2, y - 2, 13, x + 2, y, 18, "#a66a2b");
box(x - 2, y - 2, 17, x + 2, y - 2, 18, "#ffdc75");
sphere(x, y - 2, 16, 2, gem);
set(x - 1, y - 3, 17, "#dfffff");
set(x, y - 3, 14, "#763b70");
}
// Beaded gold details between the larger settings.
for (const [x, y] of [[10, 20], [20, 12], [28, 12], [38, 20]]) {
sphere(x, y - 1, 15, 1, "#ffe294");
}
// An oversized scalloped bezel for the magic stone.
for (let z = 13; z <= 25; z++) {
const half = Math.max(0, 5 - Math.floor(Math.abs(z - 19) * 0.68));
for (let x = cx - half; x <= cx + half; x++) {
for (let y = 8; y <= 11; y++) {
set(x, y, z, y === 8 ? "#ffe28a" : "#bd792c");
}
}
}
for (const x of [19, 29]) {
sphere(x, 8, 19, 1, "#fff0ad");
}
// Only the front jewel moves: a pulsing violet-and-magenta enchantment.
part("frontGem", [24, 8, 19]);
const gemWidths = [0, 2, 3, 4, 4, 4, 3, 2, 0];
for (let i = 0; i < gemWidths.length; i++) {
const z = 15 + i;
const w = gemWidths[i];
for (let x = 24 - w; x <= 24 + w; x++) {
set(x, 7, z, Math.abs(x - 24) >= w ? "#a538db" : "#7422bd");
if (Math.abs(x - 24) <= Math.max(0, w - 1)) {
set(x, 6, z, x < 24 && z >= 19 ? "#e98cff" : "#b843f5");
}
}
}
set(22, 5, 21, "#fff0ff");
set(23, 5, 22, "#ffe4ff");
animate("frontGem", {
type: "colors",
palette: ["#9238ed", "#ed56e9", "#ffffff"],
pattern: "pulse",
glow: 0.8
});import { draw } from "./assets/voxel";
import { coronaMagica } from "./assets/corona-magica";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, coronaMagica, 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 corona-magica
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["corona-magica"] })
# It lands in client/assets/corona-magica.ts
# https://fogon.page/object/corona-magica