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

2013/4/16

Setting the score through different worlds

1
2
welleid welleid

2013/4/16

#
Hey I have a problem, I set a Score counter in my world, and it works well (inspired from the counter of the tutorial, with the rocket), the problem is when I try to add it in the next level, the value goes back to 0. Here is how I did, I set a subclass for all the levels (2 at the moment), with the method for the variable in it.
public Score getScore() 

    {
        return theScore;
    }
Then I simply add the new Score (Score.class)
//In first world, where everything goes well
 theScore = new Score();
        addObject(theScore, 100, 640);

//The method to do the score, what you'll find in an actor Class to score

public void doTheScore( int amountOfScore)
    {       
        
        WMethod wmethod = (WMethod) getWorld();
        Score score = wmethod.getScore();
            
        score.getTheScore(amountOfScore);
    }//WMethod is the world subclass

//How I try to add it in second level (name Espace3)

//First I try the same way as before, but it doesnt work
        //theScore = new Score();

//Then I try this, i found it on a topic, but doesnt work. give me an error message
Score score = (Score)getObjects(Score.class);
        addObject(score, 100, 640);
I found the second try here : http://www.greenfoot.org/topics/1057 It was like that : Timer timer = (Timer) getWorld().getObjects(Timer.class).get(0); I tried to set it so it works in my worlds, but the get(0) is a problem. whatever is the value, I get an rror message. Thanks a lot !
Gevater_Tod4711 Gevater_Tod4711

2013/4/16

#
Probably the problem in line 22 is that there is no score object in the world. The method getObjects(java.lang.Class clss) returns a java.util.List. Using .get(0) you try to get the first object of this list. But if there is no object in the list you get an error. I think it would be easyer to set the new score in the constructor of the new world. Therefor you have to add a parameter to the world constructor (an integer) where you can transfer the value of the score. In the world constructor you now know the score and you can set the score of your counter to the last known score.
welleid welleid

2013/4/16

#
I dont really understand what you mean. I add the Score in the constructor of the second level, name Espace3 (the constructor is the place where you put your source code isnt it?). And I dont really understand how you would add an integer (a parameter?) in a class. Thanks a lot !
Gevater_Tod4711 Gevater_Tod4711

2013/4/16

#
Your current constructor of the world probably looks like this:
public Espace3() {
    //some other stuff;
}
With an integer as parameter it should look like this:
public Espace3(int currentScore) {
    Score score = new Score();
    score.setScore(currentScore); //not shure if this is the right method name;
    addObject(score, x, y);
}
Gevater_Tod4711 Gevater_Tod4711

2013/4/16

#
I forgot to say: You need to change the setWorld method call a bit: If you now got Greenfoot.setWorld(new Espace3()); you now need Greenfoot.setWorld(new Espace3(score)); Instead of 'score' you have to add the current score.
welleid welleid

2013/4/16

#
Okay thanks, but the problem is that to go to the next level, you have to clic a button.
if("Espace3".equals(thisW))
            {
                WMethod wmethod = (WMethod) getWorld();
                int leScore = wmethod.theScore;

                
                //int scoreActuel = getWorld().getScore();
                Greenfoot.setWorld(new Espace3(leScore) );
            }
And as you can see i am currently having problem to get the score in a variable^^''
welleid welleid

2013/4/16

#
Ok so I improved that by setting the button as a superclass of the Score, so I can access its variable of score. Now I have another problem, in the second level, i get an error message java.lang.NullPointerException whenever i call the method to score from the Movers.class
Gevater_Tod4711 Gevater_Tod4711

2013/4/17

#
Probably that consists of a problem with the new score counter. Could you post the code please.
danpost danpost

2013/4/17

#
welleid wrote...
Ok so I improved that by setting the button as a superclass of the Score, so I can access its variable of score.
That is not an improvement. Button objects are not Score objects and the Button class should not be a subclass of the Score class. There are various ways that can be used to transfer the score from one world to another. The two main ways are listed below. (1) By passing either the score object or the score itself in the constructor parameter (as being given by Gevater_Tod4711); (2) By setting the score object or the score itself from the old world when you create the new world. I do prefer the second way (only because it avoids passing parameters).
if("Espace3".equals(thisW))
{
    Score scoreObj = (Score) getWorld().getObjects(Score.class).get(0); // get score object
    Espace3 e3 = new Espace3(); // create new world
    e3.addObject(scoreObj, scoreObj.getX(), scoreObj.getY()); // transfer score object
    Greenfoot.setWorld(e3); // set new world to activate
}
Line 5 places the score counter in the same place in the new world as it was in the old world. Of course, you can use a different location if you wanted to.
davmac davmac

2013/4/17

#
Ok so I improved that by setting the button as a superclass of the Score, so I can access its variable of score.
Trust me, that's the wrong solution. When you make some class a subclass of another, you don't give it access to the variables of some instance of the superclass - you just effectively make the subclass have variables with the same names; they are still different variables with different values. From your description, I'm not really sure what's wrong, but you're not very clear on some things. If line 22 doesn't work, it means you don't actually have a Score in the world. Lines 22 and 23 together don't make sense - line 22 tries to find a score object that's already in the world, and line 23 tries to add that score object into the world (even though it must already be in the world). What class are these lines in?
welleid welleid

