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

2014/5/21

Refreshing the score on screen

SullyFish SullyFish

2014/5/21

#
so I have a problem with getting the score to update in the background. It works fine otherwise to count and such but I dont know how to update it. Please and thank you! this is the background, and Kunai is the class that counts the kills
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.awt.Color;
/**
 * Write a description of class Floor here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Floor extends World
{
     public Bar bar = new Bar("Ninja", "Health Points", 20, 20);
     private int startEnenemies = 1;
     public int players;
     public Kunai kunai;
     private int Points = kunai.Kills;
     GreenfootImage bg = getBackground();
    /**
     * Constructor for objects of class Floor.
     * 
     */
    public Floor()
    {    
        // Create a new world with 600x400 cells with a cell size of 1x1 pixels.
        super(1200, 800, 1); 
        
        bg.setColor(Color.BLACK);
        
        Score();
        Killing();
     
        addEnnemies(startEnenemies);
        addObject(new Ninja(),500,500);
        addObject(bar, 1000, 740);
        addObject(new Bat(), 520,450);
    }
     private void addEnnemies(int count) 
    {
        for(int i = 0; i < count; i++) 
        {
            int x = Greenfoot.getRandomNumber(getWidth()/2);
            int y = Greenfoot.getRandomNumber(getHeight()/2);
            addObject(new Ennemies(), x, y);
        }
    }
    public void act()
        {
        if (Greenfoot.getRandomNumber(200) == 0)
                {
                    addObject (new Ennemies(), Greenfoot.getRandomNumber(600) + 20, Greenfoot.getRandomNumber(440) + 20);
                }
                {
        if (bar.getValue() == bar.getMinimumValue())
        {
            if (getObjects(GameOver.class).isEmpty()) showGameOver();
            return;
        }
        }
        }
    private void showGameOver()
        {
         addObject(new GameOver(), getWidth() / 2, getHeight() / 2);
         Greenfoot.stop();
        }
    public int Score ()
     {
     return Points;
     }
     public void Killing()
     {
       bg.drawString("Kills " + Points , 1050,100);
     }
}
The Kunai class in case you wanted to see it
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class Kunai here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Kunai extends SmoothMover
{
    /** The damage this bullet will deal */
    private static final int damage = 50;
    public static int Kills;
    /** A bullet looses one life each act, and will disappear when life = 0 */
    private int life = 40;
    
    public Kunai()
    {
    }
    
    public Kunai(Vector speed, int rotation)
    {
        super(speed);
        setRotation(rotation);
        addForce(new Vector(rotation, 15));
    }
    
    /**
     * The bullet will damage asteroids if it hits them.
     */
    public void act()
    {
        if(life <= 0) {
            getWorld().removeObject(this);
        } 
        else {
            life--;
            move();
            checkEnnemiesHit();
        }
    }
    
    /**
     * Check whether we have hit an asteroid.
     */
    private void checkEnnemiesHit()
    {
        Ennemies ennemies = (Ennemies) getOneIntersectingObject(Ennemies.class);
        if (ennemies != null){
            getWorld().removeObject(this);
            ennemies.hit(damage);
            Kills = Kills + 1;
            System.out.println(Kills);
        }
    }
}
danpost danpost

2014/5/21

#
Because 'Kills' is a 'public static' field in the Kunai class, you do not need to do anything special to get its value from another class. Also, if you look at line 15 in your Floor class, you should note that the 'Points' field is assigned its value when the world object is created (it is never re-assigned a new value or modified in any way). Plus, you should avoid having more than one field in a project trying to hold the same value (ie. 'Points' and 'Kills' in the two different classes). Next, line 28 in the Floor class calls a method that returns the value stored in 'Points'; but nothing is done with the value (it goes to never-never land -- immediately; it has no bearing on what line 29 does at all, if that is what you were thinking). That brings us to the method that line 29 calls, the 'Killing' method. I will presume that this method will be called at least any time the value of 'Kills' in the Kunai class changes. But, each time you draw a new string onto the background image, you will be drawing over the previously drawn strings, making a mix of the digits in the score. You need to refill the area (or the entire background) with its original image before drawing the updated string. With what you have now, you can remove from the Floor class the following lines: lines 14 and 15, line 28, and lines 64 through 67. Then change the 'Killing' method to this:
public void Killing()
{
    GreenfootImage bg2 = new GreenfootImage(bg); // create a new clean background image
    bg2.drawString("Kills "+Kunai.Kills, 1050, 100); // draw the string on image
    setBackground(bg2); // set the new image as the background image of the world
}
Now, you will want to call this method from the 'checkEnnemiesHit' method of the Kunai class. So, change line 53 to this:
((Floor)getWorld()).Killing();
You will also need to add at line 27 of your Floor class the following line:
Kunai.Kills = 0;
otherwise, the value of 'Kills' will carry over into subsequent games because it is 'static'.
SullyFish SullyFish

2014/5/22

#
Okay I added the code and Im getting this error java.lang.NullPointerException at Kunai.checkEnnemiesHit(Kunai.java:42) at Kunai.act(Kunai.java:32) at greenfoot.core.Simulation.actActor(Simulation.java:507) at greenfoot.core.Simulation.runOneLoop(Simulation.java:470) at greenfoot.core.Simulation.runContent(Simulation.java:204) at greenfoot.core.Simulation.run(Simulation.java:194)
danpost danpost

2014/5/22

#
You will need to post your current code for the 'checkEnnemiesHit' method.
SullyFish SullyFish

2014/5/23

#
    private void checkEnnemiesHit()
    {
        Ennemies ennemies = (Ennemies) getOneIntersectingObject(Ennemies.class);
        if (ennemies != null){
            getWorld().removeObject(this);
            ((Floor)getWorld()).Killing();  
            ennemies.hit(damage);
            Kills = Kills + 1; 
        }
    }
danpost danpost

2014/5/23

#
Move line 5 to the end of the 'if' block.
SullyFish SullyFish

2014/5/27

#
alright thank you I ended up changing it so that the enemies were 2 hits to kill and I almost got the counter to work but it counts the next shot after the kill as the kill and I tried moving around the coding to make it work but it just gives me errors! what do I change now?
    private void checkEnnemiesHit()
    {
        Ennemies ennemies = (Ennemies) getOneIntersectingObject(Ennemies.class);
        if (ennemies != null){

            ennemies.hit(damage);
            ((Floor)getWorld()).Killing(); 
            getWorld().removeObject(this);
            if(ennemies.stability <= 0)
            {
            Kills = Kills + 1; 
            }
            
        }
    }
danpost danpost

2014/5/27

#
You should have the 'hit(int)' method in the Ennemies class return a boolean to indicate whether it was a kill hit or not: public boolean hit(int damage) >>>> if (stability <= 0) { getWorld().removeObject(this); return true; } else return false; Then change line 6 above to: if (ennemies.hit(damage)) { Kills = Kills+1; ((Floor)getWorld().Killing(); }
SullyFish SullyFish

2014/5/28

#
Thank you it works great
danpost danpost

2014/5/28

#
I should have thought of this before -- an easier way. Since the enemy is removed from the world if it is a kill hit, you do not have to return the boolean; just check to see if it is still in the world:
ennemies.hit(damage);
if (ennemies.getWorld() == null)
{
    Kills = Kills+1;
    ((Floor)getWorld()).Killing();
}
getWorld().removeObject(this);
You need to login to post a reply.