JoC #29: Viewer questions: timers

      Time is an illusion. Lunchtime doubly so.
            — Douglas Adams

We are starting a new, probably more or less regular, thing today: answering viewer questions.

In the first of the Q&A episodes, I am talking about timers: How to arrange something to happen after a specific time delay. This principle is generally useful for many games and simulations. We also get  bit more practice with int variables.

Download video

Concepts discussedtime delay, variables, counting


17 thoughts on “JoC #29: Viewer questions: timers

  1. Hi,
    I get no errors, but after eating a Ladybird no new ones are created.
    It worked fine before I used a timer.

  2. One more question, I have made a little scenario were if a zombie overlaps with a human the human is replaced with a zombie, but the first handful of humans just get eaten and then the rest are turned, why would that be?

    void eatWhenOverHuman()
    {
    if (canSee(Human.class))
    {
    eat(Human.class);
    getWorld().addObject(new Zombie(), getX(), getY());
    }
    }

  3. Hi Sir

    Thank you so much for your series and Greenfoot! It is helping me so much with my studies as a Java developer. Awesome stuff!

  4. @William I don’t know. Your code looks fine. It’s hard to say without seeing more of the code. If you still need help, post your code on the Greenfoot site and point us to it.

  5. Hi Michael, I have been trying to fix an animation using this timer to delay the switch between two images. In the Crab World scenario the code:

    public void animateCrab()
    {
    if (getImage() == image1 )
    {
    setImage(imgae2);
    }
    else
    {
    setImage(image1);
    }
    }

    doesn’t work with other kinds of movement since the switch is almost instantaneous, and almost appears to flicker. So in an attempt to delay the switch I applied a timer like the one used in this video but it doesn’t work very well. I was wondering if you had a better solution. Thanks for any help.

  6. Using a timer is the best solution. You could initialise a counter to, say 6, and then count down, and only switch the image when the counter is 0:


    private int count = 6;
    ...

    public void animateCrab()
    {
    count--;
    if (count == 0) {
    if (getImage() == image1 )
    {
    setImage(imgae2);
    }
    else
    {
    setImage(image1);
    }
    count = 6;
    }
    }

  7. Hello! : ) I corrected the bug. First I added a new variable:

    private int bugsEaten;

    Then i modified the newBug( ) and checkNewBug( ) methods as the following:

    /**
    * Set up the frame delay for a new bug.
    */
    public void newBug()
    {
    bugDelay = bugDelay + BUG_DELAY;
    bugsEaten++;
    }

    /**
    * Check if a new bug is to be added right now.
    */
    public void checkNewBug()
    {
    if (bugsEaten > 0) {
    if (bugDelay > (bugsEaten-1)*BUG_DELAY) {
    bugDelay–;
    if (bugDelay == (bugsEaten-1)*BUG_DELAY) {
    createNewBug();
    bugsEaten–;
    }
    }
    }
    }

  8. What happens if you eat two bugs in rapid succession? Say you eat a bug and the timer only gets down to 50 and you eat a second bug… does the timer reset to 100 and now there is one less bug in the world?

  9. Another and better solution (i guess):

    First i added: private int bugDelayArray[ ] = new int[2]; instead private int bugDelay;

    Then modified the newBug( ) and checkNewBug( ) as:

    /**
    * Set up the frame delay for a new bug.
    */
    public void newBug()
    {
    bugDelayArray[bugsEaten] = BUG_DELAY;
    bugsEaten++;
    }

    /**
    * Check if a new bug is to be added right now.
    */
    public void checkNewBug()
    {
    int i = 0;
    while ( i 0) {
    bugDelayArray[i]–;
    if (bugDelayArray[i] == 0) {
    createNewBug();
    bugDelayArray[i]=bugDelayArray[i+1];
    bugsEaten–;
    }
    }
    i++;
    }
    }

  10. The last one fails when i use more than 2 bugs. The next may succeed for until 10 bugs:

    private int bugDelayArray[] = new int[10];

    /**
    * Set up the frame delay for a new bug.
    */
    public void newBug()
    {
    bugDelayArray[bugsEaten] = BUG_DELAY;
    bugsEaten++;
    }

    /**
    * Check if a new bug is to be added right now.
    */
    public void checkNewBug()
    {
    int i = 0;
    while ( i 0) {
    bugDelayArray[i]–;
    if (bugDelayArray[i] == 0) {
    createNewBug();
    int j = 0;
    while ( j < bugsEaten) {
    bugDelayArray[j]=bugDelayArray[j+1];
    j++;
    }
    bugsEaten–;
    }
    }
    i++;
    }
    }

Leave a Reply

Your email address will not be published. Required fields are marked *