← Ancient and prehistory3D assetfogon/pterodactilo
Pterodáctilo
Drag to turn it// «Pterodáctilo» · gpt-6-sol (medium)
// A cartoon pterodactyl in flight, seen with wide leathery wings spread out to both sides (along x), a small body in the middle, a long pointed beak at the front (-y) and a backward-pointing crest on the head. Wings are thin membranes in warm orange-brown with darker finger bones along the front edge; body tan, small black eyes. Raised a little above the floor on a short dark rock perch under its feet.
const stone = ["#494741", "#53514a", "#605d53"];
const tan = "#c99a62";
const tanLight = "#e2b77b";
const rust = "#b66c3c";
const wingLight = "#d58a4c";
const wingDark = "#97532f";
const bone = "#704431";
// Short, rough rock perch.
for (let z = 0; z <= 5; z++) {
const rx = z < 2 ? 8 : z < 4 ? 7 : 6;
const ry = z < 2 ? 6 : 5;
for (let x = 24 - rx; x <= 24 + rx; x++) {
for (let y = 26 - ry; y <= 26 + ry; y++) {
const edge = Math.abs(x - 24) / rx + Math.abs(y - 26) / ry;
if (edge < 1.42 && (edge < 1.12 || rand() > 0.3)) {
set(x, y, z, stone[Math.floor(rand() * stone.length)]);
}
}
}
}
box(20, 23, 6, 28, 28, 6, "#625e51");
line(18, 23, 3, 21, 22, 4, 0, "#373b39");
line(28, 30, 2, 30, 28, 4, 0, "#383b39");
// Feet grip the perch; the little body sits above it.
for (const x of [21, 27]) {
line(x, 24, 15, x, 25, 8, 1, "#866044");
line(x, 25, 8, x, 25, 6, 1, "#684934");
for (const dx of [-2, 0, 2]) {
line(x, 25, 6, x + dx, 22, 6, 0, "#593d30");
set(x + dx, 21, 6, "#42352d");
}
}
ellipsoid(24, 24, 18, 5, 6, 6, "#ad7850");
ellipsoid(24, 22, 20, 4, 5, 5, tan);
ellipsoid(24, 19, 20, 3, 3, 3, tanLight);
line(24, 21, 21, 24, 17, 25, 2, tan);
// Each thin, scalloped membrane is its own flapping part.
function wing(side) {
const shoulder = side < 0 ? 19 : 29;
const name = side < 0 ? "leftWing" : "rightWing";
part(name, [shoulder, 21, 24]);
const front = [19, 18, 18, 17, 17, 16, 16, 16, 16, 17, 17, 17, 18, 18, 19, 19, 19];
const back = [28, 30, 32, 34, 35, 35, 33, 35, 36, 34, 32, 33, 30, 27, 24, 22, 20];
function wx(d) { return shoulder + side * d; }
function height(d, y) {
const t = (back[d] - y) / Math.max(1, back[d] - front[d]);
return 23 + Math.round(d * 0.31 + t * 1.6);
}
for (let d = 0; d <= 16; d++) {
for (let y = front[d]; y <= back[d]; y++) {
const z = height(d, y);
const t = (y - front[d]) / Math.max(1, back[d] - front[d]);
let color = rust;
if (t < 0.24) color = wingLight;
else if (t > 0.8) color = wingDark;
else if (rand() < 0.16) color = "#c47b43";
set(wx(d), y, z, color);
if (d < 12 && t > 0.16 && t < 0.78) {
set(wx(d), y, z - 1, "#a76037");
}
}
}
// Dark leading finger and long supporting struts.
for (let d = 0; d <= 16; d++) {
const z = height(d, front[d]);
set(wx(d), front[d], z + 1, bone);
if (d < 13) set(wx(d), front[d] + 1, z + 1, "#895033");
}
line(wx(1), 21, 25, wx(5), 27, 26, 0, bone);
line(wx(5), 27, 26, wx(8), 35, 25, 0, bone);
line(wx(3), 19, 25, wx(9), 27, 27, 0, bone);
line(wx(9), 27, 27, wx(12), 30, 27, 0, bone);
line(wx(6), 17, 27, wx(12), 22, 28, 0, bone);
line(wx(12), 22, 28, wx(16), 20, 29, 0, bone);
animate(name, { type: "swing", axis: "y", speed: side < 0 ? -4 : 4, amplitude: 0.5 });
}
wing(-1);
wing(1);
part("body");
// Round friendly head and a backward-pointing crest.
ellipsoid(24, 16, 26, 4, 4, 4, tan);
ellipsoid(24, 15, 27, 3, 3, 3, tanLight);
for (let y = 19; y <= 32; y++) {
const t = (y - 19) / 13;
const halfWidth = Math.max(0, Math.round(2 * (1 - t)));
const z = Math.round(30 + 2 * Math.sin(t * Math.PI) - t);
for (let x = 24 - halfWidth; x <= 24 + halfWidth; x++) {
set(x, y, z, y < 24 ? "#b77a49" : "#98603d");
if (y < 28) set(x, y, z + 1, "#d99b5f");
}
}
// Broad base, long pointed beak, and a fine lower-jaw line.
for (let y = 4; y <= 13; y++) {
const width = Math.floor((y - 4) * 0.38);
for (let x = 24 - width; x <= 24 + width; x++) {
const top = 24 + Math.round((y - 4) * 0.25);
set(x, y, top, "#cc8647");
set(x, y, top - 1, "#aa6537");
if (Math.abs(x - 24) < width) set(x, y, top + 1, "#e4a65d");
}
}
set(24, 3, 24, "#8a5233");
line(24, 5, 23, 24, 12, 23, 0, "#7d4b32");
set(22, 11, 27, "#754b37");
set(26, 11, 27, "#754b37");
// Big black dot eyes, visible from the front and sides.
for (const x of [21, 27]) {
set(x, 12, 28, "#342b27");
set(x, 13, 28, "#18191a");
set(x, 12, 27, "#18191a");
set(x, 11, 28, "#ffffff");
}
set(20, 15, 27, "#1b1b1b");
set(28, 15, 27, "#1b1b1b");import { draw } from "./assets/voxel";
import { pterodactilo } from "./assets/pterodactilo";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, pterodactilo, 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 pterodactilo
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["pterodactilo"] })
# It lands in client/assets/pterodactilo.ts
# https://fogon.page/object/pterodactilo