|
All the world’s a stage, and this quote, often abused.
M. Jadud
|
What can an Actor do? Not as pressing a question as What Would an Actor Do? (WWAD?), but certainly an important question never-the-less. I want to remind the gentle reader that I have many grand schemes about great, sweeping themes and stories about agent-based programming in Java using Greenfoot… but at the moment, I’m just wandering around. And in my wanderings, I’d like to make the mushrooms in my LumpWorld wander around, too.
Of course, I don’t know how to do that. I could try and use Google to find out how, or I could go back and read the tutorial. However, I want to try something a little different. I’ll read some documentation.
Now, I know some of you are saying “Matt! Reading documentation! That’s awfully extreme, isn’t it?” Well, my friends, it is. Very extreme. And, for the record, it is very, very exciting. And Greenfoot has plenty of documentation hidden inside it, if you know where to look.

Documentation be hidden in them thar classes…
Lets start with the Actor class. If I double-click on the Actor class, I get a whole mess of Java.

Double-clicking the Actor class yields a mess-o-Java.
This mess-o-Java is not for the faint-of-heart. If you look at the top of the file, you’ll see that it is written by @author Poul Henriksen, which means that a crazy person wrote that code. And we all know what happens when crazy people write software. So be careful if you spend any serious time looking at this code. What is more interesting is in the upper-right-hand corner of this window: a little drop-down menu. It has two options: Implementation and Interface Go ahead and select Interface.

Documentation regarding the Actor class.
This is more like it! The interface documentation tells us about all the things we can do with an Actor object. For example, in my last example, I used the setRotation method; we can see that it is documented here, and not just in the Wombats tutorial. Along with it is a method called setLocation. The method summary is really quite straight-forward:
void setLocation(int x, int y)
          Assign a new location for this object.
This method consumes two integers, and returns nothing. I’m guessing it is a magic teleport method, and probably should have been called magicTeleporter(int x, int y), because it will magically make your Actor jump to anyplace in the Greenfoot World. I’m going to take my existing act() method:
public void act()
{
lump_rotation = lump_rotation + 1;
setRotation(lump_rotation);
}
and I’m going to modify it just a bit. I’m going to make my mushrooms wander around while they’re rotating.
A first attempt
The neat thing about sitting down to a piece of software as rich as Greenfoot is that you can find things you don’t expect. Put another way, I can come to the table with all kinds of assumptions, pre-conceived notions, and expectations about how Greenfoot should or will work, and then be surprised when it doesn’t work that way. Since the point of this blog is to wander around Greenfoot “kicking the tires” (so to speak), I might as well talk about some of my failures along side some of my successes, no?
Here was my first attempt at making a Lump that would march across the screen:
public class Lump extends Actor
{
private int lump_rotation;
private int lump_X;
public Lump()
{
lump_X = getX();
}
public void act()
{
lump_rotation = lump_rotation + 1;
setRotation(lump_rotation);
// Move the Lump around!
lump_X = lump_X + 1;
setLocation(lump_X, getY());
}
}
My previous post explored making my Lumps rotate around their axes; this would have them spinning and marching around. However, this code has a significant problem that didn’t really make sense to me at first:
java.lang.IllegalStateException: The actor has not been inserted into a world
so it has no location yet. You might want to look at the
method addedToWorld on the Actor class.
at greenfoot.Actor.failIfNotInWorld(Actor.java:537)
at greenfoot.Actor.getX(Actor.java:103)
at Lump.(Lump.java:23)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:494)
at greenfoot.core.WorldInvokeListener$2.run(WorldInvokeListener.java:150)
You see, I put the call getX() in the constructor for my Actor. (The constructor is a special Java class method that is called when a new object is created. It always has the same name as the class—in this case, it is called Lump().) When I right-click to create a new Lump() object, everything is fine… until I try and put it in the world. At this point, the object is created, but it doesn’t yet exist in the world. So, everything goes badly for my Lump, and this exception is thrown.
That’s cool. Since this post is about reading documentation, I then went back to the documentation I mentioned earlier and started reading. Sure enough, the docs tell me that I can’t do what I tried to do. Because I’m a slow monkey, it looks like the documentation might become even more explicit about this point—that would be cool. While reading more carefully, I discovered the addedToWorld() method. This fits in thusly:
- You right-click to create a new Actor object
- You drop your Actor on the World
- Your Actor’s constructor is called
- Your Actor’s
addedToWorld() is called
Now, I’m sure other nifty things happen in there, but this is enough for us to be getting on with.
A second attempt
Now that I’ve learned to stop fearing Greenfoot, and learned to love the documentation, my life has been much, much better. My next attempt at making my Actor wander around was much better.
public class Lump extends Actor
{
private int lump_rotation;
private int lump_X;
public Lump()
{
}
public void addedToWorld(greenfoot.World world) {
lump_X = getX();
}
public void act()
{
lump_rotation = lump_rotation + 1;
setRotation(lump_rotation);
// Move the Lump around!
lump_X = lump_X + 1;
setLocation(lump_X, getY());
}
}
Now, my Lump correctly drops into the World! Woot! What happened next, however, was not expected; I’ve created a video to demonstrate what I encountered next.

A video of my first Greenfoot exception! (6.9MB, right-click to download.)
An exception! In particular, this text popped up on my screen: