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

2018/1/24

changing worlds problem

1
2
ImAndrew ImAndrew

2018/1/24

#
I have a door class which should send the player to another room(World) when he defeated all the enemies. The code is working well until I try to add a door which should get me back in a room I already was.When I do that Greenfoot freezes and when I restart the game it says that I would have an infinite loop in a world constructor.
public class Door extends Actor
{
    World nextRoom;
    
    public Door(World _nextRoom)
    {
        nextRoom = _nextRoom;
    }
    
    public void act() 
    {
        nextRoom(nextRoom);
    }
    
    public void nextRoom(World nextWorld)
    {
        if(getWorld().getObjects(Enemy.class).isEmpty())
        {
            Hero hero = (Hero)getOneIntersectingObject(Hero.class);
            if(hero != null)
            {
                nextWorld.addObject(hero,100,150);
                Greenfoot.setWorld(nextWorld);
            }
        }
    }
}
I have a Dungeon super class which holds a static hero object for all the rooms. public class Dungeon1 extends World { protected final static int WIDTH = 800; protected final static int HEIGHT = 600; protected final static int CELL_SIZE = 1; protected int enemiesRemaining; protected static Hero hero; public Dungeon1(int _width, int _height, int _cellsize) { super(_width, _height, _cellsize); }
Super_Hippo Super_Hippo

2018/1/24

#
Where and how do you create the Door objects?
Vercility Vercility

2018/1/24

#
Hard to say without complete code I'll take a guess and say that your old world is still empty, therefore triggering the next world, which sends u back etc..
ImAndrew ImAndrew

2018/1/24

#
Super_Hippo wrote...
Where and how do you create the Door objects?
Example I create and place a door in room 1 to room 2 (Door door = new Door(room2)).If I create and place a door in room 2 (Door door2 = new Door(Room1)) for room 1 then it freezes or tell me that I have an infinite loop until I delete the door2 with another editor.
Super_Hippo Super_Hippo

2018/1/24

#
Show the world code.
ImAndrew ImAndrew

2018/1/24

#
super class
public class Dungeon1 extends World
{
    protected final static int WIDTH = 800;
    protected final static int HEIGHT = 600;
    protected final static int CELL_SIZE = 1;
    protected int enemiesRemaining;
    protected static Hero hero;
    public Dungeon1(int _width, int _height, int _cellsize)
    {
        super(_width, _height, _cellsize);
    }
}
first room subclass
public class D1_R1 extends Dungeon1
{
    public D1_R1()
    {    
        super(800, 600, 1);
        prepare();
    }
    
    private void prepare()
    {
        hero = new Hero();
        addObject(hero,200,200);

        RangeEnemy rangeenemy = new RangeEnemy(hero);
        addObject(rangeenemy,188,225);
        RangeEnemy rangeenemy2 = new RangeEnemy(hero);
        addObject(rangeenemy2,190,342);
        CloseEnemy closeenemy = new CloseEnemy(hero);
        addObject(closeenemy,723,54);
        CloseEnemy closeenemy2 = new CloseEnemy(hero);
        addObject(closeenemy2,534,62);
 
        Door door = new Door(new D1_R2());
        addObject(door,392,277);
    }
}
Second room subclass
public class D1_R2 extends Dungeon1
{
    /**
     * Constructor for objects of class D1_R2.
     * 
     */
    public D1_R2()
    {
        super(800, 600, 1);
        prepare();
    }
    
    void prepare()
    {
        CloseEnemy closeenemy3 = new CloseEnemy(hero);
        addObject(closeenemy3,641,425);
        CloseEnemy closeenemy4 = new CloseEnemy(hero);
        addObject(closeenemy4,508,238);
        
        Door door2 = new Door(new D1_R3());
        addObject(door2,266,465);

        //Door door3 = new Door(new D1_R1()); here is the problem
        //addObject(door2,266,465);

    }
}
Super_Hippo Super_Hippo

2018/1/24

#
Yes, you have a loop. D1_R1 creates a D1_R2 object which creates a D1_R1 object again which creates a D1_R2 object etc... What you could do is that you pass a number and not the world and create the world when it triggers based on the number. Or you create all rooms ones and the doors lets you move from one room to another without creating a new one. So for example when you clear room 1, go to room 2 and then later back to room 1, room 1 will stay cleared. Or not if you create a new instance of the world.
ImAndrew ImAndrew

2018/1/24

#
Super_Hippo wrote...
Yes, you have a loop. D1_R1 creates a D1_R2 object which creates a D1_R1 object again which creates a D1_R2 object etc... What you could do is that you pass a number and not the world and create the world when it triggers based on the number. Or you create all rooms ones and the doors lets you move from one room to another without creating a new one. So for example when you clear room 1, go to room 2 and then later back to room 1, room 1 will stay cleared. Or not if you create a new instance of the world.
I tried to create an array of worlds and pass one object from the array to the constructor(to select the next world) but it doesn't find the array.
public class Door extends Actor
{
    World nextRoom;
    
    World[] worldArr = {
    new D1_R1(),
    new D1_R2(),
    };
    
    public Door(World _nextRoom)
    {
        nextRoom = _nextRoom;
    }
    
    public void act() 
    {
        nextRoom(nextRoom);
    }
    
    public void nextRoom(World nextWorld)
    {
        if(getWorld().getObjects(Enemy.class).isEmpty())
        {
            Hero hero = (Hero)getOneIntersectingObject(Hero.class);
            if(hero != null)
            {
                nextWorld.addObject(hero,100,150);
                Greenfoot.setWorld(nextWorld);
            }
        }
    }
}
danpost danpost

2018/1/24

#
An array is probably alright to use; however, it needs to be a permanent one that is accessible to all worlds easily. You could do this is several ways. One is to put it in your Dungeon1 world as a static array, where the constructor assigns its values. Another is to use a separate abstract class (maybe called 'WorldManager') to hold the array, with possibly a static method or two to make easy access to the elements of the array. A static int field can be placed into the class to track which world is active and make an easy determination of which are the from and to rooms. With that, you will not be passing or creating undo worlds or having any looping going on. You will be giving the doors a value -- either '-1' for "from" or '1' for "to". Your initial world constructor will still need to initialize the data even if it is in a separate class. A static method can be called to have the class re-initialize.
ImAndrew ImAndrew

2018/1/24

#
danpost wrote...
An array is probably alright to use; however, it needs to be a permanent one that is accessible to all worlds easily. You could do this is several ways. One is to put it in your Dungeon1 world as a static array, where the constructor assigns its values. Another is to use a separate abstract class (maybe called 'WorldManager') to hold the array, with possibly a static method or two to make easy access to the elements of the array. A static int field can be placed into the class to track which world is active and make an easy determination of which are the from and to rooms. With that, you will not be passing or creating undo worlds or having any looping going on. You will be giving the doors a value -- either '-1' for "from" or '1' for "to". Your initial world constructor will still need to initialize the data even if it is in a separate class. A static method can be called to have the class re-initialize.
When I try to create the array I get the java heap space exception, also can you explain me more about how would help me the WorldManager class?
public class Dungeon1 extends World
{
    protected final static int WIDTH = 800;
    protected final static int HEIGHT = 600;
    protected final static int CELL_SIZE = 1;
    protected int enemiesRemaining;
    protected static Hero hero;
    static World[] worldArr;
    
    public Dungeon1(int _width, int _height, int _cellsize)
    {
        super(_width, _height, _cellsize);
        worldArr = new World[]{
            new D1_R1(),
            new D1_R2(),
            new D1_R3()
        };
    }
}
Vercility Vercility

2018/1/24

#
You're running a loop again Your Dungeon1 constructor calls R1 which calls super( which is Dungeon1), which calls R1 etc.
Super_Hippo Super_Hippo

2018/1/24

#
Try
private static World[] worldArr =
{
    new D1_R1(),
    new D1_R2(),
    new D1_R3()
};
as line 8 and remove lines 13-17.
ImAndrew ImAndrew

2018/1/24

#
Vercility wrote...
You're running a loop again Your Dungeon1 constructor calls R1 which calls super( which is Dungeon1), which calls R1 etc.
Oh,I see , I will get a headache with these loops.
Super_Hippo wrote...
Try
private static World[] worldArr =
{
    new D1_R1(),
    new D1_R2(),
    new D1_R3()
};
as line 8 and remove lines 13-17.
I tried this earlier and I got an exception when I add a door object to D1_R1 World "java.lang.NoClassDefFoundError: Could not initialize class D1_R1 " I'm out of solutions.
Vercility Vercility

2018/1/24

#
ImAndrew wrote...
Vercility wrote...
You're running a loop again Your Dungeon1 constructor calls R1 which calls super( which is Dungeon1), which calls R1 etc.
Oh,I see , I will get a headache with these loops.
Super_Hippo wrote...
Try
private static World[] worldArr =
{
    new D1_R1(),
    new D1_R2(),
    new D1_R3()
};
as line 8 and remove lines 13-17.
I tried this earlier and I got an exception when I add a door object to D1_R1 World "java.lang.NoClassDefFoundError: Could not initialize class D1_R1 " I'm out of solutions.
How exactly did you do that
danpost danpost

2018/1/24

#
Maybe you can get some pointers from my Door World Entry Demo scenario.
There are more replies on the next page.
1
2