← CiudadObjeto 3Dfogon/estacion-de-servicio
Estación de servicio
Arrastrá para girarlo// «Estación de servicio» · gpt-6-sol (medium)
// A gas station: a wide flat canopy roof with a blue and white stripe on four columns covering two fuel pumps on a concrete island, and behind it (+y) a small convenience shop with a glass front. A tall sign on a pole at one corner shows prices. Clean and open in front (-y).
// Asphalt lot and pale concrete forecourt
box(2, 2, 0, 45, 45, 0, "#535b60");
for (let x = 2; x <= 45; x++)
for (let y = 2; y <= 45; y++) {
const n = rand();
if (n < 0.11) set(x, y, 0, "#5d656a");
else if (n < 0.17) set(x, y, 0, "#4a5358");
}
box(4, 4, 1, 38, 28, 1, "#c9c8bd");
box(5, 5, 1, 37, 27, 1, "#deddd1");
for (let y = 7; y <= 25; y += 6)
line(5, y, 1, 37, y, 1, 0, "#c8c9be");
// Convenience shop, behind the pumps
box(9, 30, 1, 39, 44, 21, "#bd654d");
box(10, 30, 2, 38, 30, 15, "#d27a60");
for (let z = 3; z <= 20; z += 4)
line(9, 30, z, 39, 30, z, 0, "#ac5746");
for (let x = 11; x <= 38; x += 5)
for (let z = 5; z <= 19; z += 4)
if (rand() > 0.45) set(x, 30, z, "#e18b6d");
// Dark framed storefront and broad reflective panes
box(11, 29, 3, 37, 29, 14, "#263e43");
box(12, 28, 4, 20, 28, 13, "#68aeb8");
box(27, 28, 4, 36, 28, 13, "#68aeb8");
box(22, 28, 3, 25, 28, 13, "#438d9d");
box(21, 28, 3, 21, 28, 14, "#253d43");
box(26, 28, 3, 26, 28, 14, "#253d43");
for (const x of [12, 17, 20, 22, 25, 27, 32, 36])
line(x, 27, 5, x, 27, 12, 0, "#9ed3d2");
line(12, 27, 9, 20, 27, 9, 0, "#b8ded8");
line(27, 27, 9, 36, 27, 9, 0, "#b8ded8");
set(24, 27, 7, "#efd587");
box(10, 28, 2, 38, 29, 2, "#e9dfc6");
box(8, 29, 21, 40, 44, 23, "#e9e5d7");
box(8, 29, 23, 40, 44, 23, "#faf4e5");
box(9, 28, 16, 39, 28, 21, "#176b96");
box(10, 27, 16, 38, 27, 16, "#f5f4e8");
box(10, 27, 21, 38, 27, 21, "#f5f4e8");
// Small pixel lettering on the shop fascia
const glyph = {
M: ["10101", "11111", "10101", "10101", "10101"],
A: ["01110", "10001", "11111", "10001", "10001"],
R: ["11110", "10001", "11110", "10100", "10010"],
T: ["11111", "00100", "00100", "00100", "00100"]
};
function word(text, x0, y, z0, color) {
for (let i = 0; i < text.length; i++) {
const rows = glyph[text[i]];
for (let row = 0; row < 5; row++)
for (let col = 0; col < 5; col++)
if (rows[row][col] === "1")
set(x0 + i * 6 + col, y, z0 + 4 - row, color);
}
}
word("MART", 12, 26, 16, "#fff4d4");
for (const x of [11, 37]) {
set(x, 26, 18, "#f2c963");
set(x, 26, 19, "#f2c963");
}
// Raised fuel island with rounded-looking contrasting edges
box(12, 11, 2, 33, 23, 2, "#9fa6a1");
box(13, 12, 3, 32, 22, 3, "#e4e3d8");
line(12, 11, 2, 33, 11, 2, 0, "#f8f2d9");
for (const x of [12, 33]) {
box(x, 12, 3, x, 22, 3, "#f2d37b");
}
// Two chunky blue-and-white dispensers, facing the open forecourt
for (const px of [16, 28]) {
box(px - 2, 14, 4, px + 2, 19, 5, "#36515b");
box(px - 2, 14, 6, px + 2, 18, 12, "#f1f0e7");
box(px - 2, 13, 11, px + 2, 19, 13, "#176d9b");
box(px - 2, 13, 13, px + 2, 19, 13, "#3699be");
box(px - 1, 13, 8, px + 1, 13, 10, "#263f49");
box(px - 1, 12, 9, px + 1, 12, 10, "#8ccbd0");
set(px, 11, 10, "#e7f1dc");
for (const dx of [-1, 0, 1]) set(px + dx, 12, 7, "#e6c863");
box(px - 2, 13, 4, px + 2, 13, 5, "#296d91");
// Green hoses and their nozzles on either side
for (const s of [-1, 1]) {
const hx = px + s * 3;
line(px + s * 2, 17, 10, hx, 17, 8, 0, "#193f39");
line(hx, 17, 8, hx, 17, 5, 0, "#193f39");
box(hx, 16, 6, hx, 16, 8, "#254f40");
set(hx, 15, 6, "#e9bb50");
}
}
// Four sturdy canopy supports, with darker bases
for (const x of [7, 35])
for (const y of [7, 25]) {
box(x - 1, y - 1, 2, x + 1, y + 1, 4, "#8d9793");
box(x - 1, y - 1, 5, x + 1, y + 1, 24, "#efeee5");
line(x - 1, y - 1, 6, x - 1, y - 1, 23, 0, "#c7d4d4");
box(x - 1, y - 1, 22, x + 1, y + 1, 24, "#267ca3");
}
// Wide, thin floating canopy; its blue/white fascia reads from all sides
box(4, 4, 24, 38, 28, 25, "#e2e5df");
box(4, 4, 26, 38, 28, 27, "#15658e");
box(4, 4, 28, 38, 28, 28, "#f9f9ed");
box(5, 5, 29, 37, 27, 29, "#d6e0dc");
line(4, 3, 25, 38, 3, 25, 0, "#b9d3d9");
line(4, 3, 27, 38, 3, 27, 0, "#4ca9c6");
line(4, 4, 28, 38, 4, 28, 0, "#ffffff");
line(4, 28, 27, 38, 28, 27, 0, "#4ca9c6");
// Warm fileteado-like pinstripes and little diamond ornaments
line(12, 3, 26, 30, 3, 26, 0, "#efc65e");
for (const x of [9, 33]) {
set(x, 3, 26, "#e85d51");
set(x - 1, 3, 27, "#efc65e");
set(x + 1, 3, 27, "#efc65e");
}
// Tall roadside price sign on the front-right corner
box(42, 6, 1, 43, 7, 21, "#344f52");
line(42, 5, 2, 42, 5, 20, 0, "#74958e");
box(38, 5, 19, 46, 8, 35, "#175e85");
box(38, 4, 20, 46, 4, 34, "#233f4b");
box(38, 3, 30, 46, 3, 34, "#1976a0");
box(38, 3, 35, 46, 8, 35, "#f5f3e6");
box(39, 2, 31, 45, 2, 33, "#f6f1de");
line(39, 2, 30, 45, 2, 30, 0, "#edc75b");
const digits = {
"1": ["010", "110", "010", "010", "111"],
"5": ["111", "100", "111", "001", "111"],
"9": ["111", "101", "111", "001", "111"],
"7": ["111", "001", "010", "010", "010"],
"2": ["111", "001", "111", "100", "111"]
};
function price(text, x0, z0) {
for (let i = 0; i < text.length; i++)
for (let row = 0; row < 5; row++)
for (let col = 0; col < 3; col++)
if (digits[text[i]][row][col] === "1")
set(x0 + i * 3 + col, 2, z0 + 4 - row, "#f5df8e");
}
price("159", 39, 24);
price("172", 39, 18);
line(39, 2, 23, 45, 2, 23, 0, "#41899b");
// Open approach: lane ticks, curb and compact planters
for (const x of [12, 32]) {
box(x, 3, 1, x + 1, 6, 1, "#f4e4a9");
box(x, 8, 1, x + 1, 9, 1, "#f4e4a9");
}
for (const x of [6, 40]) {
box(x - 1, 37, 1, x + 1, 41, 2, "#d3cfbb");
box(x, 38, 3, x, 40, 5, "#315c43");
set(x - 1, 39, 4, "#427b50");
set(x + 1, 39, 4, "#528957");
}import { draw } from "./assets/voxel";
import { estacionDeServicio } from "./assets/estacion-de-servicio";
// En cada cuadro: parado sobre (x, y), el centro de su base.
draw(ctx, estacionDeServicio, 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 estacion-de-servicio
# Con las herramientas de Fogón (conector)
add_assets({ slug: "<tu-juego>", ids: ["estacion-de-servicio"] })
# Queda en client/assets/estacion-de-servicio.ts
# https://fogon.page/object/estacion-de-servicio