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

2013/8/25

Calling Methods from Different Classes

mrbones mrbones

2013/8/25

#
I'm working with on one of the little crab scenarios, and I am trying to have it add another lobster and more worms after you eat a set amount of worms. The problem is that I can't get my crab class to call my method "nextLevel();" from my CrabWorld class to add more worms and another lobster. Instead I keep getting an error message saying "non-static method nextLevel() cannot be referenced from a static context. Thanks in advance.
//CRAB CLASS


import greenfoot.*;  // (World, Actor, GreenfootImage, and Greenfoot)

/**
 * This class defines a crab. Crabs live on the beach. They like sand worms 
 * (very yummy, especially the green ones).
 * 
 * Version: 5
 * 
 * In this version, the crab behaves as before, but we add animation of the 
 * image.
 */

public class Crab extends Animal
{
    private GreenfootImage image1;
    private GreenfootImage image2;
    
   private int wormsEaten;
        
    /** 
     * Act - do whatever the crab wants to do. This method is called whenever
     *  the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act()
    {
        checkKeypress();
        move();
        lookForWorm();
        switchImage();
    }

    public Crab()
    {
        image1 = new GreenfootImage("crab.png");
        image2 = new GreenfootImage("crab2.png");
        setImage(image1);
        
        
    }

    public void switchImage()
    {
        if ( getImage() == image1 )
        {
            setImage(image2);
        }
        else
        {
            setImage(image1);
        }
    }
    
    /**
     * Check whether a control key on the keyboard has been pressed.
     * If it has, react accordingly.
     */
    public void checkKeypress()
    {
        if (Greenfoot.isKeyDown("left")) 
        {
            turn(-15);
        }
        if (Greenfoot.isKeyDown("right")) 
        {
            turn(15);
        }
    }
  
    /**
     * Check whether we have stumbled upon a worm.
     * If we have, eat it. If not, do nothing. If we have
     * eaten eight worms, we win.
     */
    public void lookForWorm()
    {
        if ( canSee(Worm.class) ) 
        {
            eat(Worm.class);
            Greenfoot.playSound("slurp.wav");
            wormsEaten = wormsEaten +1;
            if (wormsEaten == 8)
        {
            CrabWorld.nextLevel();
            wormsEaten = 0;
        }
        }
    }
}
//CrabWorld Class

import greenfoot.*;  // imports Actor, World, Greenfoot, GreenfootImage

import java.util.Random;
import java.awt.Color;

public class CrabWorld extends World
{


//    public static final Color pathColor = new Color(227, 202, 148);
    /**
     * Create the crab world (the beach). Our world has a size 
     * of 560x560 cells, where every cell is just 1 pixel.
     */
    public CrabWorld() 
    {
        super(560, 560, 1);
        populateWorld();
        
    }
  
    /**
     * Create the objects for the start of the game.
     */
    public void populateWorld()
    {
        addObject(new Crab(), 300, 300);
        
        addObject(new Lobster(), 90, 70);
        addObject(new Lobster(), 390, 200);
        addObject(new Lobster(), 360, 500);
        
        addObject(new Worm(), Greenfoot.getRandomNumber(560), Greenfoot.getRandomNumber(560));
        addObject(new Worm(), Greenfoot.getRandomNumber(560), Greenfoot.getRandomNumber(560));
        addObject(new Worm(), Greenfoot.getRandomNumber(560), Greenfoot.getRandomNumber(560));
        addObject(new Worm(), Greenfoot.getRandomNumber(560), Greenfoot.getRandomNumber(560));
        addObject(new Worm(), Greenfoot.getRandomNumber(560), Greenfoot.getRandomNumber(560));
        addObject(new Worm(), Greenfoot.getRandomNumber(560), Greenfoot.getRandomNumber(560));
        addObject(new Worm(), Greenfoot.getRandomNumber(560), Greenfoot.getRandomNumber(560));
        addObject(new Worm(), Greenfoot.getRandomNumber(560), Greenfoot.getRandomNumber(560));
        addObject(new Worm(), Greenfoot.getRandomNumber(560), Greenfoot.getRandomNumber(560));
        addObject(new Worm(), Greenfoot.getRandomNumber(560), Greenfoot.getRandomNumber(560));
        
    }
        public void nextLevel()
    { 
        
            addObject(new Lobster(), Greenfoot.getRandomNumber(560), Greenfoot.getRandomNumber(560));
            addObject(new Worm(), Greenfoot.getRandomNumber(560), Greenfoot.getRandomNumber(560));
            addObject(new Worm(), Greenfoot.getRandomNumber(560), Greenfoot.getRandomNumber(560));
            addObject(new Worm(), Greenfoot.getRandomNumber(560), Greenfoot.getRandomNumber(560));
            addObject(new Worm(), Greenfoot.getRandomNumber(560), Greenfoot.getRandomNumber(560));
            addObject(new Worm(), Greenfoot.getRandomNumber(560), Greenfoot.getRandomNumber(560));
            addObject(new Worm(), Greenfoot.getRandomNumber(560), Greenfoot.getRandomNumber(560));
            addObject(new Worm(), Greenfoot.getRandomNumber(560), Greenfoot.getRandomNumber(560));
            addObject(new Worm(), Greenfoot.getRandomNumber(560), Greenfoot.getRandomNumber(560));
            addObject(new Worm(), Greenfoot.getRandomNumber(560), Greenfoot.getRandomNumber(560));
            addObject(new Worm(), Greenfoot.getRandomNumber(560), Greenfoot.getRandomNumber(560));
            addAnimals = false;
        
    }

}
Gevater_Tod4711 Gevater_Tod4711

2013/8/25

#
The problem is in line 86 of your Crab class. Your method call CrabWorld.nextLevel(); is a static one but the method is not declared static. To fix this problem you can just change this line to:
((CrabWorld) getWorld()).nextLevel();
Because you are trying to call the method nextLevel as if it were a static method, which it is not. Instead of having a reference to your current crab world, you tried to do CrabWorld.nextLevel. To fix this, make sure that Crab has a reference to the current CrabWorld, or do cast the World provided from getWorld()
mrbones mrbones

2013/8/25

#
Wow thanks Gevater_tod4711 and FkyginRapidUnicornPig. It now works perfectly. However i'm still slightly confused. I understand that I can't call a static if it is not static, but the syntax is slightly confusing. Why is is it ((CrabWorld) getWorld()).nextLevel(); do the parentheses refer that it is not static?
Gevater_Tod4711 Gevater_Tod4711

2013/8/25

#
A static method is not declared public void but public static void (or private or anything else). This static methds can be called with just the classname + the method name (like CrabWorld.nextLevel();). A non static method has to be called throu the reference to the object. A static method doesn't need a reference because a static method or field is the same for all classes and doesn't change anything of the object. A non static method call has to be connected with the object you want to call this method for (the reference). In your case the reference is getWorld(). But getWorld() returns an object from type greenfoot.World and in the class greenfoot.World there is no method nextLevel. That method only exists in the CrabWorld method. Now because your world is a CrabWorld you can cast the World object that is returned from getWorld() to a CrabWorld and so you have the reference with the right type and you now can call the method nextLevel(). The (CrabWorld) is the cast. The part ((CrabWorld) getWorld()) casts the returned world to a CrabWorld (because of the brakets it's casted before the method is called. Now you have the objects reference which has the right type and you call the method nextLevel().
mrbones mrbones

2013/8/25

#
I see. Thanks for the help gevater_tod4711
You need to login to post a reply.