← Monsters and enemies3D assetfogon/torreta
Torreta
Drag to turn it// «Torreta» · gpt-6-sol (medium)
// A cartoon enemy defense turret: a sturdy round grey metal base bolted to the floor with yellow-black hazard stripes, a rotating head on top with a dark visor slit glowing red and two short gun barrels pointing toward -y.
const cx = 24, cy = 24;
const dist = (x, y) => Math.hypot(x - cx, y - cy);
// Heavy, stepped circular base.
for (let z = 0; z <= 17; z++) {
const r = z <= 2 ? 17 : z <= 9 ? 16 : z <= 13 ? 14 : 11;
for (let x = cx - 17; x <= cx + 17; x++) {
for (let y = cy - 17; y <= cy + 17; y++) {
const d = dist(x, y);
if (d > r) continue;
let color = z < 2 ? "#30363c"
: z < 5 ? "#59636b"
: z < 10 ? "#69757d"
: z < 14 ? "#59656d" : "#414c54";
if (d > r - 1.3) color = z < 3 ? "#252b30" : "#39444b";
if ((z === 2 || z === 9 || z === 13) && d > r - 1.8)
color = "#a2adb1";
// Diagonal yellow-and-black warning bands around the lower skirt.
if (z >= 4 && z <= 7 && d > r - 2.4) {
const angle = Math.atan2(y - cy, x - cx);
const band = Math.floor(angle * 12 / Math.PI + z * 0.55);
color = ((band % 2) + 2) % 2
? (z >= 6 ? "#ffd344" : "#e9ad28")
: "#24282b";
}
if (d < r - 2 && rand() < 0.045)
color = z > 9 ? "#78848b" : "#7f8b90";
set(x, y, z, color);
}
}
}
// Floor bolts: dark sockets, steel heads, bright screw marks.
for (const [x, y] of [[12, 12], [36, 12], [12, 36], [36, 36]]) {
cylinder(x, y, 2, 2, 2, "#252b30");
cylinder(x, y, 4, 1, 1, "#c2c9c8");
set(x, y, 5, "#626c71");
set(x - 1, y, 4, "#e0d6a0");
}
// Stationary bearing beneath the turning head.
cylinder(24, 24, 16, 10, 3, "#242d34");
cylinder(24, 24, 18, 9, 2, "#a0aaad");
cylinder(24, 24, 20, 8, 1, "#343e46");
part("head", [24, 24, 26]);
// Rounded, solid armored head with a light crown and shaded underside.
for (let z = 17; z <= 36; z++) {
for (let x = 10; x <= 38; x++) {
for (let y = 10; y <= 38; y++) {
const v =
((x - 24) / 14) ** 2 +
((y - 24) / 14) ** 2 +
((z - 26) / 10) ** 2;
if (v > 1) continue;
let color = z < 21 ? "#37434c"
: z < 26 ? "#60717c"
: z < 31 ? "#83949d" : "#a8b6b9";
if (v > 0.81 && z < 28) color = "#46545e";
if (y < 19 && z >= 28 && v < 0.86) color = "#a7b7bb";
if (v < 0.8 && rand() < 0.025) color = "#b6c0bf";
set(x, y, z, color);
}
}
}
// Broad armored brow and inset, dark visor.
box(16, 11, 29, 32, 14, 31, "#36424b");
box(18, 10, 31, 30, 14, 32, "#c1c8c5");
box(15, 10, 24, 33, 12, 29, "#273039");
box(17, 9, 25, 31, 9, 28, "#101820");
box(18, 8, 26, 30, 8, 28, "#ad222e");
box(19, 7, 27, 29, 7, 27, "#ff4b50");
box(19, 8, 28, 22, 8, 28, "#ff8581");
box(26, 8, 28, 29, 8, 28, "#ff8581");
box(23, 7, 27, 25, 7, 27, "#91212c");
box(17, 9, 24, 31, 9, 24, "#68777e");
// Two short, chunky barrels project toward the viewer (-y).
for (const x of [13, 35]) {
box(x - 3, 12, 19, x + 3, 18, 24, "#35414a");
box(x - 2, 11, 23, x + 2, 16, 24, "#89969b");
cylinder(x, 4, 21, 2, 11, "#535f68", "y");
cylinder(x, 6, 21, 2, 2, "#a3adb0", "y");
cylinder(x, 3, 21, 3, 2, "#283138", "y");
cylinder(x, 3, 21, 2, 1, "#879398", "y");
set(x, 2, 21, "#11191f");
set(x, 2, 22, "#11191f");
set(x - 1, 2, 21, "#11191f");
set(x + 1, 2, 21, "#11191f");
set(x, 2, 20, "#11191f");
set(x, 2, 23, "#c1c8c6");
}
// Small warning beacon atop the head.
cylinder(24, 24, 35, 3, 2, "#313b43");
cylinder(24, 24, 37, 2, 2, "#e33b3b");
set(24, 22, 38, "#ff9990");
animate("head", { type: "swing", axis: "z", speed: 1, amplitude: 0.6 });import { draw } from "./assets/voxel";
import { torreta } from "./assets/torreta";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, torreta, 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 torreta
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["torreta"] })
# It lands in client/assets/torreta.ts
# https://fogon.page/object/torreta