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

2013/10/18

When adding to statusboard when and object leaves the world.

Cyan002 Cyan002

2013/10/18

#
Hi guys, I'm needing some help again. I am trying to figure out how exactly to setup my counter properly. I want it to add to my "misses" when the cannonball I fire hits anything but the target. I have all of this in my world class
public int angle = 0;
public int power = 50;
public int misses = 0;

public void Spawn()
    {
        StatusBoard status = new StatusBoard();
        status.setValues(angle, power, misses);
        addObject(status, 50,90);
    }

public int getMisses()
    {
        return misses;
    }
    
    public void increaseMisses()
    {
        misses = misses + 1;
        statusBoard.setValues(angle, power, misses);
    }
In my cannonball class I have
public void cannonBallRemove()
    {
        World fodderWorld = getWorld();
        FodderWorld FodderWorld = (FodderWorld) getWorld();
        if ( getY() > fodderWorld.getHeight() )
        {
           FodderWorld.increaseMisses();
           fodderWorld.removeObject(this);
           return;
        }
    }
Currently I've come to an understanding that when the cannonball is fired it will check to see if it is in the world. Then if it is not because its hit the wall or hit the world's edge it should add 1 to the misses. If it didn't hit the wall or the world edge then it hit a target. Hitting the target will prompt the player to restart the game. So when I trying to fire the cannon ball and it does hit the world edge it gives me a null point exception error. Any help would be greatly appreciated.
Zamoht Zamoht

2013/10/18

#
Can you provide more code? For instance where in your code do you call cannonBallRemove() ? And you should be able to see where in the your code the nullPoint error occurs.
danpost danpost

2013/10/18

#
Your cannonBallRemove method seems a bit out of sorts. (1) there is no need for line 3 (since line 4 does the same while typecasting the world); (2) you should not use the exact class name as the name of the field (change field name to lowercase); (3) the condition on line 5 will only work if your world is not bounded (if you created it with 'false' as the last argument in the 'super' call in the world constructor); otherwise, use 'getX() == fodderWorld.getHeight()-1'; (4) the 'return' is not needed (there is no code to avoid after it) The method should be more like this:
public void cannonBallRemove()
{
    FodderWorld fodderWorld = (FodderWorld) getWorld();
    if (getY() > fodderWorld.getHeight()) // this may need changed, as per above
    {
        fodderWorld.increaseMisses();
        fodderWorld.removeObject(this);
    }
}
danpost danpost

2013/10/18

