【问题标题】:Killing particle systems in processing with a countdown timer使用倒数计时器杀死正在处理的粒子系统
【发布时间】:2016-09-19 03:19:32
【问题描述】:

需要一些帮助来修改此代码。我正在学习一些关于粒子系统的教程,我目前正在尝试编写 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;
  }
}

【问题讨论】:

    标签: java class inheritance logic processing


    【解决方案1】:

    以后,请尝试发帖MCVE。现在我们无法运行您的代码,因为它包含编译器错误。无论如何,我们不需要查看您的整个草图,只需一个小示例即可。

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

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

    使用一张纸和一支铅笔运行一个示例。假设您的systems 列表中有3 个ParticleSystem 实例,循环在第二个。然后删除第二个,将第三个移到第二个索引中。循环的下一次迭代移动到第三个索引...但现在那里什么都没有!

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

    从那里只需跟踪每个实例的 startTime 并将其与 millis() 进行比较,您现在没有这样做。

    这是一个 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,您可能希望使用反向循环方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-27
      • 2023-03-13
      • 2013-04-13
      相关资源
      最近更新 更多