2016-09-19 48 views
0

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

回答

0

在未来,请尝试发布的MCVE。现在我们无法运行您的代码,因为它包含编译器错误。无论如何,我们不需要看到你的整个草图,只是一个小例子而已。

但看你的代码,这里有一个问题:通过使用一张纸和一支铅笔为例

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

运行。假设您的systems列表中有3 ParticleSystem个实例,并且该循环位于第二个循环中。然后删除第二个,将第三个移到第二个索引中。循环的下一个循环移动到第三个索引...但现在没有什么!

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

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

下面是演示如何使用millis()Iterator 10秒后杀死Particle实例的MCVE:

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的形式进行部署,您可能需要使用反向循环方法。