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

2017/8/26

Why are these errors being thrown?

t_k_990 t_k_990

2017/8/26

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

/**
 * Write a description of class MyWorld here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class MyWorld extends World
{
    /**
     * Constructor for objects of class MyWorld.
     * 
     */
    public MyWorld()
    {    
        super(600, 400, 1);
        addFlowers();
        flowerBlock2.cracked = false;
        scale();
        if(Rocket.shotsLeft == 0) {
            Rocket.shotsLeft = 10;
        }
        addRocket();
        GreenfootImage Img1 = new GreenfootImage("grass.jfif");
        GreenfootImage image = new GreenfootImage(Img1);
        setBackground(image);
    }
    public void addRocket() {
        addObject(new Rocket (), 306 ,350);
    }
    public void scale() {
        Bullet.imgg.scale(50, 50);
    }
    public void addFlowers() {
        addObject(new flowerBlock2 (), 51, 47);
    }
}
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot
/**
 * Write a description of class flowerBlock2 here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class flowerBlock2 extends Actor
{
    /**
     * Act - do whatever the flowerBlock2 wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
       CrackedFlower();
    }
    GreenfootImage img = new GreenfootImage("flower 2 no crack.png");
    GreenfootImage img2 = new GreenfootImage("change flower to png and make crack.png");
    static boolean cracked = false;
    public static int timesHit = 0;
    public void CrackedFlower() 
    {
        if(actor == null && cracked == false) {
            setImage(img);
            cracked = true;
        }
        if(actor != null || cracked == true) {
                setImage(img2);
                timesHit = timesHit +1;
            }
        if(timesHit >= 2) {
            getWorld().removeObject(this); //still shows error, 1 bullet counts as two shots
        }
    }
    Actor actor = getOneIntersectingObject(Bullet.class);
}
terminal window wrote...
at flowerBlock2.<init>(flowerBlock2.java:36) at MyWorld.addFlowers(MyWorld.java:36) at MyWorld.<init>(MyWorld.java:18)
danpost danpost

2017/8/26

#
The assignment of 'actor' on line 36 is attempted at the time a flowerBlock2 object is created (not every time you use 'actor' in your code). The created object is yet to be placed into a world at that time. Since you cannot call the 'getOneIntersectingObject' method while the object is not in the world, the error is produced. You could move line 36 to before line 24 to fix the issue; however, there are other things to be considered here. You have already noted the issue of one bullet causing multiple hits on the object. I will get back to that issue later. There is another issue which I should mention -- that of the one (single) 'cracked' value applying to all flowerBlock2 objects instead of each object having its own cracked value. The same can be said about 'timesHit'. Remove the 'static' modifier from lines 20 and 21 to correct this. You will also need to remove line 19 from the MyWorld class. Also, in the MyWorld class constructor (the constructor is above from lines 15 to 28), you have some other code which does not belong there. Scaling the size of the bullet image should be done in the Bullet class. Asking if rocket has no shots left is pointless here because the world is still being created and, not only that, the rocket has not even been placed into the world yet (not to mention that any rocket that might have been placed into the world would not have any time to act yet). Lines 25 through 27 is over-cooked coding:
// lines 25 through 27, as above
GreenfootImage Img1 = new GreenfootImage("grass.jfif");
GreenfootImage image = new GreenfootImage(Img1);
setBackground(image);

// is equivalent to
GreenfootImage Img1 = new GreenfootImage("grass.jfif");
setBackground(Img1);

// which is equivalent to
setBackground(new GreenfootImage("grass.jfif"));
Basically, your MyWorld code can be reduced to this:
import greenfoot.*; 

public class MyWorld extends World
{
    public MyWorld()
    {    
        super(600, 400, 1);
        addObject(new flowerBlock2(), 51, 47);
        addObject(new Rocket(), 306 ,350);
        setBackground(new GreenfootImage("grass.jfif"));
    }
}
Now, the Rocket and Bullet classes will still need some work (checking shots for rocket and sizing image of bullet). You will need to provide codes for them if you require help in fixing them. Back to the multiple hits by single bullet issue. Since only two hits are allowed before flowerBlock dies (it is removed from the world), we only need two states (one before the first hit and one before the second hit). Well, if we set 'actor' to the first bullet, then the two states can be 'null' or a bullet (the first encountered bullet) in the 'actor' field. By keeping a reference to the first bullet, we can avoid using it for multiple hits. In fact, you do not even require a 'timesHit' or a 'cracked' field. You never needed a 'cracked' field to begin with, as 'timesHit > 0' was always equivalent to the value of 'cracked'. I will provide a revised flowerBlock2 class code and show a better use of static fields along with:
import greenfoot.*;

public class flowerBlock2 extends Actor
{
    static GreenfootImage img2 = new GreenfootImage("change flower to png and make crack.png");
    Actor actor;

    public void act() 
    {
        Actor bullet = getOneIntersectingObject(Bullet.class);
        if (bullet != null && bullet != actor) // intersecting a new bullet
        {
            if (actor == null) // first bullet
            {
                actor = bullet;
                setImage(img2);
            }
            else // second bullet
            {
                getWorld().removeObject(this);
            }
        }
    }
}
Because all flowerBlock2 objects will use the same cracked image, it is okay to make the 'img2' field a static one. I removed the 'img' field altogether presuming that the default image for objects of the class would be set to that image anyway.
You need to login to post a reply.