← BásicoObjeto 3Dfogon/manzana
Manzana
Arrastrá para girarlo// «Manzana» · gpt-6-sol (medium)
// Apple («Manzana»).
// Rounded apple with a shallow dimple around the stem.
for (let x = 4; x <= 44; x++) {
for (let y = 4; y <= 44; y++) {
const dx = x - 24, dy = y - 24;
const angle = Math.atan2(dy, dx);
const ribs = 1 + 0.018 * Math.cos(7 * angle + 0.4)
+ 0.012 * Math.cos(11 * angle);
const r = Math.hypot(dx, dy) / ribs;
if (r >= 20) continue;
const round = Math.sqrt(Math.max(0, 1 - (r / 20) ** 2));
const bottom = 17 - 17 * round;
const dimple = 5.3 * Math.exp(-(r * r) / 36);
const crown = 0.65 * Math.cos(5 * angle + 0.3)
* Math.exp(-(((r - 8) / 8) ** 2));
const top = 16 + 18 * round - dimple + crown;
for (let z = Math.ceil(bottom); z <= Math.floor(top); z++) {
set(x, y, z, "#bd1d31");
}
}
}
// Shade the exposed voxel steps: bright red crown, deeper red underneath.
const skin = [];
forEach((x, y, z) => skin.push([x, y, z]));
for (const [x, y, z] of skin) {
const upper = !get(x, y, z + 1);
const front = !get(x, y - 1, z);
const side = !get(x + 1, y, z) || !get(x - 1, y, z);
if (!upper && !front && !side) continue;
const light = z * 0.07 + (x - 24) * 0.045 + (upper ? 1.1 : 0);
const rib = Math.cos(9 * Math.atan2(y - 24, x - 24) + z * 0.08);
const fleck = rand();
let color;
if (z < 7) color = fleck < 0.20 ? "#941a29" : "#a7192b";
else if (light > 2.8) color = fleck < 0.18 ? "#ec3949" : "#dc2940";
else if (light > 1.7) color = fleck < 0.18 ? "#df2a40" : "#ca2037";
else color = fleck < 0.23 ? "#a5182b" : "#ba1b30";
if (rib > 0.84 && !upper && fleck < 0.55) color = "#aa192c";
if (front && z < 17 && fleck < 0.12) color = "#a7192b";
set(x, y, z, color);
}
// Small broken, creamy reflection on the front of the skin.
const glint = [
[23, 20, "#f4d9aa"], [24, 20, "#eebf9b"],
[22, 19, "#f7dfb8"], [24, 19, "#ffe5b9"],
[25, 18, "#f7ddb0"], [22, 17, "#f3d9b5"],
[24, 17, "#fff0c9"], [26, 17, "#eebfa0"],
[23, 16, "#f8dfb8"], [25, 16, "#ffedc6"],
[26, 15, "#f0c49f"], [23, 14, "#f3d8ae"],
[25, 14, "#fff0c9"], [24, 13, "#e9bb9b"],
[26, 12, "#f0d0aa"]
];
for (const [x, z, color] of glint) {
for (let y = 4; y <= 24; y++) {
if (get(x, y, z)) {
set(x, y - 1, z, color);
break;
}
}
}
// Short woody stem, emerging from the sunken center.
box(25, 23, 29, 26, 24, 39, "#754022");
box(25, 23, 31, 25, 23, 39, "#a26832");
box(26, 24, 32, 26, 24, 39, "#542e20");
box(25, 23, 40, 27, 24, 41, "#67371f");
set(26, 23, 41, "#a36a36");
// One broad leaf, extending left from the stem.
const widths = [1, 2, 3, 3, 4, 4, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0];
for (let x = 9; x <= 24; x++) {
const i = x - 9;
const cy = 21 + Math.round(i * 0.18);
const w = widths[i];
const high = i >= 3 && i <= 10 ? 39 : (i <= 1 ? 37 : 38);
for (let y = cy - w; y <= cy + w; y++) {
const edge = Math.abs(y - cy) >= w;
const lower = edge ? high - 2 : high - 3;
for (let z = lower; z <= high - (edge ? 1 : 0); z++) {
set(x, y, z, edge ? "#32732c" : "#508d2e");
}
if (!edge) {
set(x, y, high, rand() < 0.27 ? "#95bd45" : "#78aa36");
}
}
}
for (let x = 12; x <= 21; x++) {
const y = 21 + Math.round((x - 9) * 0.18);
set(x, y, x <= 19 ? 40 : 39, x % 3 === 0 ? "#b2cc59" : "#98bd47");
}import { draw } from "./assets/voxel";
import { manzana } from "./assets/manzana";
// En cada cuadro: parado sobre (x, y), el centro de su base.
draw(ctx, manzana, 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 manzana
# Con las herramientas de Fogón (conector)
add_assets({ slug: "<tu-juego>", ids: ["manzana"] })
# Queda en client/assets/manzana.ts
# https://fogon.page/object/manzana