← Asian3D assetfogon/expendedora-japonesa
Expendedora japonesa
Drag to turn it// «Expendedora japonesa» · gpt-6-sol (medium)
// A bright Japanese drinks vending machine: a tall white and red box with a glowing display window full of rows of small colorful cans and bottles, small blue price lights under each, a coin slot panel and a dark pickup slot at the bottom.
const red = "#b8292b", redLight = "#df4440", redDark = "#831e26";
const gold = "#e9b84d", goldLight = "#ffe09a";
const white = "#f5f0e4", stone = "#d6d3ca";
const green = "#315d52", greenLight = "#4a7966", greenDark = "#24483f";
const blue = "#70d9f5";
// White stone footing and the solid vending-machine body.
box(9, 15, 0, 39, 33, 2, stone);
box(11, 16, 2, 37, 32, 40, white);
box(9, 15, 3, 11, 33, 40, red);
box(37, 15, 3, 39, 33, 40, red);
box(10, 15, 3, 38, 16, 4, redDark);
box(10, 15, 39, 38, 33, 40, red);
box(12, 15, 5, 12, 32, 38, gold);
box(36, 15, 5, 36, 32, 38, gold);
// Subtle lacquer and stone variation on the sides.
for (let z = 6; z < 38; z++) {
for (let y = 17; y < 32; y++) {
if (rand() < 0.075) {
set(9, y, z, rand() < 0.5 ? redLight : redDark);
set(39, y, z, rand() < 0.5 ? redLight : redDark);
}
}
}
// Recess behind the illuminated product display.
box(13, 14, 15, 30, 15, 36, "#233943");
box(14, 13, 16, 29, 13, 35, "#294b58");
// Only the lit display backing changes color; the drinks remain colorful.
part("display", [22, 14, 26]);
box(14, 12, 16, 29, 12, 35, "#e9f8fa");
animate("display", {
type: "colors",
palette: ["#ffffff", "#d9f5ff", "#fff3c6"],
pattern: "wave",
glow: 0.5
});
part("body", [24, 24, 0]);
// Deep red lacquered window surround and fine gold inner rim.
box(11, 11, 14, 12, 16, 37, redDark);
box(30, 11, 14, 31, 16, 37, redDark);
box(11, 11, 36, 31, 16, 37, red);
box(11, 11, 14, 31, 16, 15, red);
box(13, 10, 16, 13, 12, 35, gold);
box(30, 10, 16, 30, 12, 35, gold);
box(13, 10, 35, 30, 12, 35, gold);
box(13, 10, 15, 30, 12, 15, gold);
// Four shelves of miniature cans and bottles, with a blue price lamp
// immediately below every product.
const drinkColors = [
["#e34440", "#49a7d2", "#f3c14e", "#6ba960", "#e78aba"],
["#f0c955", "#d95d59", "#68b5ae", "#ec8b4c", "#7859a7"],
["#6caa65", "#ef858f", "#e9c24d", "#4b9fca", "#db5546"],
["#d85b46", "#9acb70", "#668bcc", "#e9a5bd", "#e7ae48"]
];
for (let row = 0; row < 4; row++) {
const bottom = 18 + row * 5;
box(14, 11, bottom - 2, 29, 12, bottom - 2, "#a7b9ad");
box(14, 10, bottom - 2, 29, 10, bottom - 2, gold);
for (let col = 0; col < 5; col++) {
const x = 15 + col * 3;
const c = drinkColors[row][col];
box(x, 10, bottom, x + 1, 11, bottom + 2, c);
box(x, 10, bottom + 2, x + 1, 11, bottom + 2, "#f8e9d6");
set(x, 9, bottom + 1, "#fff4cc");
set(x, 10, bottom - 1, blue);
set(x + 1, 10, bottom - 1, "#b9f5ff");
if ((row + col) % 3 === 0) {
set(x, 10, bottom + 3, "#e8e1cc"); // bottle neck
}
}
}
// Glass glints at the left edge of the display.
for (let z = 18; z < 35; z += 4) set(13, 9, z, "#d4f7fb");
// Right-hand payment panel.
box(32, 13, 14, 37, 15, 35, red);
box(33, 12, 16, 36, 12, 34, white);
box(33, 11, 28, 36, 11, 33, "#56736d");
box(34, 10, 31, 35, 10, 31, "#c4eff0");
box(34, 10, 29, 35, 10, 29, blue);
box(33, 10, 25, 36, 11, 26, gold);
box(34, 9, 26, 35, 9, 26, "#293b3d"); // coin slot
box(34, 10, 21, 35, 10, 22, "#384a53"); // card reader
set(35, 9, 22, "#70e5ba");
for (let z = 17; z <= 19; z += 2) {
set(34, 10, z, "#f5cd69");
set(36, 10, z, blue);
}
// Dark pickup opening, with a substantial red-and-gold surround.
box(13, 14, 4, 31, 16, 12, redDark);
box(15, 12, 6, 29, 13, 10, "#202c31");
box(16, 11, 6, 28, 11, 7, "#38474a");
box(14, 11, 5, 30, 12, 5, gold);
box(14, 11, 11, 30, 12, 11, gold);
box(14, 11, 6, 14, 12, 10, gold);
box(30, 11, 6, 30, 12, 10, gold);
box(17, 12, 8, 27, 12, 8, "#141e24");
// Header: a cherry blossom emblem and a compact gold sign.
box(13, 14, 37, 35, 15, 40, redLight);
box(14, 13, 38, 35, 13, 38, redDark);
for (const [dx, dz] of [[0, 1], [1, 0], [2, 1], [1, 2], [1, 1]]) {
set(18 + dx, 12, 38 + dz, "#f6a9bd");
}
set(19, 11, 39, "#fff1d9");
box(24, 12, 39, 33, 12, 39, goldLight);
for (const x of [24, 27, 30, 33]) set(x, 12, 38, gold);
// A little temple-style tiled canopy, including upturned eaves.
box(8, 13, 41, 40, 34, 41, gold);
box(7, 12, 42, 41, 35, 42, greenDark);
box(9, 14, 43, 39, 33, 43, green);
box(11, 17, 44, 37, 30, 44, greenLight);
for (let x = 9; x <= 39; x += 3) {
box(x, 12, 42, x, 35, 42, greenLight);
box(x, 15, 43, x, 33, 43, greenDark);
}
for (let x = 9; x <= 39; x += 6) {
set(x, 11, 42, gold);
set(x, 36, 42, gold);
}
for (const x of [7, 8, 40, 41]) {
box(x, 12, 43, x, 35, 44, green);
set(x, 12, 45, greenLight);
set(x, 35, 45, greenLight);
}import { draw } from "./assets/voxel";
import { expendedoraJaponesa } from "./assets/expendedora-japonesa";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, expendedoraJaponesa, 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 expendedora-japonesa
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["expendedora-japonesa"] })
# It lands in client/assets/expendedora-japonesa.ts
# https://fogon.page/object/expendedora-japonesa