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

2015/3/22

Counter doesen't increase when item is collected

1
2
3
SalatgurkenJoe SalatgurkenJoe

2015/3/22

#
i want to increase a counter, if the actor collects an item. in my case ammunition, that he can shot. but it doesn't work, if i touch the item this comes up: java.lang.NullPointerException at Ammunition.collectAmmunition(Ammunition.java:30) at Ammunition.act(Ammunition.java:19) at greenfoot.core.Simulation.actActor(Simulation.java:594) at greenfoot.core.Simulation.runOneLoop(Simulation.java:552) at greenfoot.core.Simulation.runContent(Simulation.java:215) at greenfoot.core.Simulation.run(Simulation.java:205) this is my code from the item, maybe someone can help me.
import greenfoot.*;

/**
 * Write a description of class Ammunition here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Ammunition extends Items
{
    private Counter counter;
    /**
     * Act - do whatever the Ammunition wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        scrollingMethods();
        collectAmmunition ();
    }    

      public void collectAmmunition ()
    {
        
        Actor Player = getOneIntersectingObject (Player.class);
        if (Player != null)
        
        {
            World myWorld = getWorld();
            counter.add(3);
            myWorld.removeObject(this);

        }
        
    }
    
}
danpost danpost

2015/3/22

#
Line 11 defines a Counter field that is never assigned a Counter object. I presume you create and add one into the world in the world class.
SalatgurkenJoe SalatgurkenJoe

2015/3/23

#
now i added it in the world class. the problem doesn't appear anymore if i collect the item but my counter doesn't count either. This method is in the player class:
 public void collectAmmo ()
    {
        Actor ammo = getOneIntersectingObject (Ammo.class);
        if (ammo !=null)
        { 
            World myWorld=getWorld();
            counter.add(3);
            myWorld.removeObject(ammo);
            pickUpItem.play();
            
        }
    }
and this is my world class:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class World1 here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Level1 extends World
{
    GreenfootSound myMusic = new GreenfootSound ("BGMelodie.mp3");
    GreenfootSound PickUpItem = new GreenfootSound ("PickUpItem.mp3");
    GreenfootSound MenuTheme = new GreenfootSound ("MenuTheme.mp3");

    public Player Player;
    public Scroll theScroll;
    HealthBar healthbar = new HealthBar ();
    Counter counter = new Counter();
    
    
    public Level1()
    {    
        super(1000, 600, 1, false); //The extra 'false' parameter means that the world is unbounded.
        addTiles();
        Player = new Player(counter);
        addObject(Player, 70, 100); //Creates the player.
        theScroll = new Scroll();
        addObject(theScroll, 0, -10);
        prepare();
    }

    /**
     * Creates tiles for building your world.
     */
    public void addTiles()
    {
        for(int i=1;i<2;i++)
        {
            addObject(new Street1(), i*30 + 180, 600);
            addObject(new Street1(), i*30 + 600, 600);
            addObject(new Street1(), i*30 + 1110, 500);
            addObject(new Platform1(), i*30 + 1500, 305);
            addObject(new Platform1(), i*30 + 1800, 305);
            addObject(new Platform1(), i*30 + 2100, 245);
            addObject(new Street1(), i*30 + 2520, 500);
            addObject(new Street1(), i*30 + 2940, 500);
            addObject(new Platform1(), i*30 + 3330, 305);
            addObject(new Platform1(), i*30 + 3600, 215);
            addObject(new Platform1(), i*30 + 3900, 215);
            addObject(new Platform1(), i*30 + 4110, 215);
            addObject(new Wall1(), i*30 + 4410, 180);
            addObject(new Platform1(), i*30 + 3930, 365);
            
            

            
        }
    }

    /**
     * Creates enemies.
     * */

    public Player getPlayer()
    {
        return Player;
    }

    public Scroll getScroll()
    {
        return theScroll;
    }
    
    public HealthBar getHealthBar () //makes the player to be able to get the method
    
    {
        return healthbar; //Player can now call this method
    }
    
    public Counter getCounter()
    {
        return counter;
    }
    
    /**
     * Prepare the world for the start of the program. That is: create the initial
     * objects and add them to the world.
     */
    private void prepare()
    {
        for (int o=1;o<2;o++)
        {
            
            Counter counter = new Counter();
            addObject(counter, 54, 30);
            addObject (healthbar, 170, 30);
            addObject (healthbar, 200, 40);
            Enemy1 enemy1 = new Enemy1();
            addObject(enemy1, 246, 426);
            Enemy1 enemy12 = new Enemy1();
            addObject(enemy12, o+1200, 324);
            Sandwich sandwich2 = new Sandwich();
            addObject(sandwich2, 780, 400);
            Comet comet = new Comet();
            addObject(comet, o+1200, 324);


        }
        Music music = new Music();
        addObject(music, 937, 28);
    }
   
    
}
I don't know what's wrong in this code.
danpost danpost

2015/3/23

#
Line 18 assigns a Counter object to the 'counter' field; however, you create another Counter object on line 94 and add it into the world. So, 'counter' does not refer to the Counter object in the world. (you can just remove line 94 so that the pre-assigned 'counter' is added into the world on line 95)
SalatgurkenJoe SalatgurkenJoe

2015/3/23

#
thank you very much! that fixed the problem.
SalatgurkenJoe SalatgurkenJoe

2015/3/23

