質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Processing

Processingは、オープンソースプロジェクトによるCGのためのプログラミング言語です。Javaをベースにしており、グラフィック機能に特化しています。イメージの生成やアニメーションなど、視覚的なフィードバックを簡単に得ることが可能です。

Q&A

解決済

1回答

822閲覧

Tree関数を競合せずに追加する方法

msw

総合スコア9

Processing

Processingは、オープンソースプロジェクトによるCGのためのプログラミング言語です。Javaをベースにしており、グラフィック機能に特化しています。イメージの生成やアニメーションなど、視覚的なフィードバックを簡単に得ることが可能です。

1グッド

0クリップ

投稿2019/11/26 15:12

前提・実現したいこと

・下記コードに再帰を使って木を描く為のTree関数を追加したいです。
・ソースコードは長いですが、分かり易くする為に全部入れました。申し訳ございません。
問題の部分は最後の方にあるTree関数の所です。宜しくお願い致します。

発生している問題・エラーメッセージ

setup()内にTree関数を呼び出すと、一度だけ描画されるだけで後は消えてしまいます。 また、draw()内で呼び出すと、当然ですが何度も線が描画されて目がチカチカとしてしまいました。 Note内で毎秒画面の更新を行っているせいだと思うのですが、一度描画したものに対して以後他のプログラムの影響を受けないようにする事は出来ませんよね? どうにか上手く追加する方法はないでしょうか?

該当のソースコード

processing

