← Monsters and enemies3D assetfogon/vampiro
Vampiro
Drag to turn it// «Vampiro» · gpt-6-sol (medium)
// A cartoon vampire count facing -y: pale lavender-white face with slicked black hair in a widow's peak, red glowing eyes and two small white fangs, a black suit with a white shirt and red bow tie, and a long black cape with a tall pointed red-lined collar falling to the floor behind him.
const black = "#171425";
const shadow = "#0d0b18";
const suit = "#252334";
const suitLight = "#343246";
const skin = "#e9e0f6";
const skinShade = "#c9b9df";
const hair = "#10101b";
const red = "#c72543";
const brightRed = "#ff4055";
// Legs pivot independently at the hips.
part("leftLeg", [20, 23, 17]);
box(17, 20, 5, 22, 27, 17, suit);
box(17, 19, 5, 18, 26, 15, suitLight);
box(16, 15, 0, 22, 27, 5, shadow);
box(16, 14, 1, 22, 20, 4, black);
box(17, 14, 4, 21, 16, 4, suitLight);
animate("leftLeg", { type: "swing", axis: "x", speed: 4, amplitude: 0.3 });
part("rightLeg", [28, 23, 17]);
box(26, 20, 5, 31, 27, 17, suit);
box(30, 19, 5, 31, 26, 15, suitLight);
box(26, 15, 0, 32, 27, 5, shadow);
box(26, 14, 1, 32, 20, 4, black);
box(27, 14, 4, 31, 16, 4, suitLight);
animate("rightLeg", { type: "swing", axis: "x", speed: -4, amplitude: 0.3 });
part("body");
// Chunky suit and broad shoulders.
box(14, 19, 16, 34, 29, 28, suit);
box(13, 20, 25, 35, 28, 29, suitLight);
box(15, 17, 18, 33, 19, 26, black);
box(15, 17, 16, 33, 27, 18, shadow);
box(21, 16, 19, 27, 19, 29, "#f4f0fa");
box(22, 15, 20, 26, 16, 28, "#ffffff");
// Angled lapels frame the white shirt.
for (let z = 20; z <= 28; z++) {
const inset = Math.floor((z - 20) / 3);
box(17 + inset, 15, z, 20 + inset, 18, z, suitLight);
box(28 - inset, 15, z, 31 - inset, 18, z, suitLight);
}
line(17, 15, 20, 23, 15, 28, 0, "#575267");
line(31, 15, 20, 25, 15, 28, 0, "#575267");
set(24, 15, 21, "#e5b76a");
set(24, 15, 18, "#e5b76a");
// Sleeves, cuffs, and pale hands.
for (const [a, b] of [[10, 15], [33, 38]]) {
box(a, 19, 18, b, 27, 26, suit);
box(a, 19, 24, b, 25, 27, suitLight);
box(a, 18, 16, b, 27, 18, "#f4f0fa");
box(a + 1, 18, 12, b - 1, 26, 16, skinShade);
box(a + 1, 17, 14, b - 1, 20, 16, skin);
}
// Neck, oversized lavender-white face, and soft lower-face shading.
box(21, 20, 27, 27, 25, 31, skinShade);
ellipsoid(24, 21, 34, 9, 8, 8, skinShade);
ellipsoid(24, 19, 35, 8, 6, 7, skin);
box(18, 15, 29, 20, 16, 32, "#f7efff");
box(28, 15, 29, 30, 16, 32, "#f7efff");
box(22, 13, 31, 26, 15, 33, skinShade);
box(23, 12, 32, 25, 14, 33, "#f8f0ff");
// Slick, swept-back black hair and sharp widow's peak.
ellipsoid(24, 22, 40, 9, 8, 4, hair);
box(16, 18, 37, 18, 26, 40, shadow);
box(30, 18, 37, 32, 26, 40, shadow);
box(17, 15, 38, 31, 18, 40, hair);
box(19, 14, 37, 29, 16, 38, hair);
box(22, 14, 36, 26, 16, 37, hair);
box(23, 13, 35, 25, 15, 36, hair);
for (let x = 19; x <= 29; x += 3) {
line(x, 16, 40, x + 2, 23, 42, 0, "#302b3b");
}
// Expressive glowing red eyes beneath dark brows.
for (const x of [20, 28]) {
box(x - 2, 13, 33, x + 2, 15, 36, "#443448");
box(x - 2, 12, 36, x + 2, 14, 37, hair);
box(x - 1, 12, 34, x + 1, 13, 35, brightRed);
set(x, 11, 35, "#ffab79");
set(x + 1, 11, 34, "#ff6c68");
}
box(21, 14, 29, 27, 15, 30, "#65445d");
box(22, 13, 29, 26, 14, 29, "#56334d");
// Two tiny, friendly fangs.
box(21, 12, 28, 22, 14, 30, "#ffffff");
box(26, 12, 28, 27, 14, 30, "#ffffff");
// Big, unmistakable red bow tie.
box(20, 13, 26, 23, 16, 28, "#a51437");
box(25, 13, 26, 28, 16, 28, "#a51437");
box(20, 12, 27, 22, 14, 28, brightRed);
box(26, 12, 27, 28, 14, 28, brightRed);
box(23, 11, 26, 25, 14, 28, "#e52b48");
// Cape hangs behind him and sways from the shoulders.
part("cape", [24, 29, 29]);
for (let z = 0; z <= 30; z++) {
const taper = Math.floor(z * 0.17);
const left = 8 + taper;
const right = 40 - taper;
const front = 30 - Math.floor(z / 10);
const back = front + 4;
box(left, front, z, right, back, z, z < 5 ? shadow : black);
box(left + 2, front, z, right - 2, front, z,
z < 6 ? "#681c35" : "#92213d");
// Heavy dark outer seam makes the silhouette read at a distance.
box(left, front, z, left + 1, back, z, shadow);
box(right - 1, front, z, right, back, z, shadow);
if (z % 5 === 0) {
box(left + 2, back, z, right - 2, back, z, "#292334");
}
}
// Tall pointed collar: black edges with a vivid red lining.
for (const side of [-1, 1]) {
for (let z = 29; z <= 42; z++) {
const outer = z > 36 ? 12 - Math.floor((z - 36) / 3) : 13;
const inner = z > 38 ? 17 - Math.floor((z - 38) / 2) : 17;
const x0 = side < 0 ? outer : 48 - inner;
const x1 = side < 0 ? inner : 48 - outer;
box(x0, 22, z, x1, 30, z, shadow);
if (z <= 39) {
box(x0 + 2, 21, z, x1 - 2, 23, z,
z > 35 ? "#f03750" : red);
}
}
}
animate("cape", { type: "swing", axis: "x", speed: 2, amplitude: 0.15 });import { draw } from "./assets/voxel";
import { vampiro } from "./assets/vampiro";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, vampiro, 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 vampiro
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["vampiro"] })
# It lands in client/assets/vampiro.ts
# https://fogon.page/object/vampiro