← BásicoObjeto 3Dfogon/frutilla
Frutilla
Arrastrá para girarlo// «Frutilla» · gpt-6-sol (medium)
// Strawberry («Frutilla»).
const cx = 24, cy = 24;
const profile = [
[0, 1.5], [2, 4], [5, 7], [9, 10.5], [13, 13.5],
[17, 16], [22, 18], [27, 19], [30, 18.5],
[33, 16.5], [35, 12.5], [36, 7]
];
function radiusAt(z) {
for (let i = 1; i < profile.length; i++) {
if (z <= profile[i][0]) {
const a = profile[i - 1], b = profile[i];
return a[1] + (b[1] - a[1]) * (z - a[0]) / (b[0] - a[0]);
}
}
return 0;
}
// Broad, rounded shoulders taper to the strawberry's pointed bottom.
for (let z = 0; z <= 36; z++) {
const r = radiusAt(z);
for (let x = 3; x <= 45; x++) {
for (let y = 3; y <= 45; y++) {
const dx = x - cx, dy = y - cy;
const angle = Math.atan2(dy, dx);
const uneven = 0.35 * Math.sin(7 * angle + z * 0.28)
+ 0.25 * Math.sin(11 * angle - z * 0.4);
if ((dx * dx + dy * dy) / ((r + uneven) ** 2) > 1) continue;
let color;
const light = rand();
if (z < 9) color = light < 0.17 ? "#9b2229" : "#ad2029";
else if (z < 20) color = light < 0.19 ? "#ae242c" : "#bf2930";
else color = light < 0.2 ? "#c12a31" : "#d33239";
if (y > 29 && light < 0.42) color = z < 17 ? "#982128" : "#b5252c";
if (x < 21 && y < 25 && z > 17 && light > 0.72) color = "#e13a40";
set(x, y, z, color);
}
}
}
// Little recessed red marks and raised, pale-gold seeds.
for (let z = 6; z <= 32; z += 4) {
const r = radiusAt(z);
const count = Math.round(2 * Math.PI * r / 4.7);
for (let i = 0; i < count; i++) {
if (rand() < 0.09) continue;
const a = 2 * Math.PI * (i + (Math.floor(z / 4) % 2) * 0.5) / count
+ (rand() - 0.5) * 0.13;
const zz = z + Math.round((rand() - 0.5) * 1.4);
const rr = radiusAt(zz);
const x = Math.round(cx + Math.cos(a) * rr);
const y = Math.round(cy + Math.sin(a) * rr);
if (get(x, y, zz) === undefined) continue;
set(x, y, zz - 1, "#942329");
set(x, y, zz, rand() < 0.25 ? "#dc9c51" : "#edbf69");
if (rand() < 0.48) set(x, y, zz + 1, "#f1ce79");
if (rand() < 0.38) set(x + Math.sign(Math.cos(a)), y + Math.sign(Math.sin(a)), zz, "#b96d36");
}
}
// Dark undersides of seven separate pointed calyx leaves.
const leaves = [
[-1.40, 18], [-0.54, 17], [0.31, 18], [1.22, 19],
[2.05, 17], [2.93, 18], [3.79, 16], [4.57, 17]
];
for (const [a, length] of leaves) {
const ux = Math.cos(a), uy = Math.sin(a);
const vx = -uy, vy = ux;
for (let s = 3; s <= length; s++) {
const width = Math.max(0, Math.round(1 + 3.1 * Math.sin(Math.PI * s / length)));
const tip = s > length - 3;
for (let t = -width; t <= width; t++) {
if (tip && Math.abs(t) > length - s) continue;
const x = Math.round(cx + ux * s + vx * t);
const y = Math.round(cy + uy * s + vy * t);
const z = Math.round(38 - 0.32 * s - (s > 13 ? (s - 13) * 0.55 : 0));
set(x, y, z - 1, "#195c20");
set(x, y, z, Math.abs(t) === width ? "#247b21" :
rand() < 0.23 ? "#318e25" : "#3a9e27");
if (Math.abs(t) < 1 && s < length - 2 && rand() < 0.7)
set(x, y, z + 1, "#51ac2b");
}
}
}
// Leafy central crown, with a few lighter top-facing blocks.
ellipsoid(cx, cy, 37, 7, 6, 2, "#328c24");
for (let x = 18; x <= 30; x++)
for (let y = 18; y <= 30; y++)
if (get(x, y, 38) && rand() < 0.42)
set(x, y, 38, rand() < 0.55 ? "#53ad2c" : "#419c29");
// Short bent stalk rising above the crown.
box(23, 23, 38, 25, 25, 40, "#286e22");
box(24, 23, 41, 25, 24, 42, "#338322");
box(25, 22, 42, 26, 23, 43, "#378a25");
set(26, 21, 44, "#4a9d2b");
set(25, 22, 44, "#2b7622");import { draw } from "./assets/voxel";
import { frutilla } from "./assets/frutilla";
// En cada cuadro: parado sobre (x, y), el centro de su base.
draw(ctx, frutilla, 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 frutilla
# Con las herramientas de Fogón (conector)
add_assets({ slug: "<tu-juego>", ids: ["frutilla"] })
# Queda en client/assets/frutilla.ts
# https://fogon.page/object/frutilla