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

2013/2/9

Adding multiple objects to the world via another object.

Minion1 Minion1

2013/2/9

#
I've posted this question before and Danpost was kind enough to send me an answer, but I'll be honest, I didn't understand it. Here's what I'm trying to do: Hero wanders around world for a bit. After a certain number of steps, he encounters an enemy. I've created a class called "BattleBackDrop" which will add all of the necessary objects and control the flow of the battle, and it is at this moment that I am stuck. The "BattleBackDrop" (bbd for short) can be called from another class easily and added to the world, but I'm trying to get the bbd to add buttons to the world with which the player can control the battle. But as danpost pointed out to me earlier, I'm trying to call an object into the world by using an object that's not yet in the world, which is backfiring. Is there a way to do this? Here is the relevant code:
public BattleBackdrop()
    {
        //places the battle backdrop on the world.
        setImage(img);

        //error occurs below
        getWorld().addObject(button, 650, 200);
    }
And the actual error is here: java.lang.NullPointerException at BattleBackdrop.<init>(BattleBackdrop.java:16) at Scroller.beginBattle(Scroller.java:158) at Scroller.checkKeyPress(Scroller.java:83) at WorldMap.act(WorldMap.java:15) at greenfoot.core.Simulation.actActor(Simulation.java:565) at greenfoot.core.Simulation.runOneLoop(Simulation.java:523) at greenfoot.core.Simulation.runContent(Simulation.java:213) at greenfoot.core.Simulation.run(Simulation.java:203) I'm probably just screwing everything up, but as it turns out, designing a battle system is FAR beyond this hopeless noob.
vonmeth vonmeth

2013/2/9

#
 getWorld().addObject(button, 650, 200);
We are going to see more code to see what is going on. Where is this button variable set, and where the object that is set to this variable created? Posting the whole class where this method is would be helpful.
Minion1 Minion1

2013/2/9

#
The button is a separate class, that is instantiated from the bbd constructor. The bbd code is below:
import greenfoot.*;

/**
 * This class will handle the battle scenarios in their entirety.
 */

public class BattleBackdrop extends Backdrops
{
    private GreenfootImage img = new GreenfootImage("Battlescreen2.png");
    Button button = new Button("Attack");
    
    public BattleBackdrop()
    {
        //places the battle backdrop on the world.
        setImage(img);
        getWorld().addObject(button, 650, 200);
    }

    public void battleOrder()
    {
        //The order of battle operations should be controlled by this method.
    }

    public void victory()
    {
        //Add exp, money and found items.
        //Then remove the Battle object.
    }

    public void defeat()
    {
        //If all characters are dead, lose the game.
    }

    public void act() 
    {
    }
}
danpost danpost

2013/2/9

#
The problem is that the object is not actually in any world while the constructor is executing. Look at it this way. To put an object in the world (let us call it Something)
// first we create the object (this is when the constructor is executed)
Something something = new Something();
// then we add it to the world (only after this will 'getWorld' not be null)
addObject(something, 50, 50);
// now it is in a world and 'getWorld' will return the world it is in

// even if you code it with this
addObject(new Something(), 50, 50);
// the constructor is executed before it is placed in the world
There is a method that will be called automatically immediately after the object is placed in a world. This is the 'addedToWorld' method. You can add the button objects there. Remove line 16 above and add the following method to the class.
public void addedToWorld(World bbd)
{
    bbd.addObject(button, 650, 200);
}
Minion1 Minion1

2013/2/9

#
Perhaps I should have asked a better question. This was danpost's response the first time around. I copied it down but had no time to really work with it. Ultimately, I found that I don't understand it. Can someone explain it to me? Danpost said: It is not that at all. What you are doing is trying to add a BattleBackdrop object into a world from which the Battle object, which you are creating it in, is still being constructed and not yet in any world. So there is no world returned from 'getWorld' to add the object in; hence the nullPointerException ('getWorld' returns null). What you can do is override the 'addedToWorld(World)' method, which is called when the object is added into the world, to create and add the objects. public void addedToWorld(World world) { enemyField = new BattleBackdrop(); world.addObject(enemyField, 349, 128); setEnemies(); } Which would leave you with an empty constructor.
danpost danpost

2013/2/9

#
Change all occurances of 'bbd' to 'world' in my previous post in this discussion.
Minion1 Minion1

2013/2/9

#
You mean like this? public void addedToWorld(World world) { world = new World(); world.addObject(enemyField, 349, 128); setEnemies(); }
Minion1 Minion1

2013/2/9

#
The "addedToWorld" method you suggested needs a world as a parameter. I guess I don't understand what to enter for that parameter, nor where to place the method in the overall scheme of things... Do I place it inside of the constructor or outside of the constructor and make a call to it?
danpost danpost

2013/2/9

#
You do not need the statement 'world = new World();' as the world is supplied for you. The method is called automatically when you 'addObject' the object into a world. You DO NOT code any calls to this method. It is a seperate method in the class (outside of the constructor).
Minion1 Minion1

2013/2/9

#
Well I'll be.. it worked! Thank you danpost. I'll see about making good use of this. Some other thoughts occured to me while waiting for a response, I may be able to work on this through another way. But now that this is working it will help me immensely. Sorry for all the confusion, I'm very new to this.
You need to login to post a reply.