I'm making a game and i have timer loop and in the timer i have some features which allow flowers to spawn. Once the flowers hit the age of lets say 300 they turn into deadflwoers and the image changes, but once they hit the age of 400 then i want them to disappear of the scene but i dont know where i'm going wrong in order to do so.

AnimationTimer timer = new AnimationTimer() {       
    ArrayList<GameObject>DeadFlowers = new ArrayList<GameObject>();
    @Override
    public void handle(long now) {
        // TODO Auto-generated method stub  
        gc.drawImage(img1, 0, 0, canvas.getWidth(), canvas.getHeight());

        if(count++>60) {
            flowers.add(new SpawnFlowers(gc, rnd.nextInt(600), rnd.nextInt(550)));
            count = 1;
        }

        for(GameObject obj : Hive) {
            obj.update();
        }

        for(GameObject obj : flowers) { 
            ((SpawnFlowers)obj).grow();

        }

        for(GameObject obj : DeadFlowers) {
            ((SpawnFlowers)obj).removeFlowers();
            DeadFlowers.remove(obj);
        }

        for(GameObject obj : characterList) {
            obj.update();
        }
    }
};

my Flowers class:

class SpawnFlowers extends GameObject implements FlowerIF {

  FlowerIF delegate;
  int age= 0;

  public SpawnFlowers(GraphicsContext gc, double x, double y) {
    super(gc, x, y);
    img = new Image("/res/rose.png");
    update();
    delegate = this;
    // TODO Auto-generated constructor stub
  }

public void grow() {
    age+=1;
    if(age == 300)
        delegate = new DeadFlower(gc, x, y);
    delegate.update();
}

public void removeFlowers() {
    if (age == 400) {
        delegate.update();
    }
}
}

3 Answers

0
shani klein On

If I'm not wrong, after your flowers is dead it doesn't seems like you change there age So why should the get to age of 400 ?

1
GhostCat On

Most like, your actual problem is here:

 for(GameObject obj : DeadFlowers) {
   ((SpawnFlowers)obj).removeFlowers();
   DeadFlowers.remove(obj);
 } 

You turned your flowers into a DeadFlower when it has age 300. I assume that you also add that new DeadFlower object to your list of dead flowers. In the next game loop, the above code calls checks: is the age 400, if so ... do nothing. Next, your code will removes that dead flower object from the dead flower list!

In other words: when the flower gets to 300, you turn it into a dead flower. Right afterwards, you remove that dead flower from the list of dead flowers. Thus that list will always be emptied immediately.

Long story short: your whole logic is quite screwed up. You have to step back and clearly outline (for yourself first) what buckets you have, and how you want to process them. As in:

if (age == 400) {
    delegate.update();
}

This code does nothing specific for that 400 case. Compare it to the 300 case. There you create a new object at least. Something changes. But in the 400 case, well, you update. What is that supposed to do?!

Beyond that: it seems you are adding your dead flowers to that list implicitly, within the constructor of that class. Super bad idea. The class that holds that list of dead flowers should be the only place where new flowers are added to that list, or removed. I assume your DeadFlowers class knows that list, and adds new instances to that list. That is dead wrong.

And another minor thing: ArrayList<GameObject>DeadFlowers = new ArrayList<GameObject>(); should better be List<GameObject> deadFlowers = new ArrayList<>(); . There is no need to express the specific type (ArrayList) on the left hand side, there is no need to use the generic type on the right hand side. And of course, DeadFlowers violates java naming conventions (should start lower case).

2
cmoetzing On

You have a list DeadFlowers but you never add() something.

Therefore your loop

for(GameObject obj : DeadFlowers) {
    ((SpawnFlowers)obj).removeFlowers();
    DeadFlowers.remove(obj);
}

will never run.

You could for example do

public void grow() {
    age+=1;
    if(age == 300) {
        delegate = new DeadFlower(gc, x, y);
        DeadFlowers.add(delegate);
    }
    delegate.update();
}

I am not really sure what you want to achieve with this method. You probably want to remove the condition if that is just code to repaint.

public void removeFlowers() {
    if (age == 400) {
        delegate.update();
    }
}