code / nuke

Lines646 C608 make30 Markdown8
(105 lines)
1 /**
2 * ASCII explosion from squeamish ossifrage at:
3 * https://codegolf.stackexchange.com/questions/24462/display-the-explosion-of-a-star-in-ascii-art/24554#24554
4 */
5 #include "colors.h"
6 #include <curses.h>
7 #include <math.h>
8 #include <stdlib.h>
10 #define NUM_BLOBS 800
11 #define PERSPECTIVE 50.0
13 typedef struct {
14 double x,y,z;
15 } spaceblob_t;
17 static double prng() {
18 static long long s=1;
19 s = s * 1488248101 + 981577151;
20 return ((s % 65536) - 32768) / 32768.0;
23 void draw_explosion(int i, int midx, int midy) {
24 static spaceblob_t blobs[NUM_BLOBS];
25 int rows,cols;
26 getmaxyx(stdscr,rows,cols);
27 int maxx,minx,maxy,miny;
28 minx = -midx;
29 maxx = cols+minx-1;
30 miny = -midy;
31 maxy = rows+miny-1;
33 if (i == 0) {
34 /* Generate random blob coordinates */
35 for (int i=0; i<NUM_BLOBS; i++) {
36 double bx,by,bz,br;
37 bx = prng();
38 by = prng();
39 bz = prng();
40 br = sqrt(bx*bx + by*by + bz*bz);
41 blobs[i].x = (bx / br) * (1.3 + 0.2 * prng());
42 blobs[i].y = (0.5 * by / br) * (1.3 + 0.2 * prng());;
43 blobs[i].z = (bz / br) * (1.3 + 0.2 * prng());;
45 /* Flash on the first frame */
46 bkgd(COLOR_PAIR(WHITE_BG));
47 erase();
48 return;
51 bkgd(0);
52 chtype line[cols+1];
53 for (int y=miny; y<=maxy; y++) {
54 int row = y+midy;
55 for (int x=minx; x<=maxx; x++) {
56 int col = x+midx;
57 /* Show expanding star in next 7 frames */
58 if (i<8) {
59 double r = sqrt(x*x + 4*y*y);
60 if (r < i*2)
61 mvaddch(row,col,'@');
62 continue;
65 /* Otherwise show blast wave */
66 double r = sqrt(x*x + 4*y*y) * (0.5 + (prng()/3.0)*cos(16.*atan2(y*2.+0.01,x+0.01))*.3);
67 int v = i - r - 7;
68 if (v<0) {
69 if (i<19) {
70 int attr = 0;//color_ramp1[i-8];
71 line[col] = "%@W#H=+~-:."[i-8] | attr;
72 } else {
73 line[col] = ' ';
75 } else if (v<20) {
76 int attr = 0;//color_ramp2[v];
77 line[col] = " .:!HIOMW#%$&@08O=+-"[v] | attr;
78 } else {
79 line[col] = ' ';
82 if (i >= 8) {
83 line[cols+1] = '\0';
84 mvaddchstr(row,0,line);
88 /* Add blobs with perspective effect */
89 if (i>6) {
90 int i0 = i-6;
91 for (int j=0; j<NUM_BLOBS; j++) {
92 double bx = blobs[j].x * i0;
93 double by = blobs[j].y * i0;
94 double bz = blobs[j].z * i0;
95 if (bz<5-PERSPECTIVE || bz>PERSPECTIVE) continue;
96 int x = midx + bx * PERSPECTIVE / (bz+PERSPECTIVE);
97 int y = midy + by * PERSPECTIVE / (bz+PERSPECTIVE);
98 if (x>=0 && x<cols && y>=0 && y<rows) {
99 int row = y, col = x;
100 mvaddch(row,col,(bz>40) ? '.' : (bz>-20) ? 'o' : '@');