问题
I have just started programming some things with Greenfoot, learning java along the way. I have become familiar on how to call certain methods between classes, and also differences between static and non-static.
I'm makeing a game where you play the crab and move around to collect worms. There is a lobster that randomly roams around and if comes in contact with the crab, the crab dissapears. Every time you eat a worm, the score goes up by 10.
It contains 5 classes named Crab, Lobster, Worm, Counter, and CrabWorld. For your sake, I'll just post the well documented code for you to read. But the important part that I am having trouble with is calling a method from the lobster to the Crab instance created by the CrabWorld. This method would change the lives of the crab.
I have tried calling ((CrabWorld) getWorld), but I don't need to access the CrabWorld. I need to access the Crab instance (created in the CrabWorld, if that matters) from from the Lobster Class.
Crabworld:
import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
/**
* Creates the crab Enviornment with a counter, crab and lobster. Also has methods to
* place random worms in the world over time. Also has a method to add the score
* To the Counter score
* @author Troy Bick
* @version 12/20/13
*/
public class CrabWorld extends World
{
private Actor playerCrab = new Crab();
private Counter score = new Counter("Score: ");
/**
* Constructor for objects of class CrabWorld.
*
*/
public CrabWorld()
{
super(560, 560, 1);
prepare();
}
/**
* Prepare the world for the start of the program. That is: create the initial
* objects and add them to the world.
*/
private void prepare()
{
addObject(score, 100, 540);
addObject(playerCrab, 280, 280);
addObject(new Lobster(), 100, 100);
}
/**
* Randomly places worms at random periods
*/
public void act()
{
if(Greenfoot.getRandomNumber(100)<0.5){
addObject(new Worm(), Greenfoot.getRandomNumber(540)+10, Greenfoot.getRandomNumber(540)+10);
}
}
public void eatenWorm()
{
score.add(10);
}
public void eatsCrab()
{
playerCrab.isEaten();
}
Crab:
import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
public class Crab extends Actor
{
private int wormsEaten = 0;
private int lives = 3;
/**
* Act - do whatever the Crab wants to do. This method is called whenever
* the 'Act' or 'Run' button gets pressed in the environment. Run calls Act every
* frame.
*/
public void act()
{
moveAndTurn();
eat();
}
/**
* Determines the key pressed and moves/turns the crab.
*/
public void moveAndTurn()
{
move(3);
if(Greenfoot.isKeyDown("a")){
turn(3);
}
if(Greenfoot.isKeyDown("d")){
turn(-3);
}
}
/**
* Detects if the worm is close to the crab, and if so, eats it.
*/
public void eat()
{
Actor worm;
worm = getOneObjectAtOffset(0,0,Worm.class);
World world = getWorld();
if(worm != null)
{
world.removeObject(worm);
Greenfoot.playSound("eating.wav");
wormsEaten++;
((CrabWorld) getWorld()).eatenWorm();
}
}
/**
* Returns the number of worms eaten.
*/
public int getWormsEaten()
{
return wormsEaten;
}
/**
* Returns the number the lives the crab has left.
*/
public int getLivesCount()
{
return lives;
}
/**
* Subtracts a life from lives.
*/
public void eaten()
{
lives--;
}
}
Lobster:
import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
/**
* Write a description of class Lobster here.
*
* @author (your name)
* @version (a version number or a date)
*/
public class Lobster extends Actor
{
/**
* Act - do whatever the Lobster wants to do. This method is called whenever
* the 'Act' or 'Run' button gets pressed in the environment.
*/
public void act()
{
moveAround();
eat();
}
public void eat()
{
Actor crab;
crab = getOneObjectAtOffset(0,0,Crab.class);
if(crab != null)
{
World world = getWorld();
world.removeObject(crab);
((CrabWorld) getWorld()).eatsCrab();
}
}
public void moveAround()
{
move(3);
//Random Movements
if(Greenfoot.getRandomNumber(100) < 10)
{
turn(Greenfoot.getRandomNumber(40) - 20);
}
//World Edge Detection
if(getX() <= 10 || getX() >= getWorld().getWidth()-10)
{
turn(10);
}
if(getY() <= 10 || getY() >= getWorld().getHeight()-10)
{
turn(10);
}
}
}
So when the lobster that has be added to the world eats the crab, I want that crab to lose a life, but when I try to compile, I get an error on the CrabWorld class that it could not find the method mentioned. Why is that?
Just very confused... If anyone could help me that would be great. If I'm missing anything, I fix it.
Thanks in advanced, Troy
回答1:
The problem you have is that in CrabWorld
you declare playerCrab
as
private Actor playerCrab = new Crab();
So although playerCrab is actually an instance of Crab, to CrabWorld it is an Actor and you can therefore only call the methods that Actor defines.
You could change your declaration to
private Crab playerCrab = new Crab();
That way CrabWorld knows that playerCrab
is an instance of Crab
and you can then call any of the public methods that Crab
defines. Given that your member variable is called playerCrab
it seems that you will always have it as a Crab
, so there it's certainly appropriate for it to be declared as one.
An alternative approach, if you control the Actor
type would be to add a loseLife()
method to it if you think that the concept of losing a life is common to classes that extend Actor
. Your Lobster
class doesn't have that concept at present, but if you were to decide to add that to it then a method on Actor
would be an appropriate way to do it.
回答2:
So it looks like you have a getWorld method in your Lobster class which I'm assuming gets the whole world. If you add a getCrab method in your CrabWorld then your lobster could access the crab.
Inside CrabWorld
public Crab getCrab(){
return playerCrab;
}
Then in Lobster
((CrabWorld) world).getCrab();
来源:https://stackoverflow.com/questions/20708443/calling-methods-from-other-classes-java