For a Greenfoot final class project, I decided to make a game called "Doggie the Super Catcher". What this game basically does is that the actor, Doggie, will try his best to catch the clovers and special treats that seems to be falling from the trees by running back and forth across the screen (through the user's left and right arrow keyboard input, of course). However, the thing is that I want to create multiple levels, and that I kind of want what I have for the first world (named GameWorld) to appear in level 1, which is in a different world. How am I supposed to do that? In other words, I can't seem to transfer the same things from GameWorld to Level1, which includes the clovers, candies, and score board, when a certain condition is met (i.e., a specific number of points is reached)? FYI: I've used a separate actor for the score board (hope this helps...). Does any of you know of a way? Thanks.
import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
public class Doggie extends Actor
{
// Declare arrays of Greenfoot images for animation
private GreenfootImage[] runningLeft;
private GreenfootImage[] runningRight;
// Declare Greenfoot images for standing still facing left and right
private GreenfootImage standingStill;
private GreenfootImage standingLeft;
private GreenfootImage standingRight;
//
boolean facingLeft;
// Integers that help control the speed of movement and animation
private int animationCounter;
private int animationDelay;
private int animationDelayCounter;
private int animationSpeed;
Clover c;
SpecialTreat1 c1;
SpecialTreat2 c2;
public Doggie()
{
String fileName;
String fileNamePrefix = "left0";
String fileNameSuffix = ".png";
runningLeft = new GreenfootImage[3];
runningRight = new GreenfootImage[3];
for (int imageCounter = 0; imageCounter < runningLeft.length; imageCounter++)
{
fileName = fileNamePrefix + (imageCounter + 1) + fileNameSuffix;
runningLeft[imageCounter] = new GreenfootImage(fileName);
runningRight[imageCounter] = new GreenfootImage (runningLeft[imageCounter]);
runningRight[imageCounter].mirrorHorizontally();
}
standingStill = new GreenfootImage ("still01.png");
standingLeft = new GreenfootImage ("left01.png");
standingRight = new GreenfootImage (standingLeft);
standingRight.mirrorHorizontally();
facingLeft = true;
animationSpeed = 5;
animationDelay = 6;
animationDelayCounter = 0;
animationCounter = 0;
}
/**
* Act - do whatever the Doggie wants to do. This method is called whenever
* the 'Act' or 'Run' button gets pressed in the environment.
*/
public void act()
{
animationDelayCounter++;
if (animationDelayCounter == animationDelay)
{
animationCounter++;
animationDelayCounter = 0;
}
if (animationCounter > runningRight.length - 1)
animationCounter = 0;
c = (Clover)getOneIntersectingObject(Clover.class);
c1 = (SpecialTreat1)getOneIntersectingObject(SpecialTreat1.class);
c2 = (SpecialTreat2)getOneIntersectingObject(SpecialTreat2.class);
if (c != null)
{
c.collect();
GameWorld gW = (GameWorld)getWorld();
gW.showPoints();
}
if (c1 != null)
{
c1.collect();
GameWorld gW = (GameWorld)getWorld();
gW.showPoints();
}
if (c2 != null)
{
c2.collect();
GameWorld gW = (GameWorld)getWorld();
gW.showPoints();
}
}
public void runLeft()
{
if (!(facingLeft))
animationCounter = 0;
facingLeft = true;
setImage (runningLeft[animationCounter]);
setLocation (getX() - animationSpeed, getY());
}
public void runRight()
{
if (facingLeft)
animationCounter = 0;
facingLeft = false;
setImage (runningRight[animationCounter]);
setLocation (getX() + animationSpeed, getY());
}
public void standStill()
{
if (facingLeft)
{
setImage(standingLeft);
}
else
setImage(standingRight);
animationCounter = 0;
animationDelayCounter = 0;
}
}
In Greenfoot, levels are usually implemented by having different worlds. So you might have:
class Level1 extends World
{
...
}
And
class Level2 extends World
{
...
}
They will both appear directly beneath World in the class diagram. If you want to share code between your levels (e.g. they both spawn clovers) then you probably want a shared parent class. So you might have:
class DoggieWorld extends World
{
public void spawnClovers(int speed)
{
if (Greenfoot.getRandomNumber(1000) < speed)
addObject(new Clover(), Greenfoot.getRandomNumber(getWidth()), 0);
}
}
Then you have two level classes, each of which extends DoggieWorld (not just plain World), allowing you to call the spawnClovers method from each:
class Level1 extends DoggieWorld
{
public void act()
{
spawnClovers(20);
}
}
class Level2 extends DoggieWorld
{
public void act()
{
spawnClovers(50);
}
}
I don't want to make this answer too long, but hopefully that gives the general idea: have a shared parent world class which both level classes inherit from (using extends), and then both level classes can call methods from the shared parent.
Edit: sorry, I think I just understood more clearly that you also want to transfer the actors between the worlds when switching level. You can do this by going through all the actors of the type you are interested in, and removing them from the existing world and adding them to the new world. E.g. include this sort of method in Level1:
public void changeLevel()
{
World nextLevel = new Level2();
for (Clover c : getObjects(Clover.class))
{
// Must ask for position before removing from world:
int x = c.getX();
int y = c.getY();
removeObject(c);
nextLevel.addObject(c, x, y);
}
Greenfoot.setWorld(nextLevel);
}
Hope that helps