← City3D assetfogon/taxi
Taxi
Drag to turn it// «Taxi» · gpt-6-sol (medium)
// A Buenos Aires taxi: a compact four-door sedan, longer along y, with a black lower body and a bright yellow roof, a small lit TAXI sign on the roof, dark windows, round headlights at the front (-y) and red taillights at the back, four black wheels with grey hubs.
// Compact Buenos Aires taxi: front faces -y.
const black = "#17191d";
const blackHi = "#24272c";
const blackLow = "#101216";
const yellow = "#ffd32c";
const yellowHi = "#ffe25a";
const yellowShade = "#e7ad18";
const glass = "#243c49";
const glassHi = "#426575";
// Chunky black sedan body, with slightly clipped corners.
box(11, 9, 5, 36, 39, 11, black);
box(13, 6, 5, 34, 42, 11, black);
box(15, 5, 6, 32, 43, 10, black);
box(12, 9, 10, 35, 39, 12, blackHi);
// Hood and trunk, kept black below the yellow cabin.
box(14, 6, 12, 33, 15, 12, blackHi);
box(14, 37, 12, 33, 42, 12, blackHi);
box(15, 7, 13, 32, 13, 13, black);
box(15, 39, 13, 32, 41, 13, black);
// Yellow upper doors and sturdy window frame.
box(11, 16, 11, 36, 37, 13, yellowShade);
box(12, 17, 13, 35, 36, 18, yellow);
box(13, 18, 18, 34, 35, 19, yellowHi);
box(14, 19, 20, 33, 34, 20, yellow);
box(15, 20, 21, 32, 33, 21, yellowHi);
// Sloped front and rear pillars.
for (let z = 14; z <= 18; z++) {
const inset = Math.max(0, z - 15);
box(14, 15 + inset, z, 33, 16 + inset, z, yellow);
box(14, 36 - inset, z, 33, 37 - inset, z, yellow);
}
// Windscreens.
box(16, 15, 15, 31, 15, 17, glass);
box(17, 16, 18, 30, 16, 18, glass);
box(16, 37, 15, 31, 37, 17, glass);
box(17, 36, 18, 30, 36, 18, glass);
box(18, 15, 17, 25, 15, 17, glassHi);
// Two dark windows on each side, divided by a bright B-pillar.
for (const x of [12, 35]) {
box(x, 19, 14, x, 24, 17, glass);
box(x, 27, 14, x, 33, 17, glass);
box(x, 25, 14, x, 26, 18, yellowShade);
box(x, 19, 18, x, 33, 18, yellowHi);
box(x, 20, 17, x, 23, 17, glassHi);
box(x, 28, 17, x, 31, 17, glassHi);
}
// Black doors, seams, handles, and a tiny fileteado-inspired flourish.
for (const x of [10, 37]) {
box(x, 17, 6, x, 36, 10, blackHi);
box(x, 25, 6, x, 25, 10, blackLow);
box(x, 18, 11, x, 36, 12, yellow);
box(x, 20, 10, x, 23, 10, "#d6d8d2");
box(x, 29, 10, x, 32, 10, "#d6d8d2");
box(x, 18, 7, x, 23, 7, yellowShade);
box(x, 29, 7, x, 34, 7, yellowShade);
set(x, 24, 8, "#e85c42");
set(x, 26, 8, "#e85c42");
}
// Crisp roof rim and subtly varied paint.
box(14, 19, 20, 33, 19, 20, yellowShade);
box(14, 34, 20, 33, 34, 20, yellowShade);
for (let i = 0; i < 75; i++) {
const x = 15 + Math.floor(rand() * 18);
const y = 20 + Math.floor(rand() * 14);
set(x, y, 21, rand() < 0.65 ? yellowHi : yellow);
}
// Front grille, bumper, and round headlights.
box(17, 4, 7, 30, 4, 9, "#353a3e");
for (let x = 19; x <= 28; x += 2) box(x, 3, 7, x, 3, 9, "#697277");
box(13, 5, 5, 34, 5, 5, "#62696b");
for (const cx of [16, 31]) {
for (let dx = -2; dx <= 2; dx++)
for (let dz = -2; dz <= 2; dz++)
if (dx * dx + dz * dz <= 4)
set(cx + dx, 4, 9 + dz, "#fff3bf");
set(cx, 3, 9, "#ffffff");
}
box(22, 3, 5, 26, 3, 6, "#f7e6b3");
// Rear lights and license plate.
for (const cx of [15, 32]) {
box(cx - 2, 44, 7, cx + 2, 44, 10, "#ad242b");
box(cx - 1, 45, 8, cx + 1, 45, 9, "#f04b42");
box(cx - 2, 44, 10, cx + 2, 44, 10, "#ff9770");
}
box(21, 44, 6, 27, 44, 8, "#ddd9bb");
box(22, 45, 7, 26, 45, 7, "#364250");
box(14, 43, 5, 33, 43, 5, "#62696b");
// Lit roof sign with chunky TAXI lettering.
box(17, 22, 22, 32, 26, 26, yellowShade);
box(18, 21, 23, 31, 21, 25, "#fff4c9");
box(18, 22, 26, 31, 26, 26, yellowHi);
const letters = [
["111", "010", "010"], // T
["010", "111", "101"], // A
["101", "010", "101"], // X
["111", "010", "111"] // I
];
letters.forEach((glyph, i) => {
for (let row = 0; row < 3; row++)
for (let col = 0; col < 3; col++)
if (glyph[row][col] === "1")
set(18 + i * 4 + col, 20, 25 - row, "#25292c");
});
// Each wheel is its own spinning part. Axles run along x.
function wheel(name, cx, cy, outerX) {
part(name, [cx, cy, 5]);
for (let x = cx - 2; x <= cx + 2; x++) {
for (let dy = -5; dy <= 5; dy++) {
for (let dz = -5; dz <= 5; dz++) {
const d2 = dy * dy + dz * dz;
if (d2 <= 25)
set(x, cy + dy, 5 + dz,
d2 >= 17 ? "#111316" : "#202328");
}
}
}
for (let dy = -2; dy <= 2; dy++)
for (let dz = -2; dz <= 2; dz++)
if (dy * dy + dz * dz <= 4)
set(outerX, cy + dy, 5 + dz, "#929b9d");
set(outerX, cy, 5, "#d6d8cf");
for (const [dy, dz] of [[-2, 0], [2, 0], [0, -2], [0, 2]])
set(outerX, cy + dy, 5 + dz, "#566165");
animate(name, { type: "spin", axis: "x", speed: 6 });
}
wheel("front_left_wheel", 9, 12, 7);
wheel("front_right_wheel", 38, 12, 40);
wheel("rear_left_wheel", 9, 36, 7);
wheel("rear_right_wheel", 38, 36, 40);
part("body", [24, 24, 0]);import { draw } from "./assets/voxel";
import { taxi } from "./assets/taxi";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, taxi, 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 taxi
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["taxi"] })
# It lands in client/assets/taxi.ts
# https://fogon.page/object/taxi