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

2017/3/7

Automatically changing & insert objects after.

1
2
OKNEM OKNEM

2017/3/7

#
Hello, so danpost recently assisted me with getting my health bar onscreen. I would now like to put in a Starting Screen. The first screen, which appears when you start the game, is called "Intro.class" and is supposed to stay there for five seconds, then automatically disappear. This reveals the second screen, "Rules.class" which stays there for 20 seconds. After they're both finished, the Asteroids now start spawning, the Rocket appears, the Counter appears and the Health bar appears. This is what I have for the prepare() method so far (the Rules and Intro picture fill the whole screen, that's why they're in the middle):
public void prepare()
    {
        Rules rules = new Rules();
        addObject(new Rules(), 400, 300);
        
        Intro intro = new Intro();
        addObject(new Intro(), 400, 300);
        
        // I need to put something to set the location of these two, something like a repeated setLocation? Not a major problem at the moment.
    }
In the Intro class (this is the delay, then the removal. I heard that you need to multiply the number of seconds by 60 to get this right?):
public void act() 
    {
        Greenfoot.delay(300);
        getWorld().removeObject(this);
    }   
In the Rules class (the delay, the removal and the insertion of the other objects):
private Health healthbar = new Health();
    private Counter theCounter;
    /**
     * Act - do whatever the Rules wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        Greenfoot.delay(1200);
            getWorld().removeObject(this);
            getWorld().addObject(healthbar,690,34);
            Rocket rocket = new Rocket();
            getWorld().addObject(new Rocket(270),410,510);
            theCounter = new Counter();
            getWorld().addObject(theCounter, 76, 30);
        
    }    
And I haven't attempted the Asteroid spawning delay yet. I don't think it's as easy as copying and pasting the whole method into the Rules class, so it's still in Space , like this (the delay is my attempt at stopping it from spawning until after the title screens, I don't think it's right):
 private int delayAsteroid=0;
    /**
     * Checks the delay of the Asteroid class, and if it's at zero, adds another Asteroid at a
     * an x coordinate of 40 degrees, and a random y coordinate.
     */
    public void act()
    {
        Greenfoot.delay(15000);
        
        if (delayAsteroid>0 && --delayAsteroid>0) 
        {
            return;
        }
        addObject(new Asteroid(), 30, (Greenfoot.getRandomNumber(570)));
        delayAsteroid = (Greenfoot.getRandomNumber(60));

    }
With all of this, there are no errors, but when I press Run and wait five seconds, a pentagonal turning symbol appears in the bottom right corner, near the classes. When I stop the game, one Asteroid appears (this is because there's no initial delay on the Asteroids spawning, so they'll spawn on the first act method) and an error message appears that says, "NullPointerException", with another red line that says "at Rules.act". Anyone know how to fix? Thanks in advance.
Super_Hippo Super_Hippo

2017/3/7

#
The error appears because in line 10 (in Rules), you remove the object from the world and then try to add objects to 'getWorld', but 'getWorld' returns 'null' because it is not in the world anymore. You can move that line to the end. I also don't think that the Rules class (which is just an image with the rules if I get this right), should save a reference to the counter and health bar. When the game runs, you don't want to use 'Greenfoot.delay' anymore because that pauses the whole scenario. So remove line 8 in the last code shown.
OKNEM OKNEM

2017/3/7

#
Awesome, this fixes it. I'm not sure how long the delays are for, though, is Greenfoot.delay(5); waiting for 5 milliseconds, 5 seconds? 5 act methods? 5 years? How long?
danpost danpost

2017/3/7

#
Out of curiosity, what does your Health class look like?
OKNEM OKNEM

2017/3/7

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

/**
 * Write a description of class Health here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Health extends Actor
{
    /**
     * Act - do whatever the Health wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {

    }

}
Awesome, am I right? Anyway, I ended up using a custom pause with private int pause = 100; for my delay. I delayed the Intro and Rules objects, and the stuff spawns in fine from the Rules class. What happens now is that another error comes when the Boop hits the Asteroid. It says another NullPointException at Boop.act and Boop.hit. Here are those codes:
public class Boop extends Thing
{
    // Setting the speed of the Boop, and the direction it fires.
    private int direction, speed;
    /**
     * Setting the speed and direction.
     */
    public Boop(int dir)
    {
        speed = 15;
        direction = dir;
    }

    /**
     * Executes the move and hitAsteroid methods.
     */
    public void act()
    {
        move();
        hit();
    }

    /**
     * Moves the Boop forwards at the set speed, which is 15.
     */
    public void move()
    {
        move(speed);
    }

    /**
     * This attempts to eat an Asteroid. If it does, it gets rid of the Asteroid
     * and the Boop. If it doesn't, it sees if it's at the edge of the world.
     */
    public void hit()
    {
        if(canSee(Asteroid.class))
        {
            Space spaceWorld = (Space) getWorld();
            Counter counter = spaceWorld.getCounter();
            counter.bumpCount(1);
            eat(Asteroid.class);
            getWorld().removeObject(this);
        }
        if(atWorldEdge())
                {
                    getWorld().removeObject(this);
                }
        }
    }
I'm presuming it's something to do with it's already out of the world?
danpost danpost

