← Level pieces 23D assetfogon/nivel-pocion-de-vida
Poción de vida
Drag to turn it// «Poción de vida» · gpt-6-sol (medium)
// A health potion: a round glass flask (sphere radius 12) with a short neck and a brown cork, filled 3/4 with glowing bright red liquid, the empty top part pale translucent-looking light blue glass, a white highlight on the left, a small white heart label on the front (-y).
const cx = 24, cy = 24, cz = 12, R = 12;
// The flask is solid at this scale, with its visible surface colored like glass.
sphere(cx, cy, cz, R, "#a8eafa");
part("liquido", [cx, cy, cz]);
for (let x = cx - R; x <= cx + R; x++) {
for (let y = cy - R; y <= cy + R; y++) {
for (let z = 0; z <= 18; z++) {
const d2 = (x - cx) ** 2 + (y - cy) ** 2 + (z - cz) ** 2;
if (d2 > R * R) continue;
let color = z < 5 ? "#d91c32" : "#ff3040";
if (z === 18) color = "#ff6070";
else if (y < 18 && z > 7 && rand() < 0.07) color = "#ff4859";
set(x, y, z, color);
}
}
}
animate("liquido", {
type: "colors",
palette: ["#ff3040", "#ff6070", "#d01020"],
pattern: "pulse",
glow: 0.5
});
part("body");
// Pale blue empty quarter and a crisp glass line above the liquid.
for (let x = 12; x <= 36; x++) {
for (let y = 12; y <= 36; y++) {
for (let z = 19; z <= 24; z++) {
const d2 = (x - cx) ** 2 + (y - cy) ** 2 + (z - cz) ** 2;
if (d2 > R * R) continue;
let color = z >= 22 ? "#c8f5ff" : "#a8eafa";
if (y < 22 && z === 19) color = "#e1faff";
set(x, y, z, color);
}
}
}
// Glass glints along the left rim, including over the red liquid.
for (let z = 5; z <= 21; z++) {
for (let x = 12; x <= 17; x++) {
const q = R * R - (x - cx) ** 2 - (z - cz) ** 2;
if (q < 0) continue;
const y = Math.round(cy - Math.sqrt(q));
if (x <= 14 || (x === 16 && z >= 10 && z <= 19)) {
set(x, y - 1, z, z > 17 ? "#f0fdff" : "#a5edfa");
}
}
}
for (let z = 8; z <= 19; z++) {
const x = 34;
const q = R * R - (x - cx) ** 2 - (z - cz) ** 2;
if (q >= 0) set(x, Math.round(cy - Math.sqrt(q)) - 1, z, "#8ad9ec");
}
// Short glass neck with a chunky lip.
cylinder(cx, cy, 23, 5, 7, "#a8eafa");
cylinder(cx, cy, 26, 6, 2, "#d9f8ff");
for (let z = 24; z <= 29; z++) {
set(20, 21, z, "#effcff");
set(21, 20, z, "#effcff");
}
// Warm brown cork, with a darker band and a light top.
cylinder(cx, cy, 29, 4, 7, "#ad6637");
cylinder(cx, cy, 29, 4, 1, "#754324");
cylinder(cx, cy, 35, 4, 1, "#d19052");
for (let z = 31; z <= 34; z++) {
set(21, 21, z, "#d19052");
set(22, 20, z, "#d19052");
}
// A little dark-red badge makes the white heart readable at small sizes.
function frontY(x, z) {
const q = R * R - (x - cx) ** 2 - (z - cz) ** 2;
return Math.round(cy - Math.sqrt(Math.max(0, q)));
}
for (let z = 9; z <= 20; z++) {
for (let x = 18; x <= 30; x++) {
const dx = (x - 24) / 6.5, dz = (z - 14.5) / 5.8;
if (dx * dx + dz * dz <= 1) {
set(x, frontY(x, z) - 1, z, "#a91730");
}
}
}
const heart = {
18: [[20, 22], [26, 28]],
17: [[19, 23], [25, 29]],
16: [[19, 29]],
15: [[20, 28]],
14: [[20, 28]],
13: [[21, 27]],
12: [[22, 26]],
11: [[23, 25]],
10: [[24, 24]]
};
for (const [height, spans] of Object.entries(heart)) {
const z = Number(height);
for (const [a, b] of spans) {
for (let x = a; x <= b; x++) {
set(x, frontY(x, z) - 2, z, z <= 11 ? "#d9f2f4" : "#ffffff");
}
}
}import { draw } from "./assets/voxel";
import { nivelPocionDeVida } from "./assets/nivel-pocion-de-vida";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, nivelPocionDeVida, 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 nivel-pocion-de-vida
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["nivel-pocion-de-vida"] })
# It lands in client/assets/nivel-pocion-de-vida.ts
# https://fogon.page/object/nivel-pocion-de-vida