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:~$
こうなります。


コメント