土曜日, 10月 02, 2010

ArrayListについて認識を改めたところ

以前の投稿(build ribbons)で、
for文のところを単にかっこいい書き方としか認識してなかったんですけど、
配列の長さがループの途中で変わるので、ああいう風にしておかないとremoveで取り除かれた分の添字が詰まった結果、参照されないオブジェクトがでてきてしまってちらつきが起こってしまいます。

こういう場合。
試しにdraw()内のfor文の初期化式をint i=0、継続条件式をi<ripples.size()、再初期化式をi++にしてみると分かります。
リファレンスにも似たような例が書いてあって、Examples>Topics>Advanced Data>ArrayListClassでも確認できます。
[Ripple.pde]
class Ripple {
float x, y, w, speed;
float age;
int intensity;
color c;
float a;
boolean finished;

Ripple(float x, float y, int intensity, color c, float speed) {
this.x = x;
this.y = y;
this.intensity = intensity;
this.c = c;
this.speed = speed;
this.age = 0;
this.a = 255-255*(age-speed)/intensity;
this.finished = false;
}

void display() {
age += speed;
a = 255-255*(age-speed)/intensity;
if(a<=5) {
finished = true;
}
stroke(c, a);
ellipse(x, y, age, age);
}

boolean finished() {
return finished;
}
}

[drawRipple.pde]
Ripple r;
ArrayList ripples;
void setup() {
size(400, 400);
background(255);
noFill();
smooth();
ripples = new ArrayList();
for(int i=0; i < 100; i++) {
ripples.add(new Ripple(random(width), random(height), (int)random(20, 80), color(0), random(0.1, 0.4)));
}
}

void draw() {
background(255);
for (int i = ripples.size()-1; i >= 0; i--) {
Ripple ripple = (Ripple)ripples.get(i);
ripple.display();
if(ripple.finished()) {
ripples.remove(ripple);
}
}
}