2013/4/17

#
Ok, improved was certainly not the word to use. I should have used the word "changed in a way that should work" but english is not my first langage, sorry^^'' In fact, i took everything from the beginning, and I saw that I didnt need all those things to set up the new Score counter in the new world. As the method in a subclass of both world, I just add a new counter in Espace3, and calls the method. Strange, but it actually works. Dont know how, dont know why. Now I used Danpost's method, but I still have this error message null.pointer... Here is all the code related to this Counter : The button :
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.awt.Color;  
import java.awt.Font;

/**
 * Write a description of class Bouton here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Bouton extends Actor
{ 
    public GreenfootImage Btn = new GreenfootImage(600,60);
    
    private String sayThat;
    private String thisW;
    
    public Bouton(String whatToSay, String whichWorld)
    {
        sayThat = whatToSay;
        thisW = whichWorld;
        
        Btn.setFont( new Font("Segoe Script", Font.PLAIN, 24));
        Btn.setColor(Color.BLACK);
        Btn.drawString(sayThat, 100, 50);
        Btn.setTransparency(130);
        
        setImage(Btn);

    }
    
    public void act() 
    {
        if(Greenfoot.mouseClicked(this))
        {
            Btn.setTransparency(255);
            
            if("Espace1".equals(thisW))
            {
                Greenfoot.setWorld(new Espace() );
            }
            
            if("Espace3".equals(thisW))
            {
                //Greenfoot.setWorld(new Espace3() );
                Score scoreObj = (Score) getWorld().getObjects(Score.class).get(0); // get score object  
                Espace3 e3 = new Espace3(); // create new world  
                e3.addObject(scoreObj, scoreObj.getX(), scoreObj.getY()); // transfer score object  
                Greenfoot.setWorld(e3);
            }
            
            if("howTo".equals(thisW))
            {
                Greenfoot.setWorld(new CommentJ() );
            }
            
            if("Menu".equals(thisW))
            {
                Greenfoot.setWorld(new Menu() );
            }
        }
    }
}
The method used by the actors to do some points
public void doTheScore( int amountOfScore)
    {       
        
        WMethod wmethod = (WMethod) getWorld();
        Score score = wmethod.getScore();
            
        score.getTheScore(amountOfScore);
    }
What I used before Danpost's message, to set the Counter in Espace3 (from the world constructor)
/*Score score = new Score();
        score.getTheScore(10); //+10 pour avoir réussi le niveau
        addObject(score, 40, 640);*/
The subclass of both levels, with the method
public class WMethod extends World
{
    public Score theScore;

    public WMethod()
    {    
        super(1100, 690, 1); 
    }
    
    public Score getScore() 
    /*
     * Méthode inspirée d'un tutoriel Greenfoot : http://www.greenfoot.org/doc/howto-1
     */
    
    {
        return theScore;
    }
}
I get the error message at the method used by the actors to score.
public void doTheScore( int amountOfScore)
    {       
        
        WMethod wmethod = (WMethod) getWorld();
        Score score = wmethod.getScore();
            
        score.getTheScore(amountOfScore);//Here
    }
Dont know what to do now... Thanks a lot
davmac davmac

2013/4/17

#
Ok, first:
The subclass of both levels, with the method
You mean the superclass, not the subclass. The level classes are subclasses of WMethod, so WMethod is the superclass of the level classes. Now, in WMethod line 3, you have:
    public Score theScore;  
But, I don't see you set 'theScore' to anything anywhere - so it is a null reference. That would explain why 'score' is null, and you then get a NullPointerException in line 7 of the doTheScore(...) method.
danpost danpost

2013/4/17

#
If you posted the code to your 'WMethod' world class, someone might be able to help. On second thought, you will need to have 'theScore' declared in each world. In the first world you apparently already have it declared with something like 'private Score theScore;'. That declaration must be in all worlds that you will have that score object in. Also, you have a method to get the score object from each world:
public Score getScore()
{
    return theScore;
}
All you need now, is a method to 'set' the score object in those secondary worlds:
public void setScore(Score scoreObj)
{
    theScore = scoreObj;
}
Instead of my previous 'addObject' line (used to transfer the score object to Escape3 world), just use
e3.setScore(theScore);
Now, back in the secondary worlds, we need to make sure that this is the score object that gets displayed, so add the following method to all secondary worlds:
public void started()
{
    addObject(theScore, 100, 640);
}
Make sure you are not adding the score object to the world anywhere else in those classes.
davmac davmac

2013/4/17

#
danpost,
If you posted the code to your 'WMethod' world class, someone might be able to help.
The code for WMethod is in welleid's most recent post.
On second thought, you will need to have 'theScore' declared in each world. In the first world you apparently already have it declared with something like 'private Score theScore;'. That declaration must be in all worlds that you will have that score object in.
'theScore' is declared in WMethod, the superclass of the other world classes, so it doesn't need to be declared separately in the other worlds.
welleid welleid

2013/4/17

#
Ok but how should i set this variable ? I put it like that : public Score theScore; But how can I set it ? And why does it work in first level without setting it ?
There are more replies on the next page.
1
2