1import ddf.minim.*; 2import ddf.minim.analysis.*; 3import ddf.minim.effects.*; 4import ddf.minim.signals.*; 5import ddf.minim.spi.*; 6import ddf.minim.ugens.*; 7 8Minim minim; 9//AudioInput in; 10AudioPlayer player; 11//float volumeIn; 12int buffersize = 512; 13 14class Note { 15 final float x; 16 final float y; 17 final float w; 18 final float h; 19 20 final float r; 21 final float r2; 22 23 final color col;//HSB, alpha 24 25 boolean isAlive = true; 26 27 Note(final float x, final float y, final float playerIn) { 28 this.x = random(700, 1200); 29 this.y = random(400, 500); 30 this.w = playerIn/2; 31 this.h = playerIn/2; 32 33 this.r = this.w / 2; 34 this.r2 = this.r * this.r; 35 36 this.col = color(random(360), 100, 100, 50); 37 } 38 39 void draw() { 40 colorMode(HSB, 360, 100, 100, 100); 41 noStroke(); 42 fill(col); 43 ellipse(x, y, w, h); 44 } 45 46 void update() { 47 } 48 49 boolean isExpired() { 50 return !isAlive; 51 } 52 53 void toggle() { 54 isAlive = !isAlive; 55 } 56} 57 58abstract class Effect { 59 protected float time; 60 protected float t = 0; 61 final float dt = 1.0; 62 63 Effect() { 64 } 65 66 abstract void draw(); 67 68 abstract void update(); 69 70 void dec() { 71 time -= dt; 72 t += dt; 73 } 74 75 boolean isExpired() { 76 return time < 0; 77 } 78} 79 80abstract class MultiEffect extends Effect { 81 ArrayList<Effect> chidren = new ArrayList<Effect>(); 82 83 MultiEffect() { 84 } 85 86 @Override 87 void draw() { 88 for (Effect eff : chidren) { 89 eff.draw(); 90 } 91 } 92 93 @Override 94 void update() { 95 for (Effect eff : chidren) { 96 eff.update(); 97 } 98 } 99 100 @Override 101 boolean isExpired() { 102 for (Effect eff : chidren) { 103 if (!eff.isExpired()) return false; 104 } 105 return true; 106 } 107} 108 109class Bakuhatu extends Effect { 110 final float x; 111 final float y; 112 float r; 113 float dr = 1; 114 final float ddr = 0.5; 115 //color col; 116 117 final int R, G, B; 118 int alpha; 119 int da = 0; 120 final int dda = 1; 121 122 Bakuhatu(final float x, final float y, final float r, final color col, final float time) { 123 this.x = x; 124 this.y = y; 125 this.r = r; 126 127 final int mask = 0xFF; 128 alpha = (col>>24) & mask; 129 alpha /= 2; 130 R = (col>>16) & mask; 131 G = (col>>8) & mask; 132 B = col & mask; 133 134 this.time = time; 135 } 136 137 @Override 138 void draw() { 139 noStroke(); 140 //fill(col); 141 colorMode(RGB); 142 fill(R, G, B, alpha); 143 ellipse(x, y, 2*r, 2*r); 144 } 145 146 @Override 147 void update() { 148 dec(); 149 r += dr; 150 dr += ddr; 151 152 alpha -= da; 153 da += dda; 154 } 155} 156 157final float g = 0.2; 158 159class Hinoko extends Effect { 160 float x; 161 float y; 162 final float r = 2; 163 final float v0 = 5; 164 float vx; 165 float vy; 166 167 final float theta; 168 169 final color col; 170 int R, G, B; 171 int alpha; 172 float da = 1; 173 final float dda = 0.05; 174 175 //final float start; 176 177 float drx, dry; 178 float ddrx, ddry; 179 180 Hinoko(final float x, final float y, final float r, final color col, final float theta, final float time) { 181 182 this.x = x; 183 this.y = y; 184 185 this.vx = v0 * cos(theta); 186 this.vy = v0 * sin(theta); 187 188 this.col = col; 189 //this.col = color(h,s,b,alpha); 190 191 final int mask = 0xFF; 192 alpha = (col>>24) & mask; 193 //alpha /= 2; 194 R = (col>>16) & mask; 195 G = (col>>8) & mask; 196 B = col & mask; 197 198 this.drx = 0.5; 199 this.dry = 0.05; 200 this.ddrx = 0.5; 201 this.ddry = 0.05; 202 203 this.time = time; 204 //this.start = time; 205 this.theta = theta; 206 } 207 208 @Override 209 void draw() { 210 noStroke(); 211 colorMode(RGB); 212 fill(R, G, B, alpha); 213 //fill(col); 214 ellipse(x, y, r, r); 215 } 216 217 @Override 218 void update() { 219 dec(); 220 221 alpha -= da; 222 da += dda; 223 224 x += vx; 225 y += vy; 226 y += g*t; 227 228 drx += ddrx; 229 dry += ddry; 230 } 231} 232 233class Hanabi extends MultiEffect { 234 Hanabi(final float x, final float y, final float r, final color col) { 235 super(); 236 237 final float timeB = 30; 238 chidren.add(new Bakuhatu(x, y, r, col, timeB)); 239 240 final float timeH = 50; 241 final int max = 32; 242 final float dtheta = TWO_PI / max; 243 for (int i=0; i<max; i++) { 244 chidren.add(new Hinoko(x, y, r, col, dtheta*i, timeH)); 245 } 246 } 247} 248 249class Effects extends ArrayList<Effect> { 250 Effects() { 251 //do nothing 252 } 253 254 void add(Effects temp) { 255 this.addAll(temp); 256 } 257 258 void draw() { 259 for (Effect eff : this) { 260 eff.draw(); 261 } 262 } 263 264 void update() { 265 ArrayList<Effect> temp = new ArrayList<Effect>(); 266 for (Effect eff : this) { 267 eff.update(); 268 if (!eff.isExpired()) temp.add(eff); 269 } 270 this.clear(); 271 this.addAll(temp); 272 } 273} 274 275class NoteController { 276 ArrayList<Note> notes = new ArrayList<Note>(); 277 278 final float margin = 100; 279 final float xmin = margin; 280 final float xmax = width-margin; 281 final float ymin = margin; 282 final float ymax = height-margin; 283 284 NoteController() { 285 // 286 } 287 //円の制御 288 void add(final float playerIn) { 289 if (notes.size() > 100) return;//check 290 if (playerIn < 20) return; 291 if (frameCount % 40 != 0) return; 292 //if (frameCount % (int)random(10, 40) != 0) return; 293 294 final float x = random(xmin, xmax); 295 final float y = random(ymin, ymax); 296 notes.add(new Note(x, y, playerIn)); 297 } 298 299 void draw() { 300 for (Note note : notes) { 301 note.draw(); 302 } 303 } 304 305 ArrayList<Note> update() { 306 ArrayList<Note> next = new ArrayList<Note>(); 307 ArrayList<Note> del = new ArrayList<Note>(); 308 for (Note note : notes) { 309 note.update(); 310 if (note.isExpired()) { 311 del.add(note); 312 } else { 313 next.add(note); 314 } 315 } 316 notes.clear(); 317 notes.addAll(next); 318 return del; 319 } 320 321 //真偽を使って判断 322 boolean isHit(final Note note) { 323 return true; 324 } 325 //全指定 326 void mouseClicked() { 327 for (Note note : notes) { 328 note.toggle(); 329 } 330 } 331} 332 333class Converter { 334 Effects makeHanabis(ArrayList<Note> notes) { 335 Effects temp = new Effects(); 336 for (Note note : notes) { 337 temp.add(makeHanabi(note)); 338 } 339 return temp; 340 } 341 342 Hanabi makeHanabi(Note note) { 343 Hanabi temp = new Hanabi(note.x, note.y, note.r, note.col); 344 return temp; 345 } 346} 347 348NoteController controller; 349Effects effects; 350Converter converter; 351 352void setup() { 353 fullScreen(); 354 frameRate(60); 355 356 /*Tree(30, width/2, height, PI, width/8); 357 fill(#8B7250); 358 rect(0, 1030, 2000, 50); */ 359 360 colorMode(HSB, 360, 100, 100, 100); 361 controller = new NoteController(); 362 effects = new Effects(); 363 converter = new Converter(); 364 365 minim = new Minim(this); 366 //in = minim.getLineIn(Minim.STEREO,buffersize); 367 final String fn = "Mountain.mp3"; 368 player = minim.loadFile(fn); 369 player.loop(); 370} 371 372void draw() { 373 background(200); 374 375 Tree(30, width/2, height, PI, width/8); 376 noStroke(); 377 fill(#8B7250); 378 rect(0, 1030, 2000, 50); 379 380 // volumeIn = in.mix.level()*200; 381 final float playerIn = player.mix.level()*200; 382 controller.add(playerIn); 383 controller.draw(); 384 ArrayList<Note> temp = controller.update(); 385 386 effects.add(converter.makeHanabis(temp)); 387 effects.draw(); 388 effects.update(); 389} 390 391//木の生成 392void Tree(float strokeWeight, float x, float y, float rotate, float length) { 393 pushMatrix(); //座標を一時保存 394 translate(x, y); //座標移動 395 rotate(rotate); //座標回転 396 strokeWeight(strokeWeight); //線の輪郭線の太さ 397 stroke(50, 0, 0); //線の色 398 line(0, 0, 0, length); //線の描画,配列の長さ 399 popMatrix(); //変更した座標を元に戻す 400 if (strokeWeight<2)return; 401 if (random(0, 4)>3 && strokeWeight<3)return; 402 Tree(strokeWeight*2/3, x-sin(rotate)*length, y+cos(rotate)*length, rotate-PI/10, length*2/3); 403 Tree(strokeWeight*2/3, x-sin(rotate)*length, y+cos(rotate)*length, rotate+PI/10, length*2/3); 404} 405 406void stop() { 407 minim.stop(); 408 super.stop(); 409} 410 411void mouseClicked() { 412 controller.mouseClicked(); 413} 414

試したこと

setup()とdraw()にそれぞれTree関数を入れ、それぞれの結果を確認した。
Tree関数のみ独立させられないか試行錯誤を重ねた。

補足情報(FW/ツールのバージョンなど)

Processing3.5.3

TN8001👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

描画内でランダム要素があるとフレームごとに描く内容が変わってしまい、ちらつくことになります。

Processing

1if (random(0, 4) > 3 && strokeWeight < 3) return;

そこで、一見規則性はなさそうに見えて、でも毎回同じ値に決定できるものに変えます。

Processing

1if (x % 5 > 3 && strokeWeight < 3) return;

適当なんでほかの数値や計算でもいいです。

投稿2019/11/26 16:23

編集2023/08/09 09:42
TN8001

総合スコア9317

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

msw

2019/11/28 08:00

>描画内でランダム要素があるとフレームごとに描く内容が変わってしまう なるほど!確かに回答のプログラムに変更した所、ちらつきませんでした。 とても丁寧なご回答ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問