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

2015/2/18

Help starting next wave of enemies

DarkGhost DarkGhost

2015/2/18

#
I'm having some trouble starting the next wave of enemies when the player reaches a certain score. On level 1 I'm trying to get the second wave of enemies to appear when the player reaches 30 points. There's 3 enemies in wave 1, killing one of them gives the player 10 points so killing them all will give the player 30 points and starts wave 2. But it gives me a "java.lang.NullPointerException" error on line 44 of the Level1 class when I have the code in the act method of the Level1 class... My world Class:
public class Level1 extends World
{
    private Score score;

    public Level1()
    {    
        super(640, 640, 1); 

        stopMusic();

        started();

        addObject(new Player1(), 57,346);

        Score score = new Score();

        addObject(score, 573,19);

        // spawn enemies for Wave 1
        addObject(new ImageLabel("WAVE: 1"), 414, 20);

        addObject(new RahikiLvl1(score), 379, 348);

        addObject(new RahikiLvl1(score), 501, 62);

        addObject(new RahikiLvl1(score), 541, 575);
        //
    }

    public void act()
    {
        if (score.getValue() == 30)
        {
            wave2();
        } 
    }

    public void wave2()
    {
        // I need to add a code to remove the Wave:1 ImageLabel
        addObject(new ImageLabel("WAVE: 2"), 414, 20);

        addObject(new RahikiLvl1(score), 337, 559);

        addObject(new RahikiLvl1(score), 432, 84);

        addObject(new RahikiLvl1(score), 542, 348);
    }

    public void wave3()
    {
        // I need to add a code to remove the Wave:2 ImageLabel
        addObject(new ImageLabel("WAVE: 3"), 414, 20);

        addObject(new RahikiLvl1(score), 331, 61);

        addObject(new RahikiLvl1(score), 408, 573);

        addObject(new RahikiLvl2(score), 563, 233);
    }

    public void started()
    {
        Menu.Lvl1Music.playLoop();
    }

    public void stopped()
    {
        Menu.Lvl1Music.pause();
    }

    public void stopMusic()
    {
        if (Menu.TitleMusic.isPlaying()) Menu.TitleMusic.stop();
        if (Menu.Lvl2Music.isPlaying()) Menu.Lvl2Music.stop();
        if (Menu.Lvl3Music.isPlaying()) Menu.Lvl3Music.stop();
    }
}
Score class (by mik):
public class Score extends Actor
{
    private static final Color transparent = new Color(0,0,0,0);
    private GreenfootImage background;
    private int value;
    private int target;

    /**
     * Create a new counter, initialised to 0.
     */
    public Score()
    {
        background = getImage();  // get image from class
        value = 0;
        target = 0;
        updateImage();
    }
    
    /**
     * Animate the display to count up (or down) to the current target value.
     */
    public void act() 
    {
        if (value < target) {
            value++;
            updateImage();
        }
        else if (value > target) {
            value--;
            updateImage();
        }
    }

    /**
     * Add a new score to the current counter value.
     */
    public void add(int score)
    {
        target += score;
    }

    /**
     * Return the current counter value.
     */
    public int getValue()
    {
        return value;
    }

    /**
     * Set a new counter value.
     */
    public void setValue(int newValue)
    {
        target = newValue;
        value = newValue;
        updateImage();
    }

    /**
     * Update the image on screen to show the current value.
     */
    private void updateImage()
    {
        GreenfootImage image = new GreenfootImage(background);
        GreenfootImage text = new GreenfootImage("" + value, 22, Color.BLACK, transparent);
        image.drawImage(text, (image.getWidth()-text.getWidth())/2, 
                        (image.getHeight()-text.getHeight())/2);
        setImage(image);
    }
}
danpost danpost

2015/2/18

#
You never assign a value to the 'score' field declared on line 3 and try to execute 'getValue' on it (on a 'null' object) on line 32. On line 15, you are creating a new local variable called 'score', which is not the 'score' field declared on line 3. Remove 'Score' from that line and 'score' will then refer to the field declared on line 3.
DarkGhost DarkGhost

2015/2/18

#
Awesome that worked, just one problem it get's stuck in a loop and runs the wave2 method over and over spawning loads of enemies. I tried adding a return value after line 46 and at the end of the wave2 method but that didn't work.
danpost danpost

2015/2/18

#
DarkGhost wrote...
Awesome that worked, just one problem it get's stuck in a loop and runs the wave2 method over and over spawning loads of enemies. I tried adding a return value after line 46 and at the end of the wave2 method but that didn't work.
Yeah. Until your score changes again, it will continue to add new enemies. I would suggest that instead of using the score, use the number of enemies in the world:
// in act of world class
if (getObjects(RahikiLvl1.class).isEmpty()) nextWave();
// add the following method to the world class
private void nextWave()
{
    wave++;
    switch(wave)
    {
        case 1: wave1(); break;
        case 2: wave2(); break;
        // etc.
        case default: Greenfoot.stop(); break;
    }
}
// add the following field to the world class
private int wave;
DarkGhost DarkGhost

2015/2/18

#
That sounds like a much better idea than using the score :) I get an "illegal start of expression" at the 'default' on line 12 of the code you sent. :/
danpost danpost

2015/2/18

#
DarkGhost wrote...
I get an "illegal start of expression" at the 'default' on line 12 of the code you sent. :/
Ok. Remove the word 'case' before 'default'. It should be:
default: Greenfoot.stop(); break;
DarkGhost DarkGhost

2015/2/18

#
Awesome that works brilliantly! Thank you so much for your help! :D
You need to login to post a reply.