This site requires JavaScript, please enable it in your browser!
Greenfoot back
nccb
nccb wrote ...

2023/11/3

Greenfoot 3.8.1 released

nccb nccb

2023/11/3

#
Greenfoot 3.8.1 is now out. This has our first new API method in a while. We've added a sleepFor method to Actor. This method is for use when you don't want an Actor to act at all for a little while. You might use it for stunning enemies for a while, or to have some actor only do something (e.g. spawn another actor) every N act() cycles. You can use it to sleep indefinitely if you want using sleepFor(-1); other objects can wake up an Actor by calling sleepFor(0) which replaces the previous instruction and wakes the actor up. All of this is already possible if you code it yourself using a variable to act as a counter (and it won't replace only doing parts of the act every N cycles, such as only firing a bullet every 20 cycles). But we thought it might be useful to have an easy way to do this built in to Greenfoot. It will work on Greenfoot 3.8.1 and the website, but it won't work if you use it, then load the project into an older Greenfoot.
lehrerfreund lehrerfreund

2023/11/4

#
That's great, thanks for implementing this new method! Everything with delay becomes much easier, especially for beginners and intermediates, which might be confused by additional structures and variables (like the act-counter). E.g. if you have an Actor exploding and you want to have its image replaced by the image of an explosion before he vanishes, you just go like
public void exploding() {
  this.setImage("explosion.png");
  this.sleepFor(20);
  this.getWorld().removeObject(this);
}
Is it possible to check if an Actor is sleeping? This could be very useful also.
nccb nccb

2023/11/6

#
Unfortunately, that code won't quite work; when you call sleepFor, you still finish the execution of the current code. (This is because all the act() methods run on a single thread; I guess we could use an exception to exit the method but it's messy and not the design we've gone for.) You'd need something more like:
private boolean exploded = false;

public void act()
{
    if (exploded)
    {
        getWorld().removeObject(this);
        return;
    }
}

public void exploding()
{
    setImage("explosion.png");
    exploded = true;
    sleepFor(20);
}
I guess one alternative is to have an explosion actor like this:
public class Explosion extends Actor
{
    public Explosion(int howManyCycles)
    {
        this.sleepFor(howManyCycles);
    }

    public void act()
    {
        getWorld().removeObject(this);
    }
}
Then elsewhere in the thing that is exploding:
getWorld().addObject(new Explosion(20), getX(), getY());
getWorld().removeObject(this);
The sleep is an Actor attribute, so you can call it before being added to the world. We don't currently have an accessor for it.
You need to login to post a reply.