使用倒数计时器

时间:2016-09-19 03:19:33

标签: java class inheritance logic processing

需要一些帮助来修改此代码。我正在编写关于粒子系统的一些教程,我目前正在尝试编写一个说:

的seom逻辑

"如果此粒子系统已运行10秒钟,请停止向其中添加粒子。当最后一个粒子死亡,系统为空时,将其从系统ArrayList中删除。"

现在发生了什么:   - 计时器倒计时,粒子停止添加到粒子系统,除了它像数组列表中每个粒子系统的定时器一样。   - 添加新粒子系统时,计时器不会重置

我需要帮助:   - 在何时重置计时器,或在制作新系统时重新初始化计时器。   - 只有让计时器影响系统(而不是屏幕上的所有计时器)

// particle system
class ParticleSystem {

    ArrayList<Particle> plist;
    PVector origin; // An origin point for where particles are birthed
    float c;
    int t;
    int countdown; // 10 seconds.
    boolean end;

    ParticleSystem(float col, int num, PVector v){
        plist = new ArrayList<Particle>();
        origin = v.get();
        c = col;
        end = false;
        countdown = 10;
        t = 10;
        for(int i = 0; i < num; i++){
            plist.add(new Particle(c,origin)); 
        }
    }
    void applyForce(PVector force){
        for (Particle p : plist){
            p.applyForce(force);
        }
    }
    void run(){     
        // iterate through array of single particles backwards
        // remove single particles when they are dead. 

        t = countdown-int(millis()/1000);
        print(t);

        for (int i = plist.size()-1; i > 0; i--){
            Particle p = plist.get(i);
            p.run();
            if (p.isDead()){
                plist.remove(i);

            }
        }
        if(t > 0){
            addParticle();
        } else {
            dead();
        }

        //print(plist.size());
    }
    void addParticle(){
        //println("AP: "+r);
        float r = random(1);
        if (r<0.4) {
            plist.add(new SquareParticle(c,origin));
        }else{
            plist.add(new Particle(c,origin));
        }
    }

    boolean dead(){
        if(plist.isEmpty() || plist.size() == 1){
            t = 10;
            return true;
        }else{
            return false;
        }
    }
}

// main tab
ArrayList<ParticleSystem> systems;

PVector windRight = new PVector(0.1,0);
PVector sortaSpeed = new PVector(0,0.1);
PVector gravity = new PVector(0,0.05);

boolean wR = false;
boolean sP = false;

void setup() {
    size(640,480);
    systems = new ArrayList<ParticleSystem>();
  noStroke();
}

void draw() {
    background(0);
  if(!systems.isEmpty()){
      for (int i =0; i < systems.size(); i++){
        ParticleSystem ps = systems.get(i);
        ps.applyForce(gravity);
        ps.run();
        if(wR){
          ps.applyForce(windRight);
        }
        if(sP){
          ps.applyForce(sortaSpeed);
        }

        if(ps.dead()){
          systems.remove(ps);
        }

        //print(systems.size());
      }
  } else {
    fill(255);
    text("'w' controls wind, 'a' controls speed, 's' adds particle systems",1,height-30);
  }



}

void keyPressed() {

  if(key == 'w'){
    wR = true;
  } else if(key == 'a'){
    //print('a');
    sP = true; 
  }else{
    systems.add(new ParticleSystem(random(100,200),10,new PVector(random(10,630),10))); //random(480)
  }
}

void keyReleased(){
  if(key == 'w'){
    wR = false;
  } else if(key == 'a'){
    sP = false;
  }
}

1 个答案:

答案 0 :(得分:0)

将来,请尝试发布MCVE。现在我们无法运行您的代码,因为它包含编译器错误。尽管如此,我们并不需要看到你的整个草图,只是一个可以说明问题的小例子。

但是看看你的代码,这里有一个问题:

 for (int i =0; i < systems.size(); i++){
    ...
    if(ps.dead()){
       systems.remove(ps);
    }

使用一张纸和一支铅笔运行一个例子。我们假设您的ParticleSystem列表中有3个systems个实例,循环位于第二个实例上。然后删除第二个,将第三个移动到第二个索引。循环的下一次迭代移动到第三个索引......但现在没有任何东西!

要解决此问题,您可以向后遍历ArrayList,或者更好的是,您可以使用Iterator

从那以后,只需跟踪每个实例startTime并将其与millis()进行比较,您现在就不会这样做。< / p>

这是一个MCVE,演示了使用millis()Iterator在10秒后杀死Particle个实例:

import java.util.Iterator;

ArrayList<Particle> particles = new ArrayList<Particle>();

void setup() {
  size(500, 500);
}

void draw() {

  background(0);

  Iterator<Particle> particleIterator = particles.iterator();
  while (particleIterator.hasNext()) {
    Particle p = particleIterator.next();
    p.draw();
    if (p.isDead()) {
      particleIterator.remove();
    }
  }
}

void mousePressed() {
  particles.add(new Particle(mouseX, mouseY));
}

class Particle {
  int startTime;
  float x;
  float y;

  public Particle(float x, float y) {
    startTime = millis();
    this.x = x;
    this.y = y;
  }

  void draw() {
    x += random(-2, 2);
    y += random(-2, 2);

    ellipse(x, y, 10, 10);
  }

  boolean isDead() {
    return millis() > startTime + 10*1000;
  }
}

请注意,您必须使用此逻辑两次:一次用于您的单个粒子,另一次用于粒子系统本身。但逻辑是相同的:记录开始时间,然后将其与millis()进行比较,并使用Iterator删除超时的内容。

另请注意,Iterator特定于Java模式。如果要部署为JavaScript,则可能需要使用向后循环方法。