#
Cyan002 wrote...
Currently I've come to an understanding that when the cannonball is fired it will check to see if it is in the world. Then if it is not because its hit the wall or hit the world's edge it should add 1 to the misses. If it didn't hit the wall or the world edge then it hit a target. Hitting the target will prompt the player to restart the game.
If using this method to catch misses, there must be a cannonball in the world at all times except when it misses; this means you must add another cannonball into the world as soon as you find out there are none present. If this is what you want, then fine -- add an act method in the world class that checks to see if the list returned from 'getObjects' using 'Cannonball.class' as an argument is empty; and if so, add one to misses and add a new cannonball object into the world. If you do not add one immediately, your counter will skyrocket its value. However, I would not recommend this method of catching misses. I believe that actions should be taken at the time the event that causes them takes place. In this case, that would mean that as soon as the edge of the world is detected, the misses should be incremented and the object removed at that time (not later when the world realizes that -- 'OH NO, there are not any cannonballs present, let us play catch up!'). Now, I do not know what triggers the cannonballs to be fired to begin with, whether they are in the world before being fired, or much else about your scenario; but, the world can still use the fact that there are no cannonballs to create one (whether immediately or upon another action (such as a click of the mouse or press of a key) and that code would go in the act method of the world.
danpost danpost

2013/10/18

#
Cyan002 wrote...
So when I trying to fire the cannon ball and it does hit the world edge it gives me a null point exception error. Any help would be greatly appreciated.
Please supply the complete error trace (just saying you are getting an error really does not help). The error could be in your cannonball class, but it could also be in your world class (or even somewhere else). You are most probably getting this error because the cannonball was removed from the world, but to determine where your code is going amiss will require you to copy/paste the entire text from your terminal window to a posting here.
Cyan002 Cyan002

2013/10/21

#
Hi sorry I haven't been around all weekend. java.lang.NullPointerException at FodderWorld.increaseMisses(FodderWorld.java:50) at Brickwall.wallStop(Brickwall.java:27) at Brickwall.act(Brickwall.java:17) So that's the error that I have. It directs me to
public void increaseMisses()
    {
        misses = misses + 1;
        status.setValues(angle, power, misses);
    }
public int getMisses()
    {
        return misses;
    }
My variables
public int angle = 0;
    public int power = 50;
    public int misses = 0;
    
    private StatusBoard status;
    private FodderWorld FodderWorld;
How I'm placing the status board into the world
public void Spawn()
    {
        StatusBoard status = new StatusBoard();
        addObject(status, 50,90);
        status.setValues(angle, power, misses);
    }
Cyan002 Cyan002

2013/10/21

#
Just in case this is how I'm getting the ball to move
public class CannonBall extends Actor
{

    protected int xSpeed = 0;
    protected int ySpeed = 0;
    public static final int GRAVITY = 2;
    public CannonBall()
    {
    }
    
    public CannonBall(int angle, int power)
    {
        power = (power * 10) / 25;
        xSpeed = (int)(power*Math.cos(Math.toRadians(angle)));
        ySpeed = (int)(power*Math.sin(Math.toRadians(angle)));
    }
    
    public void act() 
    {
        setLocation(getX()+xSpeed,getY()-ySpeed);
        ySpeed = ySpeed - GRAVITY;
    }
Cyan002 Cyan002

2013/10/21

#
and this is all of my StatusBoard
public class StatusBoard extends Actor
{
    private static final String angleLabel = "Angle: ";
    private static final String powerLabel = "Power: ";
    private static final String missesLabel = "Misses: ";
    
    
    protected GreenfootImage background = null;
    
    public StatusBoard()
    {
        background = new GreenfootImage (100, 180);
        
        background.setColor(new java.awt.Color(255,255,255,200));
        
        background.fillRect (0,0, 150, 60);
        
        setImage(background);
        
    }
    
    public void setValues(int angle, int power, int misses)
    {
        GreenfootImage img = new GreenfootImage(background);
        img.setColor(java.awt.Color.BLACK);
        
        img.drawString(angleLabel + angle, 10, 20);
        img.drawString(powerLabel + power, 10, 35);
        img.drawString(missesLabel + misses, 10, 50);
        
        setImage(img);
    }
}
Cyan002 Cyan002

2013/10/21

#
I tried moving it around to see if that would help at all.
public void wallStop()
    {
        Actor cannonBall = getOneIntersectingObject(CannonBall.class);
        if(cannonBall!=null)
        {
            World fodderWorld = getWorld();
            FodderWorld Fodder = (FodderWorld) getWorld();
            Fodder.increaseMisses();
            Fodder.getMisses();
            fodderWorld.removeObject(cannonBall);
        }
    }
danpost danpost

2013/10/21

#
In your 'Spawn' method, remove the first 'StatusBoard' in line 3. With it there, you are creating a field that is local to the method with the same name as one of your class instance fields; so, your class instance field remains 'null'. By just using the name of the instance field, you set it to the new object being created. As an alternative, you can add the following line to be the last line in the 'Spawn' method:
this.status = status;
which sets the class instance field to the value of the field local to the method.
Cyan002 Cyan002

2013/10/22

#
So what you are saying is that I should do is that.
public void Spawn()  
    {  
        StatusBoard status = new StatusBoard();  
        addObject(status, 50,90);  
        setValues(angle, power, misses);  
    }  
Won't that make the setValues method inaccessible for the world? Also I tried placing in
this.status = status;
it just causes my miss counter to be constantly set to 0
danpost danpost

2013/10/22

#
Well, yes, I guess that would because for some reason you dropped the object ('status') from in front of the method call instead of dropping the 'StatusBoard' at the beginning of the line two before it.
public void Spawn()
{
    status = new StatusBoard();
    addObject(status, 50, 90);
    status.setValue(angle, power, misses);
}
Cyan002 Cyan002

2013/10/23

#
Oh I just realized what you meant by the third line. xD
You need to login to post a reply.