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

2014/5/2

Adding smokeBomb

1
2
akilino akilino

2014/5/2

#
With the developing of my game, I'm having problem adding a class (the image of that class ), when an intersection happens...
public class theBomb extends pacActors
{
    pacWorld pacworld = (pacWorld)getWorld();
    //Smoke smoke = (Smoke)pacworld.getObjects(Smoke.class).get(0);
    Smoke smoke = new Smoke();
    /**
     * Act - do whatever the theBomb wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        explodeBad();
    } 
    
    public void explodeBad()
    {
        Actor bad  = getOneIntersectingObject(Bad.class);
        Actor bad1 = getOneIntersectingObject(Bad1.class);
        Actor bad2 = getOneIntersectingObject(Bad2.class);
        Actor bad3 = getOneIntersectingObject(Bad3.class);
        Actor bad4 = getOneIntersectingObject(Bad4.class);
        Actor bad5 = getOneIntersectingObject(Bad5.class);
        Actor bad6 = getOneIntersectingObject(Bad6.class);
        pacWorld pacworld = (pacWorld)getWorld();              
        
        //int x = getX();
        
        //---------------ao intersectar, remove a bomba e o bad
        if(bad != null)
        {
            pacworld.removeObject(bad);
            pacworld.removeObject(this);
        }

        if(bad1 != null)
        {
            pacworld.removeObject(bad1);
            pacworld.removeObject(this);
        }
        
         if(bad2 != null)
        {
            pacworld.removeObject(bad2);
            pacworld.removeObject(this);
        }
        
         if(bad3 != null)
        {
            pacworld.removeObject(bad3);
            addSmoke();
            pacworld.removeObject(this);
        }
        
         if(bad4 != null)
        {
            pacworld.removeObject(bad4);
            pacworld.removeObject(this);
        }
        
         if(bad5 != null)
        {
            pacworld.removeObject(bad5);
            pacworld.removeObject(this);
        }

         if(bad6 != null)
        {
            pacworld.removeObject(bad6);
            pacworld.removeObject(this);
        }
    }
    
    public void addSmoke()
    {
        for(int x = getX(); x < 28; x++)
        {
            pacworld.addObject(new smokeBomb(), x, getY());
            smoke.vanish(40);
        }
    }
    
    
}
It crashes and gives me this error:
java.lang.NullPointerException
	at theBomb.addSmoke(theBomb.java:86)
	at theBomb.explodeBad(theBomb.java:58)
	at theBomb.act(theBomb.java:20)
	at greenfoot.core.Simulation.actActor(Simulation.java:568)
	at greenfoot.core.Simulation.runOneLoop(Simulation.java:526)
	at greenfoot.core.Simulation.runContent(Simulation.java:215)
	at greenfoot.core.Simulation.run(Simulation.java:205)
akilino akilino

2014/5/2

#
(...)
danpost danpost

2014/5/2

#
nvm.
danpost danpost

2014/5/2

#
Line 3 will always set 'pacworld' to a 'null' value. The declaration of the field (and its assignment -- if done while being declared) happens while the object is being created and BEFORE it is placed in a world.
akilino akilino

2014/5/2

#
danpost wrote...
Line 3 will always set 'pacworld' to a 'null' value. The declaration of the field (and its assignment -- if done while being declared) happens while the object is being created and BEFORE it is placed in a world.
How do I correct this?
danpost danpost

2014/5/2

#
Remove line 3 and change 'pacworld' to 'getWorld()' in your 'addSmoke' method (line 77).
akilino akilino

2014/5/2

#
danpost wrote...
Remove line 3 and change 'pacworld' to 'getWorld()' in your 'addSmoke' method (line 77).
Thank you so much @danpost #danpost! I wish I know what's the meaning of this.. Like I know what it does, but I don't know to explain it:
pacWorld pacworld = (pacWorld)getWorld();
enemiesDown enemies = (enemiesDown)pacworld.getObjects(enemiesDown.class).get(0);
danpost danpost

2014/5/2

#
The first line declares a local variable of type 'pacWorld', gives it the name 'pacworld', and assigns it the value returned from 'getWorld()' whose type is cast from type World to type '(pacWorld)'. The second line declares a local variable of type 'enemiesDown', gives it the name 'enemies' and assigns it the value returned from the first element, 'get(0)' from the List object returned from 'getObjects(enemiesDown.class)' in the world held in the field 'pacworld' -- this element cast from type Object to type '(enemiesDown)'.
akilino akilino

2014/5/3

#
danpost wrote...
The first line declares a local variable of type 'pacWorld', gives it the name 'pacworld', and assigns it the value returned from 'getWorld()' whose type is cast from type World to type '(pacWorld)'. The second line declares a local variable of type 'enemiesDown', gives it the name 'enemies' and assigns it the value returned from the first element, 'get(0)' from the List object returned from 'getObjects(enemiesDown.class)' in the world held in the field 'pacworld' -- this element cast from type Object to type '(enemiesDown)'.
It's a bit difficult to understand, so could you give me an example? If I want to have access to enemiesDown.class, from another class that I don't have access, I need to make that procedure, in order to enemiesDown.class have access to pacWorld, that was first connected to getWorld(). Only after that I can have access of whatever pacWorld has? enemiesDown.class is a sub-class of Actor. If I want to acess to another sub-class of Actor, that is not inherited from the superclass of the enemiesDown subclass, I need to connect pacWorld to get getWorld (pacWorld pacworld = (pacWorld)getWorld() ) ? And to have access to enemiesDown.class, I need to connect it to pacWorld ( enemiesDown enemies = (enemiesDown)pacworld.getObjects(enemiesDown.class).get(0) ) ? I know I wrote a lot, and I can imageine I did repeat many words, but this is how I would understand how this works..
akilino akilino

2014/5/3

#
Also, I have another question which is about making a counter, so that when doing the method explodeBad.class, it would add the Objects with some delay, each one of it, giving some kind of motion..
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
/**
 * Write a description of class theBomb here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class theBomb extends pacActors
{
    Smoke smoke = new Smoke();
    private int contadorSmoke = 0;
    //     public int x;
    //     public int y;
    /**
     * Act - do whatever the theBomb wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        contadorSmoke++;
        if(contadorSmoke == 3)
        {
            explodeBad();
            contadorSmoke = 0;
        }
    } 

    //Método responsável pela explosão do Bad.class
    //interseção dos dois objetos resulta na remoção de ambos.
    public void explodeBad()
    {
        Actor bad  = getOneIntersectingObject(Bad.class);
        Actor bad1 = getOneIntersectingObject(Bad1.class);
        Actor bad2 = getOneIntersectingObject(Bad2.class);
        Actor bad3 = getOneIntersectingObject(Bad3.class);
        Actor bad4 = getOneIntersectingObject(Bad4.class);
        Actor bad5 = getOneIntersectingObject(Bad5.class);
        Actor bad6 = getOneIntersectingObject(Bad6.class);           

        //---------------ao intersectar, remove a bomba e o bad
        if(bad != null)
        {
            addSmoke();
            getWorld().removeObject(bad);
            getWorld().removeObject(this);
        }

        if(bad1 != null)
        {
            addSmoke();
            getWorld().removeObject(bad1);
            getWorld().removeObject(this);
        }

        if(bad2 != null)
        {
            addSmoke();
            getWorld().removeObject(bad2);
            getWorld().removeObject(this);
        }

        if(bad3 != null)
        {
            addSmoke();
            getWorld().removeObject(bad3);
            getWorld().removeObject(this);
        }

        if(bad4 != null)
        {
            addSmoke();
            getWorld().removeObject(bad4);
            getWorld().removeObject(this);
        }

        if(bad5 != null)
        {
            addSmoke();
            getWorld().removeObject(bad5);
            getWorld().removeObject(this);
        }

        if(bad6 != null)
        {
            addSmoke();
            getWorld().removeObject(bad6);
            getWorld().removeObject(this);
        }
    }

    public void addSmoke()
    {
        for(int x = getX(); x < 29; x++)
        {
            getWorld().addObject(new smokeBomb(), x, getY());
        }

        for(int x = getX(); x > 0; x--)
        {
            getWorld().addObject(new smokeBomb(), x, getY());
        }

        for(int y = getY(); y > 0; y--)
        {
            getWorld().addObject(new smokeBomb(), getX(), y);
        }

        for(int y = getY(); y < 29; y++)
        {
            getWorld().addObject(new smokeBomb(), getX(), y);
        }
    }
}
danpost danpost

2014/5/3

#
With the code I described above, it is not necessary to access the world in that way. 'getObjects' in the second line is in the World class, not in your 'pacWorld' class, and can be executed with this 'getWorld().getObjects(...' from an Actor subclass. Only if that something you need access to is specifically within the 'pacWorld class code (a method or a field) do you need to execute the first line, which casts the World objects as a type of pacWorld object. Let us say you had a method in your pacWorld class called 'executeThis' and you needed to run it from an Actor subclass. Then you could use
pacWorld pacworld = (pacWorld)getWorld();
pacworld.executeThis();
which could also be written like this:
((pacWorld)getWorld()).executeThis();
akilino akilino

2014/5/3

#
danpost wrote...
With the code I described above, it is not necessary to access the world in that way. 'getObjects' in the second line is in the World class, not in your 'pacWorld' class, and can be executed with this 'getWorld().getObjects(...' from an Actor subclass. Only if that something you need access to is specifically within the 'pacWorld class code (a method or a field) do you need to execute the first line, which casts the World objects as a type of pacWorld object. Let us say you had a method in your pacWorld class called 'executeThis' and you needed to run it from an Actor subclass. Then you could use
pacWorld pacworld = (pacWorld)getWorld();
pacworld.executeThis();
which could also be written like this:
((pacWorld)getWorld()).executeThis();
Thank you danpost! Now I do understand this! I'm changing the code and checking if gives problems or not! And about that code that I added above your last comment, where would I put the counter, in order to set a delay when adding those objects?
danpost danpost

2014/5/3

#
What exactly are you trying to accomplish and what steps will you need to accomplish it (first, in general terms; then, in detail). Like -- how do you want the user to perceive this motion as being; what are all the bad intersectors for; etc.
akilino akilino

2014/5/3

#
danpost wrote...
What exactly are you trying to accomplish and what steps will you need to accomplish it (first, in general terms; then, in detail). Like -- how do you want the user to perceive this motion as being; what are all the bad intersectors for; etc.
Objects will be added, so I don't know where to place the counter, in order that an object is placed, waits for 4 seconds before adding another one. Objects will be placed like a cross. It goes from the inner to the outer side. With the vanish method, those objects will become transparent after a few cycles
danpost danpost

2014/5/3

#
Maybe if you posted two of your bad classes ( like Bad and Bad1 ) I might get a better idea of what you are trying to do. It appears like only the first bad actor will ever be removed. Is this what is happening?
There are more replies on the next page.
1
2