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

2023/4/15

Can sombody tell me why the game does not work in the second space world?

stijn.b stijn.b

2023/4/15

#
java.lang.ClassCastException: class Space2 cannot be cast to class Space (Space2 and Space are in unnamed module of loader java.net.URLClassLoader @1248ed9) at Shot.updateScore(Shot.java:54) at Shot.doShotThings(Shot.java:33) at Shot.act(Shot.java:22) at greenfoot.core.Simulation.actActor(Simulation.java:567) at greenfoot.core.Simulation.runOneLoop(Simulation.java:530) at greenfoot.core.Simulation.runContent(Simulation.java:193) at greenfoot.core.Simulation.run(Simulation.java:183)
stijn.b stijn.b

2023/4/15

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

public class Shot  extends Actor
{
    // field with the Objectreference to the rocket that shot me
    private Rocket myship;

    public Shot(Rocket myShip)
    {
        this.myship = myship;
    }
    public void act() 
    {
        doShotThings();
    } 

    public void doShotThings() {
        int ypos = getY();
        if (ypos > 0) {
            ypos = ypos - 5;
            setLocation(getX(), ypos);
            Actor rock = getOneIntersectingObject(Asteroid.class);
            if (rock != null) {
                // We've hit an asteroid!
                updateScore();
                getWorld().removeObject(rock);
                getWorld().removeObject(this);
            }
        }
        else {
            // I reached the top of the screen
            getWorld().removeObject(this);
        }
    }
    private void updateScore()
    {
       //4: Hier maak je eerst een Objectreferentie naar de Spacewereld. Daar vraag je dan de getCounter methode op. 
        Space space = (Space) getWorld();
        space.getCounter(); 
    }
}
Spock47 Spock47

2023/4/15

#
The error message tells you "class Space2 cannot be cast to class Space". Let's see what that means: Casting can only be done for compatible types/classes. A variable always has a static type, i.e. it is what the compiler knows the object to be. E.g. for "final Actor rocket;" the compiler knows that "rocket" has static type "Actor". Also, the variable's value has a dynamic type, i.e. what the object really is. E.g. for "final Actor rocket = new Rocket();", rocket has dynamic type "Rocket". However, the compiler will only allow to call operations/methods of the static type of the variable. E.g. if type "Rocket" has a method "fly", for the variable "final Actor rocket = new Rocket();", the compiler will not allow you to call "rocket.fly();" because the compiler only knows it to be an Actor, but does not know that it is a Rocket. That's where a cast is used. A cast is an operation to tell the compiler additional knowledge about the type of the variable, so that the compiler considers it as its static type. E.g. "(Rocket)rocket" says "Believe me, compiler, I know rocket is actually a Rocket, not only an Actor. So, accept its static type as Rocket!" After that you can call fly-method on the "casted" variable:
final Rocket reallyARocket = (Rocket)rocket;
reallyARocket.fly();
However, if the information you give to the compiler with the cast is untrue, a ClassCastException will be thrown. E.g. "(Dog)rocket" will fail, because a Rocket is not a Dog. The compiler will say something like "java.lang.ClassCastException: class Rocket cannot be cast to class Dog". And that's exactly what happened in your case: Space2 objects are not of type Space. I would like to give you more insight about it with your own source code, but you haven't provided source code of Space 2 or the actual line where the error happened: The source code you posted is not the up-to-date source code for your error message: The error message says the problem is in method updateScore 21 lines (54-33) below from where it was called. Update score is called in line 25, but there isn't even a line 46 (25+21) in the source code you presented. However, it is probably the line
Space space = (Space) getWorld();
If the shot is currently in a world of type Space2, the cast "(Space) getWorld()" would result in said ClassCastException (if Space2 does not extend Space).
stijn.b stijn.b

2023/4/15

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

public class Space2 extends World
{
    
   //1: hier een veld maken die de Objectreferentie naar de Counter kan opslaan
    private Counter counter;
    
    /**
     * Constructor for objects of class Space.
     */
    
    public Space2()
    {    
        // Create a new world with 600x400 cells with a cell size of 1x1 pixels.
        super(600, 400, 1); 
        addObject(new Rocket(), 300, 340);
        //2: hier de Objectreferentie van 1: gebruiken om een nieuwe counter te maken
        counter = new Counter();
        addObject(counter, 20,20);
        
    }

    
        //3: hier maak je een methode die de counter ophaalt.
        // Noem de methode maar: public Counter getCounter()
    public void getCounter() {
        counter.bumpCount(0);
        }
        
    
    /**
     * Prepare the world for the start of the program. That is: create the initial
     * objects and add them to the world.
     */
    private void prepare()
    {
    }
    
    public void act()
    {
       spawnAsteroid();
    }
    public void spawnAsteroid() {
         if (Greenfoot.getRandomNumber(1000) < 3) {
            addObject(new Asteroid(), 0, 20);
        }
    }
    public class Counter  extends Actor
    
    {
    private int totalCount = 0;

    public Counter()
    {
        setImage(new GreenfootImage("0", 20, Color.WHITE, Color.BLACK));
    }

    /**
     * Increase the total amount displayed on the counter, by a given amount.
     */
    public void bumpCount(int amount)
    {
        totalCount += amount;
        setImage(new GreenfootImage("" + totalCount, 20, Color.WHITE, Color.BLACK));
        if (totalCount >= 10) {
        Greenfoot.setWorld(new Tussenscherm());
        }
    }
    }
}
Spock47 Spock47

2023/4/15

#
ok, replace the complete source code of Space2 with this:
public class Space2 extends Space {}
This is under the assumptions that 1. currently your Space2 class is identical to your Space class, 2. you plan to add things to Space2. If on the other hand, only assumption 1 is correct, but number 2 is incorrect (i.e. you plan that Space2 will stay identical to Space), you can just delete class Space2 and change line 18 of your Timer class to
if (timer <= 0) { Greenfoot.setWorld(new Space()); }
danpost danpost

2023/4/15

#
One way to "fix" it is as follows (in Shot class):
private void updateScore()
{
    //4: Hier maak je eerst een Objectreferentie naar de Spacewereld. Daar vraag je dan de getCounter methode op. 
    if (getWorld() instanceof Space) {
        Space space = (Space)getWorld();
        space.getCounter();
    }
    else if (getWorld() instanceof Space2) {
        Space2 space2 = (Space2)getWorld();
        space2.getCounter(); 
    }
}
Although there is probably an easier way -- like having an intermediate class between World and the two space worlds (maybe called SpaceWorld). Remove all counter stuff from the two space worlds and put them in this intermediate class; Then, the shot will always be in some SpaceWorld world (with Space and Space2 extending SpaceWorld). So:
private void updateScore() {
    ((SpaceWorld)getWorld()).getCounter();
}
You need to login to post a reply.