需要一些帮助来修改此代码。我正在编写关于粒子系统的一些教程,我目前正在尝试编写一个说:
的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 :(得分: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,则可能需要使用向后循环方法。