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

2019/11/7

Please help me with my assignment

addia addia

2019/11/7

#
I'm making an asteroid/spaceship game for my game programming class and I need to make the asteroid disappear after being hit twice. This is the code for my Bullet class:
public void act() 
    {
        super.act();
        Actor asteroid = getOneIntersectingObject(Asteroid.class);
        int counter = 0;
        if (asteroid != null)
        {
            counter++;
            if (counter == 2)
            {
                SimulationWorld world = (SimulationWorld) getWorld(); // Simulation World is a Class the teacher made for us
                world.removeObject(asteroid);
            }
        }
    }
If I remove the counter and just have the asteroid removed from the world after being shot once, it works. It's only when I add the ifs that it doesn't seem to work. Thanks for the help.
nccb nccb

2019/11/7

#
Your counter variable is declared inside the act method. That means that after the method exits, the variable and its value is forgotten. So it can never reach 2, as it always starts at 0 and maybe gets incremented once. The usual solution to this is to move the variable into the class (making it known as a field) so that it is remembered for the lifetime of the object. However -- that means the bullet will count how many times and it hits an asteroid, and when the bullet hits a second asteroid it will remove it. I don't think this is what you want. So you need to store the count in the asteroid. Then you either need to get the bullet to update the count, or perhaps easier is to move this collision detection into the asteroid to detect when it hits a bullet, and then the asteroid can update its own count.
danpost danpost

2019/11/7

#
Logic flaw: line 5 sets counter to zero, followed by possibly having it incremented by one once by line 8, upon which its value will never be 2 at line 9. Scope flaw: being counter is declared within the act method, it will not be retained between act steps The variables existence only lasts for that execution of the method and is lost when the method is exited. Placement error: it makes no sense to even have a counter variable that is to track how many times an asteroid is hit in the Bullet class. An int value does not even retain which asteroids may have been hit. Now, if each asteroid in itself retained how many times it was hit, that would make more sense. I would suggest you remove the "bullet hits asteroid" checking from the Bullet class (lines 4 thru 14) and have the asteroids check for bullets. Now, there still is a problem to deal with. Since you are not removing bullets from the world upon hitting an asteroid, the same bullet will probably be detected touching the same asteroid on consecutive act steps, meaning an int counter field would not be sufficient. However, an Actor field just might do, initially set to null. If null when a bullet is detected, set it to that bullet. If NOT null AND NOT set to bullet touching, remove the asteroid.
addia addia

2019/11/8

#
Yup! I ended up solving it and here is the code I wrote (ended up writing it in the Asteroid class):
public void disappear()
    {
        Actor bullet = getOneIntersectingObject(Bullet.class);
        SimulationWorld world = (SimulationWorld) getWorld();
        if (bullet != null)
        {
            counter++;
            world.removeObject(bullet);
            if (counter == 2)
            {
                world.removeObject(bullet);
                world.removeObject(this);
            }
        }
    }
I made the variable "counter" outside of the method like suggested. Thanks for all the help!
addia addia

2019/11/9

#
Hello again, I ran into another issue with my code and I'm really stuck on this one. Once the spaceship collides with the asteroid, the game is lost and you get transferred to the end screen of the game with your score displayed on the screen. I don't know how to get the score from one world to another. The score itself is an Actor class I created:
private double score = 0.0;
    public void act() 
    {
        World world = getWorld();
        List<SpaceShip> spaceShipList = world.getObjects(SpaceShip.class);
        if (spaceShipList.size() > 0)
        {
            SpaceShip spaceShip = spaceShipList.get(0);
            int score = (int) spaceShip.getPosition().getY() + 5;
            setImage(new GreenfootImage("Score: "  + score + " ", 30,
                                        Color.WHITE, Color.BLACK)); 
        }
    }
And this is how I end my game:
List<SpaceShip> list = getObjects(SpaceShip.class);
if (list.size() == 0)
        {
            timeUntilTransition -= getTimeStepDuration();
            if (timeUntilTransition < 0)
            {
                transitionToWorld(new EndWorld());
                music.stop();
            }
        }
In my SpaceWorld (World), I detect if there is a spaceship or not. How may I solve this problem?
addia addia

2019/11/9

#
My classmate told me about using the showText method of showTitle in my end game screen; I can't quite remember exactly what it was though... By the way, the my code works and all, it's just that I have one more thing to do for my assignment which is to display the score on the end screen and I have no clue how to do that. I appreciate all the help.
danpost danpost

2019/11/9

#
It would help to have a reference to your EndWorld world in your end game code. Split line 7 up to be:
EndWorld endWorld = new EndWorld();
transitionToWorld(endWorld);
Now you can continue with showText to that world.
addia addia

2019/11/9

#
I figured out sort of how to transfer information from one world to another but I'm not quite sure what I'm doing... This is the code in my SpaceWorld act():
List<SpaceShip> spaceShipList = getObjects(SpaceShip.class);
List<PlayerScore> playerScoreList = getObjects(PlayerScore.class);
int score = playerScoreList. // any idea what method I should use?
        if (spaceShipList.size() == 0)
        {
            timeUntilTransition -= getTimeStepDuration();
            if (timeUntilTransition < 0)
            {
                EndWorld endWorld = new EndWorld(score);
                transitionToWorld(endWorld);
                music.stop();
            }
        }
This is the code in my EndWorld right now:
public EndWorld(int score)
    {
        super ("endMenu.wav", 800, 600, new Point2D(0.0, 0.0), 20);
        showText(score, 200, 200);
    }
danpost danpost

2019/11/10

#
addia wrote...
List<SpaceShip> spaceShipList = getObjects(SpaceShip.class);
List<PlayerScore> playerScoreList = getObjects(PlayerScore.class);
int score = playerScoreList. // any idea what method I should use?
if (spaceShipList.size() == 0)
{
    timeUntilTransition -= getTimeStepDuration();
    if (timeUntilTransition < 0)
    {
        EndWorld endWorld = new EndWorld(score);
        transitionToWorld(endWorld);
        music.stop();
    }
}
In the quoted code, you do not need the score until after line 8. Maybe you can work with the following:
if (getObjects(SpaceShip.classs).isEmpty())
{
    timeUntilTranssition -= getTimeStepDuration();
    if (timeUntilTransition < 0)
    {
        PlayerScore playerScore = (PlayerScore)getObjects(PlayerScore.class).get(0);
        int score = // maybe you can finish this now
        TransitionToWorld(new EndWorld(score));
        music.stop();
    }
}
You need to login to post a reply.