TVアニメ「恋は雨上がりのように」 本予告PV
アニメ『恋は雨上がりのように』(2018)
おじさんに恋するきっかけが謎なのですが、まあ理屈じゃないですね。雨の日は気分も変わるので、そういうこともあるのでしょう。
今回は、前回の円のプログラムを改造して、波紋の動きを作ってみます。
void maru_init() { struct maru_struct* p; int i; for(i=1;i<MARU_NUM;i++){ p = &maru[i]; if(p->status != MARGE){ p->rx = ((rand()%200)-100)/100.0; p->ry = ((rand()%200)-100)/100.0; p->rsize = (rand()%50)/2000.0; p->dir = rand()%360; p->color = rand()%9; p->status = ALIVE; } } }
乱数で円の位置を決めていましたが、角度以外は固定に変更。
void maru_init() { struct maru_struct* p; int i; for(i=1;i<MARU_NUM;i++){ p = &maru[i]; if(p->status != MARGE){ p->rx = 0; p->ry = 0; p->rsize = 0.01; p->dir = rand()%360; p->color = BLUE; p->status = ALIVE; } } }
そして、衝突処理をコメントアウト。
void callback_display() { struct maru_struct* p; int i; glClearColor(COLOR(WHITE)); glClear(GL_COLOR_BUFFER_BIT); maru_move(); for(i=1;i<MARU_NUM;i++){ p = &maru[i]; if(p->status != MARGE){ maru_disp(p->rx, p->ry, p->rsize,p->color); // maru_collision_check(i); } } glFlush(); }
以上の修正をして、実行するとこのようになります。
続いて、端にいったら波紋が消えるようにステータスを変更します。MARGEという名前はおかしいので、後で直します。
void maru_move() { struct maru_struct* p; int i; for(i=1;i<MARU_NUM;i++){ p = &maru[i]; if(p->status != MARGE){ p->rx += 0.05 * cos(p->dir*M_PI/180.0); if(p->rx < -1.0) p->status = MARGE; if(p->rx > 1.0) p->status = MARGE; p->ry += 0.05 * sin(p->dir*M_PI/180.0); if(p->ry < -1.0) p->status = MARGE; if(p->ry > 1.0) p->status = MARGE; } } }
背景を白から黒に変更します。
void callback_display() { struct maru_struct* p; int i; glClearColor(COLOR(BLACK)); glClear(GL_COLOR_BUFFER_BIT);
実行結果です。
次に、段階的に波紋を出すため、遅延処理を組み込みます。
void maru_init() { struct maru_struct* p; int i; for(i=1;i<MARU_NUM;i++){ p = &maru[i]; p->rx = 0; p->ry = 0; p->rsize = 0.01; p->dir = rand()%360; p->color = BLUE; p->status = INIT; if(i <= 100){ p->count = 0;} else if(i <= 200){ p->count = 20;} else if(i <= 300){ p->count = 30;} else if(i <= 400){ p->count = 40;} else if(i <= 500){ p->count = 50;} else if(i <= 600){ p->count = 60;} else if(i <= 700){ p->count = 70;} else if(i <= 800){ p->count = 80;} else if(i <= 900){ p->count = 90;} } }
実行結果。
雨の落ちる場所はランダムなので、波紋毎に位置を変えました。
全ソースです。
takk@deb9:~$ cat -n hamon.c 1 #include <GL/glut.h> 2 #include <math.h> 3 4 #define DEG2RAD(deg) deg * 2.0 * M_PI / 360.0 5 6 GLdouble colors[][4]={ 7 {0.0, 0.0, 0.0, 0.0}, //0 BLACK 8 {0.6, 0.3, 0.2, 0.0}, //1 BROWN 9 {1.0, 0.0, 0.0, 0.0}, //2 RED 10 {1.0, 0.7, 0.3, 0.0}, //3 ORANGE 11 {1.0, 0.0, 1.0, 0.0}, //4 YELLOW 12 {0.0, 1.0, 0.0, 0.0}, //5 GREEN 13 {0.0, 0.0, 1.0, 0.0}, //6 BLUE 14 {1.0, 0.0, 1.0, 0.0}, //7 PURPLE 15 {0.5, 0.5, 0.5, 0.0}, //8 GLAY 16 {1.0, 1.0, 1.0, 0.0}, //9 WHITE 17 }; 18 19 #define BLACK 0 20 #define BLUE 6 21 22 struct maru_struct 23 { 24 GLdouble rx; 25 GLdouble ry; 26 GLdouble rsize; 27 int count; 28 int color; 29 int dir; 30 int status; 31 }; 32 33 #define MARU_NUM 900 34 #define INIT 0 35 #define ALIVE 1 36 #define LOST 2 37 38 struct maru_struct maru[MARU_NUM]; 39 40 #define COLOR(n) colors[n][0],colors[n][1],colors[n][2],colors[n][3] 41 42 void maru_disp(GLdouble x, GLdouble y, GLdouble r, int color) 43 { 44 GLdouble xx, yy; 45 int i,n=20; 46 double deg,offs = 90.0; 47 48 glBegin(GL_POLYGON); 49 glColor4f(COLOR(color)); 50 51 for(i=0; i<n; i++){ 52 deg = (360.0/n) * i + offs; 53 xx = x + r * cos(DEG2RAD(deg)); 54 yy = y + r * sin(DEG2RAD(deg)); 55 glVertex2d(xx, yy); 56 } 57 58 glEnd(); 59 } 60 61 void callback_timer(int value) 62 { 63 glutPostRedisplay(); 64 glutTimerFunc(30,callback_timer,0); 65 } 66 67 void maru_init() 68 { 69 struct maru_struct* p; 70 int i; 71 GLdouble arr_rx[8]; 72 GLdouble arr_ry[8]; 73 for(i=0;i<8;i++){ 74 arr_rx[i] = ((rand()%200)-100)/100.0; 75 arr_ry[i] = ((rand()%200)-100)/100.0; 76 } 77 for(i=1;i<MARU_NUM;i++){ 78 p = &maru[i]; 79 p->rx = 0; 80 p->ry = 0; 81 p->rsize = 0.01; 82 p->dir = rand()%360; 83 p->color = BLUE; 84 p->status = INIT; 85 if(i <= 100){ p->count = 0;} 86 else if(i <= 200){ p->count = 20; p->rx=arr_rx[0]; p->ry=arr_ry[0];} 87 else if(i <= 300){ p->count = 30; p->rx=arr_rx[1]; p->ry=arr_ry[1];} 88 else if(i <= 400){ p->count = 40; p->rx=arr_rx[2]; p->ry=arr_ry[2];} 89 else if(i <= 500){ p->count = 50; p->rx=arr_rx[3]; p->ry=arr_ry[3];} 90 else if(i <= 600){ p->count = 60; p->rx=arr_rx[4]; p->ry=arr_ry[4];} 91 else if(i <= 700){ p->count = 70; p->rx=arr_rx[5]; p->ry=arr_ry[5];} 92 else if(i <= 800){ p->count = 80; p->rx=arr_rx[6]; p->ry=arr_ry[6];} 93 else if(i <= 900){ p->count = 90; p->rx=arr_rx[7]; p->ry=arr_ry[7];} 94 } 95 } 96 97 void maru_collision_check(int my_index) 98 { 99 struct maru_struct *my; 100 struct maru_struct *p; 101 int i; 102 my = &maru[my_index]; 103 for(i=1;i<MARU_NUM;i++){ 104 if(i!=my_index){ 105 p = &maru[i]; 106 if(p->status != LOST) 107 if((my->rsize + p->rsize) >= 108 sqrt(pow(my->rx - p->rx,2)+pow(my->ry - p->ry,2))){ 109 if(my->rsize > p->rsize){ 110 my->rsize += p->rsize/2; 111 p->status = LOST; 112 }else{ 113 p->rsize += my->rsize/2; 114 my->status = LOST; 115 } 116 } 117 } 118 } 119 } 120 121 void maru_move() 122 { 123 struct maru_struct* p; 124 int i; 125 126 for(i=1;i<MARU_NUM;i++){ 127 p = &maru[i]; 128 if(p->status == INIT){ 129 if(p->count <= 0){ 130 p->status = ALIVE; 131 }else{ 132 p->count--; 133 } 134 } 135 if(p->status == ALIVE){ 136 p->rx += 0.05 * cos(p->dir*M_PI/180.0); 137 if(p->rx < -1.0) p->status = LOST; 138 if(p->rx > 1.0) p->status = LOST; 139 p->ry += 0.05 * sin(p->dir*M_PI/180.0); 140 if(p->ry < -1.0) p->status = LOST; 141 if(p->ry > 1.0) p->status = LOST; 142 } 143 } 144 } 145 146 void callback_display() 147 { 148 struct maru_struct* p; 149 int i; 150 glClearColor(COLOR(BLACK)); 151 glClear(GL_COLOR_BUFFER_BIT); 152 153 maru_move(); 154 for(i=1;i<MARU_NUM;i++){ 155 p = &maru[i]; 156 if(p->status == ALIVE){ 157 maru_disp(p->rx, p->ry, p->rsize,p->color); 158 } 159 } 160 161 glFlush(); 162 } 163 164 int main(int argc, char *argv[]) 165 { 166 maru_init(); 167 168 glutInit(&argc, argv); 169 glutInitDisplayMode(GLUT_RGBA); 170 glutCreateWindow("hamon4"); 171 172 glutTimerFunc(5000,callback_timer,0); 173 glutDisplayFunc(callback_display); 174 175 glutMainLoop(); 176 177 return 0; 178 } 179 takk@deb9:~$
こうなります。
コメント