function setup() { createCanvas(800, 1000, WEBGL); randomSeed(93613); noiseSeed(93613); brush.scaleBrushes(1); noLoop(); } function draw() { translate(-width / 2, -height / 2); // Night ground background(8, 8, 26); // Atmospheric depth - subtle radial glow behind angel brush.noStroke(); for (let i = 0; i < 12; i++) { let r = 380 - i * 28; let c = lerpColor(color(10, 12, 40), color(20, 35, 90), i / 12); brush.fill(c, 14 + i * 3); brush.circle(400, 380, r, 0.3); } // Distant war fires - lower portion for (let i = 0; i < 18; i++) { let fx = random(80, 720); let fy = random(750, 960); let fr = random(15, 55); let fc = lerpColor(color(180, 60, 10), color(255, 160, 20), random()); brush.fill(fc, random(12, 30)); brush.circle(fx, fy, fr, 0.6); } // Smoke columns rising from below brush.set("charcoal", color(30, 25, 45), 3); for (let s = 0; s < 7; s++) { let sx = random(100, 700); let sy = random(800, 950); for (let j = 0; j < 12; j++) { let nx = sx + noise(s * 10, j * 0.3) * 80 - 40; let ny = sy - j * random(30, 55); let nx2 = nx + noise(s * 10 + 5, j * 0.3 + 1) * 60 - 30; let ny2 = ny - random(20, 40); brush.line(nx, ny, nx2, ny2); } } // LEFT WING - large sweeping strokes, slightly torn brush.set("2B", color(25, 50, 140), 8); for (let i = 0; i < 14; i++) { let angle = map(i, 0, 13, -2.4, -1.1); let len = map(i, 0, 13, 320, 180); let sx = 390; let sy = 340; let ex = sx + cos(angle) * len + random(-15, 15); let ey = sy + sin(angle) * len + random(-10, 10); let mx = lerp(sx, ex, 0.5) + random(-30, 10); let my = lerp(sy, ey, 0.5) + random(-20, 20); brush.line(sx, sy, mx, my); brush.line(mx, my, ex, ey); } // Wing feather details - left brush.set("HB", color(40, 80, 200), 4); for (let i = 0; i < 20; i++) { let angle = map(i, 0, 19, -2.5, -1.0); let baseR = map(i, 0, 19, 200, 120); let sx = 390 + cos(angle) * baseR * 0.6; let sy = 340 + sin(angle) * baseR * 0.6; let ex = 390 + cos(angle) * baseR + random(-10, 10); let ey = 340 + sin(angle) * baseR + random(-8, 8); brush.line(sx, sy, ex, ey); } // RIGHT WING - more damaged, aggressive brush.set("2B", color(20, 45, 130), 9); for (let i = 0; i < 12; i++) { let angle = map(i, 0, 11, -0.3, 1.2); let len = map(i, 0, 11, 300, 160); if (i > 7) len *= random(0.5, 0.8); // torn feathers let sx = 420; let sy = 330; let ex = sx + cos(angle) * len + random(-20, 20); let ey = sy + sin(angle) * len + random(-15, 15); let mx = lerp(sx, ex, 0.45) + random(-25, 25); let my = lerp(sy, ey, 0.45) + random(-20, 20); brush.line(sx, sy, mx, my); brush.line(mx, my, ex, ey); } // Wing feather details - right, some broken brush.set("HB", color(35, 70, 190), 4); for (let i = 0; i < 16; i++) { let angle = map(i, 0, 15, -0.2, 1.3); let baseR = map(i, 0, 15, 190, 100); if (i > 10) baseR *= random(0.4, 0.7); let sx = 420 + cos(angle) * baseR * 0.5; let sy = 330 + sin(angle) * baseR * 0.5; let ex = 420 + cos(angle) * baseR + random(-12, 12); let ey = 330 + sin(angle) * baseR + random(-10, 10); brush.line(sx, sy, ex, ey); } // Wing glow - luminous edges brush.set("pen", color(80, 140, 255), 2); for (let i = 0; i < 10; i++) { let angle = map(i, 0, 9, -2.3, -1.2); let r = 280 + random(-20, 20); let x1 = 390 + cos(angle) * r; let y1 = 340 + sin(angle) * r; let x2 = x1 + cos(angle + 0.3) * random(20, 50); let y2 = y1 + sin(angle + 0.3) * random(20, 50); brush.line(x1, y1, x2, y2); } for (let i = 0; i < 8; i++) { let angle = map(i, 0, 7, -0.1, 1.1); let r = 270 + random(-20, 20); let x1 = 420 + cos(angle) * r; let y1 = 330 + sin(angle) * r; let x2 = x1 + cos(angle - 0.2) * random(20, 45); let y2 = y1 + sin(angle - 0.2) * random(20, 45); brush.line(x1, y1, x2, y2); } // ANGEL BODY - torso, monumental brush.noStroke(); brush.fill(color(20, 45, 130), 180); brush.fillBleed(3, "out"); brush.circle(400, 380, 90, 0.2); brush.fill(color(30, 60, 160), 140); brush.circle(400, 440, 70, 0.25); brush.fill(color(25, 50, 145), 160); brush.circle(400, 510, 55, 0.3); // Body contour marks brush.set("2B", color(15, 30, 100), 6); brush.line(360, 310, 355, 420); brush.line(355, 420, 365, 530); brush.line(440, 315, 448, 425); brush.line(448, 425, 438, 525); // Armor-like chest plates brush.set("rotring", color(60, 100, 220), 3); brush.line(370, 350, 430, 350); brush.line(372, 375, 428, 375); brush.line(375, 400, 425, 400); brush.line(368, 340, 380, 410); brush.line(432, 340, 420, 410); // HEAD brush.noStroke(); brush.fill(color(35, 65, 170), 200); brush.circle(400, 270, 42, 0.15); // Face suggestion - fierce brush.set("pen", color(10, 20, 60), 2); brush.line(388, 262, 396, 264); brush.line(404, 264, 412, 262); brush.line(395, 278, 405, 278); // Halo - fractured, war-damaged brush.set("rotring", color(200, 170, 50), 3); for (let i = 0; i < 14; i++) { let a1 = map(i, 0, 13, 0, TWO_PI * 0.85); let a2 = a1 + 0.25; if (i > 9) { a2 = a1 + random(0.1, 0.2); } // broken section let r = 55 + random(-3, 3); let x1 = 400 + cos(a1) * r; let y1 = 260 + sin(a1) * r * 0.4; let x2 = 400 + cos(a2) * r; let y2 = 260 + sin(a2) * r * 0.4; brush.line(x1, y1, x2, y2); } // Halo glow brush.noStroke(); brush.fill(color(220, 180, 60), 25); brush.circle(400, 260, 80, 0.4); // SWORD - diagonal slash, the war element // Blade brush.set("rotring", color(180, 200, 240), 4); brush.line(310, 200, 520, 620); brush.set("pen", color(220, 235, 255), 2); brush.line(312, 202, 518, 618); brush.line(308, 198, 522, 622); // Blade glow brush.noStroke(); brush.fill(color(100, 150, 255), 20); brush.circle(415, 410, 120, 0.5); // Sword guard brush.set("2B", color(200, 170, 50), 5); brush.line(355, 310, 395, 290); brush.line(350, 300, 400, 285); // Sword pommel brush.noStroke(); brush.fill(color(220, 180, 60), 220); brush.circle(308, 198, 12, 0.2); // ENERGY SLASH - the sword cutting through space brush.set("marker", color(100, 160, 255), 6); for (let i = 0; i < 8; i++) { let t = i / 8; let x1 = lerp(280, 550, t) + random(-20, 20); let y1 = lerp(170, 650, t) + random(-15, 15); let x2 = x1 + random(30, 80); let y2 = y1 + random(20, 60); brush.line(x1, y1, x2, y2); } // Impact sparks where sword meets something brush.set("pen", color(255, 220, 100), 2); for (let i = 0; i < 15; i++) { let angle = random(TWO_PI); let len = random(15, 60); let cx = 480 + random(-20, 20); let cy = 560 + random(-20, 20); brush.line(cx, cy, cx + cos(angle) * len, cy + sin(angle) * len); } // ARMS - reaching for the sword, dynamic brush.set("2B", color(25, 50, 140), 7); // Right arm holding sword brush.line(430, 350, 460, 300); brush.line(460, 300, 440, 260); brush.line(440, 260, 380, 240); // Left arm - striking outward brush.line(370, 360, 320, 400); brush.line(320, 400, 280, 380); // Hand on sword brush.noStroke(); brush.fill(color(30, 55, 150), 200); brush.circle(365, 295, 18, 0.2); // LEGS - descending, one forward brush.set("2B", color(20, 40, 120), 7); brush.line(385, 530, 360, 640); brush.line(360, 640, 350, 720); brush.line(415, 530, 450, 650); brush.line(450, 650, 470, 740); // Flowing robe/energy below brush.set("HB", color(30, 60, 150), 4); for (let i = 0; i < 12; i++) { let sx = 370 + random(-20, 50); let sy = 520 + random(0, 30); let ex = sx + random(-40, 40); let ey = sy + random(60, 140); brush.line(sx, sy, ex, ey); } // BATTLE DEBRIS - falling fragments brush.set("charcoal", color(60, 50, 80), 3); for (let i = 0; i < 20; i++) { let fx = random(150, 650); let fy = random(500, 900); let angle = random(TWO_PI); let len = random(8, 30); brush.line(fx, fy, fx + cos(angle) * len, fy + sin(angle) * len); } // Blood/ichor drops - golden, divine brush.noStroke(); for (let i = 0; i < 10; i++) { let dx = random(350, 500); let dy = random(400, 700); brush.fill(color(220, 160, 40), random(80, 180)); brush.circle(dx, dy, random(4, 10), 0.3); } // Enemy shadows - dark forms being struck brush.noStroke(); brush.fill(color(5, 5, 15), 120); brush.circle(520, 600, 60, 0.5); brush.circle(560, 650, 45, 0.6); brush.circle(490, 640, 35, 0.4); // Dark enemy marks brush.set("charcoal", color(10, 8, 20), 5); brush.line(500, 580, 540, 630); brush.line(530, 590, 570, 660); brush.line(480, 620, 510, 670); // Upper atmosphere - stars, distant brush.set("pen", color(150, 170, 220), 1); for (let i = 0; i < 30; i++) { let sx = random(20, 780); let sy = random(20, 200); if (dist(sx, sy, 400, 270) > 100) { let len = random(2, 6); let a = random(TWO_PI); brush.line(sx, sy, sx + cos(a) * len, sy + sin(a) * len); } } // Divine light rays from above brush.set("HB", color(60, 80, 180), 2); for (let i = 0; i < 8; i++) { let x = 350 + i * 15 + random(-5, 5); brush.line(x, 30, x + random(-20, 20), 180 + random(0, 40)); } // Wing shadow on body brush.noStroke(); brush.fill(color(10, 15, 50), 60); brush.circle(380, 400, 50, 0.3); // Final energy burst around the figure brush.set("marker", color(50, 90, 220), 3); for (let i = 0; i < 12; i++) { let angle = random(TWO_PI); let r1 = random(100, 150); let r2 = r1 + random(40, 100); let cx = 400 + random(-20, 20); let cy = 380 + random(-20, 20); brush.line( cx + cos(angle) * r1, cy + sin(angle) * r1, cx + cos(angle) * r2, cy + sin(angle) * r2 ); } // Ground fire reflection brush.noStroke(); for (let i = 0; i < 8; i++) { let gx = random(200, 600); let gy = random(880, 980); brush.fill(color(180, 80, 20), random(15, 40)); brush.circle(gx, gy, random(20, 60), 0.5); } // Crimson war accent on the angel - a wound brush.set("rotring", color(180, 30, 30), 3); brush.line(420, 380, 435, 400); brush.line(425, 385, 440, 405); brush.noStroke(); brush.fill(color(200, 40, 30), 100); brush.circle(430, 392, 12, 0.3); }