#
another question, do you know a posibility to reduce a counter for just one number if a special number is pressed. in my case, the counter decreases the number as long as the space key is pressed.
public void reduceAmmo()
    {
        if(Greenfoot.isKeyDown("space"))
        {
            if(counter.value >0)
            {
                counter.reduce(1);
            }
        }
    }
danpost danpost

2015/3/23

#
You can add a boolean field to track the state of the space key:
private boolean spaceDown;
Then use it to detect changes in the state of the key:
if (spaceDown != Greenfoot.isKeyDown("space"))
{
    spaceDown = ! spaceDown;
    if (spaceDown && counter.value > 0)
    {
        counter.reduce(1);
    }
}
SalatgurkenJoe SalatgurkenJoe

2015/3/24

#
works fine, thanks
Project Project

2015/3/25

#
I need help on a class project, and I can't figure out how to get the counter for my three Hearts to decrease, but I can get my score to increase. Here are two pictures of code from my Bug class, and one from my World or what I called my MazeWorld.
Project Project

2015/3/25

#
public class Bug extends Actor
{    
    //declare variable "score" of type ScorBoard()
    private ScoreBoard score;
    
    private HeartScore heart;
    //declare variable "counter" to increment score with each collision (see below) 
    private int counter = 0;
   
    private int counter2 = 3;
    
    int numEaten = 0;
    
    //int Heart = 3;
    // creates an instance of the ScoreBoard object and passes it to the Patrick class
    public Bug(ScoreBoard scoreboard)
    { 
        score = scoreboard;
    }       
    
    public Bug(HeartScore heartscore)
    {
        heart = heartscore;
    }
Project Project

2015/3/25

#
public void touchLizard()
        {
            Actor lizardlunch=getOneIntersectingObject(Lizard.class);
            if (lizardlunch !=null)
            {
                setLocation(46, 443);
                getWorld().addObject(new Cherries(), 250, 250);
                Greenfoot.setWorld(new MazeWorld());           
                getWorld().removeObjects(getWorld().getObjects(Home.class));
                
                
                MazeWorld w = (MazeWorld) getWorld();     //create an object of MazeWorld and cast getWorld to Mazeworld type
                //System.out.println("In touch lizard remove 1 Heart  ; ");
                //w.removeHeart(1);                          // call removeHeart from the MazeWorld Class
                              
               // counter=0;
                counter2=3;
                counter2--;
                //score.setText("Score: " + counter);
                heart.setText("Hearts: " + counter2);
                
            }
        }        
Project Project

2015/3/25

#
  public MazeWorld()
    {    
        super(500, 500, 1);
        levelOne();
        prepare();
        
        // create variable to hold ScoreBoard class
        ScoreBoard scoreboard = new ScoreBoard("Score:" + 0);
        // constructor for ScoreBoard class
        addObject(scoreboard, 54, 25);
        addObject(new Bug(scoreboard), 46, 443);
        setPaintOrder(Bug.class, Home.class);
        
        
        HeartScore heartscore = new HeartScore("Hearts:" + 3);
        addObject(heartscore, 54, 40);
        
        //setUpHeart(numHeart);
    }
Project Project

2015/3/25

#
Can someone please help me with this problem because I want to get closer to finishing this game?
danpost danpost

2015/3/25

#
Right now, you can only create a bug with either a ScoreBoard object OR a HeartScore object -- but not both. That is, you have one Bug constructor that receives one of the objects and another Bug constructor that receives the other object. You cannot call two constructors on the same Bug object creation. You can however, combine the two constructors into one:
public Bug(ScoreBoard scoreboard, HeartScore heartScore)
{
    score = scoreboard;
    heart = heartScore;
}
Then, in the MazeWorld world constructor, create the Bug object after the HeartScore object is created (as well as after the ScoreBoard object is created) and pass the HeartScore object in the Bug constructor call (as well as the ScoreBoard object).
danpost danpost

2015/3/25

#
Your 'touchLizard' method looks highly suspicious. You have the following inside the 'if' block (after all comments are removed):
setLocation(46, 443);
getWorld().addObject(new Cherries(), 250, 250);
Greenfoot.setWorld(new MazeWorld());           
getWorld().removeObjects(getWorld().getObjects(Home.class));
MazeWorld w = (MazeWorld) getWorld(); 
counter2=3;
counter2--;
heart.setText("Hearts: " + counter2);
The only line of code that really matters here is in line 3 -- setting a new MazeWorld active. The current world and all actors in it are destined for the GC (garbage collector) once the current act cycle completes. So, setting the location of the current actor in the current world is moot (line 1); adding new objects to the current world is pointless (line 2); likewise, removing objects from the current world (line 4); the comment you had for line 5 is not correct in that an object is not created -- a reference to the current world object is established and still, unless gathering information for the new world (which there is no established reference to), this reference is of no concern; lines 6 and 7 is excessive in that you can just say 'counter2 = 2;' -- but still, this 'counter2' field will soon be history; finally, the 'heart' object is also going bye-bye with the current world. In the end, the method is equivalent to this:
public void touchLizard()
{
    if (getOneIntersectingObject(Lizard.class) != null)
        Greenfoot.setWorld(new MazeWorld());
}
and all the values of all the objects in the old world will be re-initialized in new objects in the new world (like clicking the 'Reset' button).
There are more replies on the next page.
1
2
3