Multiple levels in Greenfoot games

A demo scenario

Yesterday I announced that a new Greenfoot version is available (version 2.1). Over the next few days, I’ll go through some of the new features and introduce them briefly here. This is the first one: the setWorld(…) method.

The Greenfoot class now has a method with the following signature:

setWorld (World world)

This method takes a world object as a parameter, and it will show that world in the Greenfoot main window.

This allows you to have multiple World subclasses (in my example called Level1 and Level2). You can then dynamically (that is: while your program is running) create and install other world objects. These other worlds can show entirely different scenes, such as other levels.

Two world subclasses, representing different levels.

For example, to go to Level 2, you could use the following statement:

   Greenfoot.setWorld(new Level2());

Of course, the same initialisation applies as usual: If the Level2 world creates and inserts some actors in it’s constructor, this will all happen.

One thing to keep in mind, though, is that this will – if you don’t do anything clever – create new actors. So, if you have a game character in level 1, an then you add a game character to level 2, you will have a new character object. If you stored some state (e.g. a score) in the instance variables of that actor, it will be gone. If you want to preserve the state of your game character, make sure you carry the actor object across without creating a new one.

An example showing this new functionality in action is now on the Greenfoot Gallery, here.

10 thoughts on “Multiple levels in Greenfoot games

  1. I noticed a constructor for World that includes a boolean for bounded. Can this be used to share the current Actor objects between worlds?

  2. No, the ‘bounded’ flag just removes the world size bounds, essentially making worlds infinite size. Actors can then go out of the screen (becoming invisible to the user) and come back at later stage. But they cannot transfer into other worlds this way. (Other worlds are not in the same plane – they are not to the right or below the current one, they are completely disconnected).

    Actors can be transferred into another world just by passing a reference to the actor into the world, and adding it. For example, if a game character wanted to move to Level 2 (a second world), and the character object should really move across, so that state is preserved, you could write (in the player actor):

    getWorld().removeActor(this); // leave the current world
    Greenfoot.setWorld (new Level2(this)); // create new world, install it, and pass myself into it

    In the Level2 class (a subclass of World), you could then have a constructor:

    public Level2 (MyPlayer player)
    {

    addObject (player);
    }

    This way, the player object moves from one world to the next.

  3. Few questions. Is it just me who’s having issues with exported Jar’s and webpages only having a tiny box where the world should be. And issues with MIDI not working 🙁

    How does Greenfoot determine which World to load first? Is there or could there please be a way to define which World is loaded first.

    Also on Level changing, if objects that didn’t change the world themselves need to remain across worlds what is the best way of doing this? I was thinking overriding setWorld to do the job, or is there (or plans to add) a method called in Actor when the world is changed.

    I was only expecting volume control. To find the level changing and microphone input as well. Oh and turn and move (That will help a lot when people progress from the little crab scenario). This is perhaps as amazing as when Greenfoot 2 came out.

    Keep up the amazing work 🙂

  4. @Michael:

    I haven’t seen the problem with the tiny box instead of the world. If you have a scenario where that happens – could you send it to us at support@greenfoot.org? We would be keen to track this down. It sounds like a bug. The same for MIDI not working – please report a bug so that we can investigate. I am not aware of this problem.

    Regarding the first world: You can determine this by interactively creating a world. You can instantiate the world manually using the ‘new MyWorld()’ constructor of your world object. Greenfoot will remember which world you instantiated last interactively, and use that world as the first world to show.

    Transferring objects: There is no callback in Actor for world changes. If you want to transfer some objects across, the easiest seems to be to hold a collection somewhere (e.g. in the world) and have a method to move all of them across at the right time.

  5. The Pengu scenario, from the beginning where you showed how to jump and fall up to this changing levels bit, has been very instructive. Thanks for your hard work. You are the only teacher on YouTube who I have been able to learn from.
    In response to M Clapham’s first question, I ran into this problem when I was fiddling with World construction. The tiny world appeared when the number of grid squares is small and the number of pixels is also small, like:
    super(20, 20, 1);
    It can be fixed by increasing the pixels:
    super(20,20,20).

  6. Hello Mik,
    is it possible to define a class which initializes components that exist in all worlds/levels like a live & coin counter? i try doing this with a class “BaseLevel” and Level classes, that inherit from BaseLevel but I can’t get it working. In BaseLevel, I defined a initializeObjects() method which initializes the counters and my main character. In the subclasses, i defined prepare() methods like they are usual, so they just add the other objects like platforms etc. Maybe you can help me.
    Greetings
    George

  7. Hello, it’s me again.
    I fixed it. I made a typing mistake which resulted in not calling the prepare method. Sorry for my post.

Leave a Reply

Your email address will not be published.