2017/3/7

#
OKNEM wrote...
I'm presuming it's something to do with it's already out of the world?
Correct. Use 'else if' on line 45.
OKNEM OKNEM

2017/3/7

#
if(canSee(Asteroid.class))
        {
            Space spaceWorld = (Space) getWorld();
            Counter counter = spaceWorld.getCounter();
            counter.bumpCount(1);
            eat(Asteroid.class);
            getWorld().removeObject(this);
        }
        else if(atWorldEdge())
        {
            getWorld().removeObject(this);
        }
Same error.
danpost danpost

2017/3/7

#
I see the Health class -- thanks. Now, how about the 'Thing' class -- what do you have there?
danpost danpost

2017/3/7

#
OKNEM wrote...
Same error.
Show the complete error trace and the entire Rocket class code.
OKNEM OKNEM

2017/3/7

#
import greenfoot.*;

/**
 * Rocket for my game.
 */
public class Rocket extends Thing
{
    // Delay variable.
    private int delayTimer = 20;
    
    /**
     * If the delay is not at zero, it takes off one. It then repeats this until it
     * gets to zero, in which another method is executed.
     */
    private boolean delay()
    {
        if(delayTimer >0) 
        {
            delayTimer--;
        }
        return delayTimer > 0;
    }

    /**
     * Act method - executes everything inside it when the Run or Act button is pressed.
     */
    public void act() 
    {
        checkKeys();
        fire();
    }

    /**
     * Resizes the Rocket and faces it upwards, as the original Rocket was spawned
     * facing right.
     */
    public Rocket(int direction)
    {    
        setRotation(270);
        GreenfootImage image = getImage();
        image.scale(115, 63);
        setImage(image);
    }

    public Rocket()
    {
    }

    /**
     * Move the Rocket using simple arrow key movement.
     */
    public void checkKeys()
    {
        if(Greenfoot.isKeyDown("left"))
        {
            turn(-7);
        }
        if(Greenfoot.isKeyDown("right"))
        {
            turn(7);
        }
        if(Greenfoot.isKeyDown("up"))
        {
            move(7);
        }
        if(Greenfoot.isKeyDown("down"))
        {
            move(-7);
        }
    }    

    /**
     * These are just methods to check parameters of the Rocket, for resizing purposes.
     */
    public int imageWidth()
    {
        GreenfootImage image = getImage();
        int x = image.getWidth()-45;
        return x;
    }
    public int imageHeight()
    {
        GreenfootImage image = getImage();
        int y = image.getHeight()-45;
        return y;
    }

    /**
     * Firing the bullet. If there is no delay, create a new Boop facing the rotation of the ship.
     * Reset the delay timer, too. Speed & movement of bullet is in Boop class.
     */
    public void fire()
    {
        if(!delay())
        {
            if (Greenfoot.isKeyDown("space"))
            {
                Actor blop = new Boop(getRotation());
                getWorld().addObject(blop, getX(), getY());
                blop.setRotation(getRotation());
                delayTimer = 20;
            }
        }
    }
}
I don't see how this has anything to do with the Boop? It might be something I don't know yet. Here's the error.
danpost danpost

2017/3/7

#
OKNEM wrote...
I don't see how this has anything to do with the Boop? It might be something I don't know yet.
You are right. I meant the entire Boop class. If you have changed the Boop class code since you copied the error trace, then I need to see a new error trace.
OKNEM OKNEM

2017/3/7

#
import greenfoot.*;  // Game, Boop, boop.png

/**
 * Boop is what the Rocket fires. Basically, the bullets.
 */
public class Boop extends Thing
{
    // Setting the speed of the Boop, and the direction it fires.
    private int direction, speed;
    /**
     * Setting the speed and direction.
     */
    public Boop(int dir)
    {
        speed = 15;
        direction = dir;
    }

    /**
     * Executes the move and hitAsteroid methods.
     */
    public void act()
    {
        move();
        hit();
    }

    /**
     * Moves the Boop forwards at the set speed, which is 15.
     */
    public void move()
    {
        move(speed);
    }

    /**
     * This attempts to eat an Asteroid. If it does, it gets rid of the Asteroid
     * and the Boop. If it doesn't, it sees if it's at the edge of the world.
     */
    public void hit()
    {
        if(canSee(Asteroid.class))
        {
            Space spaceWorld = (Space) getWorld();
            Counter counter = spaceWorld.getCounter();
            counter.bumpCount(1);
            eat(Asteroid.class);
            getWorld().removeObject(this);
        }
        else if(atWorldEdge())
        {
            getWorld().removeObject(this);
        }

        
    }
}
Here's the Boop class. And the error.
danpost danpost

2017/3/7

#
Okay. It is not because of removal of the boop. It is because 'theCounter' in your Space world is 'null' (probably because you are now adding it into the world from your Rules class, which you should not be).
OKNEM OKNEM

2017/3/7

#
Okay. How are you suggesting I fix this?
danpost danpost

2017/3/7

#
OKNEM wrote...
Okay. How are you suggesting I fix this?
Have the world control the Intro and Rules timing as well as the asteroids, health display and rocket.
There are more replies on the next page.
1
2