← BásicoObjeto 3Dfogon/biplano-rojo
Biplano rojo
Arrastrá para girarlo// «Biplano rojo» · gpt-6-sol (medium)
// Biplane («Biplano rojo»).
// Red biplane — front faces -y.
const red = "#d8372b";
const darkRed = "#aa261f";
const cream = "#f0e8d1";
const navy = "#26333b";
const steel = "#657174";
const wood = "#98622e";
function wing(x0, x1, y0, y1, z, upper) {
for (let x = x0; x <= x1; x++) {
for (let y = y0; y <= y1; y++) {
const tip = Math.min(x - x0, x1 - x);
if (tip === 0 && (y === y0 || y === y1)) continue;
set(x, y, z - 2, "#92251f");
set(x, y, z - 1, y === y0 ? cream : darkRed);
let color = red;
if (y === y0) color = cream;
else if (y === y0 + 1) color = "#f04a37";
else if (y === y1) color = "#ab2823";
else if (x % 6 === 0) color = "#e34030";
else if (rand() < 0.09) color = "#dd392b";
set(x, y, z, color);
}
}
// Pale, squared-off wing tips.
for (let y = y0 + 1; y <= y1 - 1; y++) {
set(x0, y, z, cream);
set(x1, y, z, cream);
}
if (upper) {
// Blue-white-red insignia, one near each tip.
for (const cx of [x0 + 8, x1 - 8]) {
const cy = Math.floor((y0 + y1) / 2);
for (let dx = -4; dx <= 4; dx++) {
for (let dy = -4; dy <= 4; dy++) {
const d = Math.sqrt(dx * dx + dy * dy);
if (d <= 3.8) {
set(cx + dx, cy + dy, z + 1,
d > 2.7 ? navy : d > 1.35 ? "#f3eee0" : red);
}
}
}
}
}
}
// Tailplane and its cream-edged elevator.
box(16, 36, 22, 32, 42, 23, darkRed);
box(17, 36, 24, 31, 41, 24, red);
box(16, 42, 24, 32, 43, 24, cream);
box(21, 38, 25, 27, 43, 25, "#e74432");
box(23, 37, 25, 25, 42, 29, darkRed);
box(23, 38, 27, 25, 41, 31, red);
box(23, 40, 30, 25, 42, 32, "#e34734");
// Rear fuselage, tapering toward the tail.
for (let y = 26; y <= 42; y++) {
const half = y > 35 ? 2 : 3;
box(24 - half, y, 20, 24 + half, y, 23,
y % 4 === 0 ? "#c32b24" : red);
box(24 - half, y, 24, 24 + half, y, 24, "#e44532");
}
box(22, 37, 20, 26, 42, 21, "#87251f");
// Lower wing: broad red panels and a bright leading edge.
wing(5, 43, 17, 28, 18, false);
box(7, 17, 19, 41, 17, 19, cream);
// Fuselage and raised red engine cowling.
box(20, 12, 19, 28, 33, 25, darkRed);
box(21, 12, 21, 27, 31, 26, red);
box(21, 13, 26, 27, 20, 27, "#ed4835");
box(20, 18, 22, 20, 30, 24, "#a32922");
box(28, 18, 22, 28, 30, 24, "#a32922");
for (let y = 15; y <= 31; y += 4) {
box(21, y, 25, 27, y, 25, "#ed4b35");
}
// Open cockpit, leather rim, seat and small windscreen.
box(21, 24, 26, 27, 32, 27, "#9b331f");
box(22, 25, 27, 26, 30, 27, "#253039");
box(22, 29, 27, 26, 31, 28, "#a36a38");
box(21, 24, 28, 27, 24, 28, "#c7753d");
box(21, 31, 27, 27, 31, 27, "#c7753d");
box(22, 22, 27, 26, 22, 29, "#8daaaa");
box(23, 22, 28, 25, 22, 29, "#d7dfd2");
// Exposed dark engine blocks and silver cylinder heads.
for (const x of [18, 29]) {
box(x, 10, 19, x + 1, 17, 23, navy);
for (const y of [11, 14, 17]) {
box(x, y, 20, x + 1, y + 1, 22, steel);
set(x, y, 23, "#a0a8a1");
}
}
box(21, 10, 20, 27, 17, 25, "#b72b23");
box(21, 10, 25, 27, 16, 26, "#ea4230");
box(22, 9, 19, 26, 11, 24, "#4b5555");
// Landing gear: angled wooden supports, axle and two chunky tires.
for (const [wx, root] of [[13, 20], [35, 28]]) {
line(root, 19, 18, wx, 15, 5, 1, wood);
line(24, 21, 18, wx, 15, 5, 0, "#79512c");
line(root, 17, 16, wx, 15, 7, 0, "#c18b4c");
}
line(13, 15, 5, 35, 15, 5, 0, "#747875");
for (const x0 of [11, 33]) {
cylinder(x0, 15, 4, 4, 4, "#1a2227", "x");
cylinder(x0 + 1, 15, 4, 3, 2, "#303b3e", "x");
}
for (const x of [11, 36]) {
for (let y = 12; y <= 18; y++) {
for (let z = 1; z <= 7; z++) {
const d = Math.hypot(y - 15, z - 4);
if (d <= 2.4) set(x, y, z, "#50565a");
if (d <= 1.35) set(x, y, z, "#b1a58b");
}
}
set(x, 15, 4, "#686a64");
}
// Interplane struts and diagonal bracing.
for (const x of [11, 16, 33, 38]) {
for (const y of [19, 26]) {
box(x, y, 19, x + 1, y + 1, 32, "#343d3e");
box(x, y, 21, x, y, 29, "#687172");
}
}
for (const x of [13, 35]) {
line(x, 20, 20, x + 2, 25, 32, 0, "#90928a");
line(x + 2, 26, 20, x, 19, 32, 0, "#666d6a");
}
box(22, 21, 27, 23, 22, 33, "#4a5050");
box(26, 21, 27, 27, 22, 33, "#4a5050");
// High upper wing and its roundels.
wing(3, 45, 17, 27, 34, true);
box(5, 17, 32, 43, 17, 33, cream);
box(5, 27, 32, 43, 27, 33, "#912821");
// Wooden propeller, mounted ahead of the engine.
box(23, 7, 16, 25, 8, 28, wood);
box(23, 7, 13, 25, 8, 17, "#bb8544");
box(23, 7, 27, 25, 8, 30, "#bb8544");
box(22, 7, 20, 26, 8, 22, "#a36d36");
box(22, 6, 19, 26, 7, 23, "#4c5655");
box(23, 5, 20, 25, 6, 22, "#929997");
set(24, 5, 21, "#343e3f");import { draw } from "./assets/voxel";
import { biplanoRojo } from "./assets/biplano-rojo";
// En cada cuadro: parado sobre (x, y), el centro de su base.
draw(ctx, biplanoRojo, 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 biplano-rojo
# Con las herramientas de Fogón (conector)
add_assets({ slug: "<tu-juego>", ids: ["biplano-rojo"] })
# Queda en client/assets/biplano-rojo.ts
# https://fogon.page/object/biplano-rojo