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

2018/12/29

Terminal Error: NullPointerException

SpeckieChan SpeckieChan

2018/12/29

#
I want to access the world Variable "foodEaten" but the game can not be started due to two NullPointerExeptions. One in the Class "SnakeHead" (line 14) and one in the World Class "Grid" (line 13). Please Help! Class "SnakeHead":
public class SnakeHead extends Actor
{
    
    private final int EAST = 0;
    private final int SOUTH = 90;
    private final int WEST = 180;
    private final int NORTH = 270;
    
    private final int SPEED = 10;
    private int counter = 0;
    
    private int foodEaten ((Grid)getWorld()).foodEaten;

    private GreenfootImage SnakeHead = new GreenfootImage("Head.png"); 
    
    public SnakeHead()
    {
       setImage("Black Head.png");
       
       setRotation(Greenfoot.getRandomNumber(4)*9);
    }
Class "Grid":
public class Grid extends World
{
    public int foodEaten = 0;
    
    public Grid()
    {    
        super(30, 20, 20); //super (600, 400, 1)
        
        setBackground("Rasenfläche.png");
        
        int x = Greenfoot.getRandomNumber(getWidth()-2)+1;
        int y = Greenfoot.getRandomNumber(getHeight()-2)+1;
        addObject(new SnakeHead(), x, y);
        
        addFood();
        
    }
danpost danpost

2018/12/30

#
You are (probably unintentionally) attempting to acquire a value from the world at a time when the actor is not in a world (that is, when 'getWorld" will return a null value). Note that the field at line 12 in your SnakeHead class is assigned its value at the time the SnakeHead object is created, which must happen before the object can be placed into a world. Is there a reason to have a foodEaten field in your Grid class? I cannot imagine a world that eats food.
SpeckieChan SpeckieChan

2018/12/30

#
Well the main reason i for footEaten to be in the Grid Class is to make the Variable accessible for a Counter Actor. I have not done any research on implementing a Counter object so i figured to just try it and do what would seem most logical to me. I thought that when the „snake“ eats Food it would influence the variable defined in my World Class thus also making it accessible for other actors such as a e.g. Scoreboard.
danpost danpost

2018/12/30

#
SpeckieChan wrote...
Well the main reason i for footEaten to be in the Grid Class is to make the Variable accessible for a Counter Actor. I have not done any research on implementing a Counter object so i figured to just try it and do what would seem most logical to me. I thought that when the „snake“ eats Food it would influence the variable defined in my World Class thus also making it accessible for other actors such as a e.g. Scoreboard.
Variables do not influence each other -- at least, not automatically. An assignment statement must be executed for a variable's value to change. The attempted assignment of line 12 in your SnakeHead class would only be executed once, during the creation of a SnakeHead object. To continuously update a field, the assignment statement must be arrived at by way of an act method. A scenario "animates" (is given time frames) by way of the act methods in its classes. It is a behavior of a SnakeHead object to eat food. It is a state of a SnakeHead object to have eaten some amount of food. It is the state of your Grid object (your world) to contain a Counter object. That being said, your SnakeHead class could contain a method (for behavior) to eat food and a field (for state) to track how much food it has eaten; and your Grid class could contain a field to reference the Counter object that is in it. The SnakeHead object could then get the reference to the counter from the world and tell it what value to display. However, it is usually not a good idea to have two fields for the same state (or value). The Counter object has an int field which would, in essence, duplicate the value of foodEaten. So, better would be either to use the Counter object and not have a foodEaten field in the SnakeHead class or to keep the field and use a text display object to show the value of how much food was eaten.
SpeckieChan SpeckieChan

2018/12/30

#
Thanks for your Help! I was able to fix my problem and implemented a Counter but .... it still does´nt work. When I read the code i don´t see a reason why my Counter does´nt work. It just stays at 0. Here´s the code: I wrote the Method ateFood which gets calles when the snake touches the food.(PS: the foodEaten variable is still there because i need it elsewhere)
public void act()
    {
        moveAround();
        
        if(isTouching(Food.class)) {
            removeTouching(Food.class);        
            foodEaten++;
            
            ateFood();
            
            Grid world = (Grid)getWorld();
            world.addFood();
        }
public void ateFood()
    {
        Grid gridWorld = (Grid) getWorld();
        Counter counter = gridWorld.getCounter();
        counter.foodCount(1);
    }
Here´s the Grid class:
public class Grid extends World
{
    
    private Counter theCounter;
    
    public Grid()
    {    
        super(30, 20, 20); //super (600, 400, 1)
        
        setBackground("Rasenfläche.png");
        
        int x = Greenfoot.getRandomNumber(getWidth()-2)+1;
        int y = Greenfoot.getRandomNumber(getHeight()-2)+1;
        addObject(new SnakeHead(), x, y);
        
        theCounter = new Counter();
        addObject(new Counter(), 1, 0);
        
        addFood();
    }
    
    public Counter getCounter()
    {
        return theCounter;
    }
and here the counter
public class Counter extends Actor
{
    private int totalCount = 0;

    /**
     * Constructor for objects of class Counter
     */
    public Counter()
    {   
        setImage(new GreenfootImage(" 0 ", 18, Color.WHITE, Color.BLACK));
    }

    public void foodCount(int amount)
    {
        totalCount += amount;
        setImage(new GreenfootImage("" + totalCount, 18, Color.WHITE, Color.BLACK));
    }
}
I don´t see a reason why it shouldn´t work?
danpost danpost

2018/12/30

#
SpeckieChan wrote...
I was able to fix my problem and implemented a Counter but .... it still does´nt work. When I read the code i don´t see a reason why my Counter does´nt work. It just stays at 0. << Codes Omitted >>
Look at lines 16 and 17 of your Grid class. Think about what they are doing. In particular, notice that each line creates a Counter object.
SpeckieChan SpeckieChan

2018/12/30

#
I downloaded the tutorial game from the website and there it works perfectly:
public class Space  extends World
{

    private Counter theCounter;

    /**
     * Constructor for objects of class Space.
     */
    public Space()
    {    
        // Create a new world with 600x400 cells with a cell size of 1x1 pixels.
        super(600, 400, 1); 
        addObject(new Rocket(), 300, 340);
        theCounter = new Counter();
        addObject(theCounter, 40, 340);
    }

    public Counter getCounter()
    {
        return theCounter;
    }
danpost danpost

2018/12/30

#
SpeckieChan wrote...
I downloaded the tutorial game from the website and there it works perfectly: << Code Omitted >>
As it should. Only one Counter object is created there.
You need to login to post a reply.