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

2018/11/29

Trying to create a highscore leaderboard?

Nate2002 Nate2002

2018/11/29

#
I want to create a leaderboard in Greenfoot, but I don't know where to start with it. I am using Java, so if anybody knows what I can do please let me know. P.S. I want it to let the person who surpasses one of the scores enter their name and it would save it to the leaderboard until somebody surpasses it.
Super_Hippo Super_Hippo

2018/11/29

#
You can import the "ScoreBoard" class and follow the instructions. This "default" version uses the Username as the displayed name but if you don't want that, you could change it so the user can write a different name in the end.
Nate2002 Nate2002

2018/11/29

#
Thank you very much
Nate2002 Nate2002

2018/11/29

#
I experienced another problem where when the game ends the leaderboard doesn't show up, but if I try to put the leaderboard in, then the world won't allow me to save.
danpost danpost

2018/11/29

#
Nate2002 wrote...
I experienced another problem where when the game ends the leaderboard doesn't show up, but if I try to put the leaderboard in, then the world won't allow me to save.
You will need to show what you tried (game over coding).
Nate2002 Nate2002

2018/11/29

#
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.awt.Color;
/**
 * Write a description of class GameOver here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class GameOver extends World
{

    /**
     * Constructor for objects of class GameOver.
     * 
     */
    public GameOver()
    {    
        // Create a new world with 600x400 cells with a cell size of 1x1 pixels.
        super(1000, 600, 1);
        GreenfootImage background = getBackground();
        background.setColor(java.awt.Color.cyan);
        background.fill();
        prepare();
    }

    private void prepare()
    {
        ScoreBoard scoreboard = new ScoreBoard();
        addObject(scoreboard,500,300);
        
    }
}
That's the GameOver World when my life equals 0.
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.awt.Color;
import java.util.List;

/**
 * An actor class that can display a scoreboard, using Greenfoot's
 * UserInfo class.  
 * 
 * You typically use this by including some code into the world for when your game ends:
 * 
 * <pre>
 *   addObject(new ScoreBoard(800, 600), getWidth() / 2, getHeight() / 2); 
 * </pre>
 * 
 * Where 800 by 600 should be replaced by the desired size of the score board. 
 * 
 * @author Neil Brown 
 * @version 1.0
 */
public class ScoreBoard extends Actor
{
    // The vertical gap between user images in the scoreboard:
    private static final int GAP = 10;
    // The height of the "All Players"/"Near Me" text at the top:
    private static final int HEADER_TEXT_HEIGHT = 25;
    // The main text color:
    private static final Color MAIN_COLOR = new Color(0x60, 0x60, 0x60); // dark grey
    // The score color:
    private static final Color SCORE_COLOR = new Color(0xB0, 0x40, 0x40); // orange-y
    // The background colors:
    private static final Color BACKGROUND_COLOR = new Color(0xFF, 0xFF, 0xFF, 0xB0);
    private static final Color BACKGROUND_HIGHLIGHT_COLOR = new Color(180, 230, 255, 0xB0);

    /**
     * Constructor for objects of class ScoreBoard.
     * <p>
     * You can specify the width and height that the score board should be, but
     * a minimum width of 600 will be enforced.
     */
    public ScoreBoard(int width, int height)
    {    
        setImage(new GreenfootImage(Math.max(600, width), height)); 
        
        drawScores();
    }
    
    public ScoreBoard()
    {
        
    }
    
    private void drawString(String text, int x, int y, Color color, int height)
    {
        getImage().drawImage(new GreenfootImage(text, height, color, new Color (0, true)), x, y);
    }
    
    private void drawScores()
    {
        // 50 pixels is the max height of the user image
        final int pixelsPerUser = 50 + 2*GAP;
        // Calculate how many users we have room for:
        final int numUsers = ((getImage().getHeight() - (HEADER_TEXT_HEIGHT + 10)) / pixelsPerUser);
        final int topSpace = getImage().getHeight() - (numUsers * pixelsPerUser) - GAP;
        
        getImage().setColor(BACKGROUND_COLOR);
        getImage().fill();

        drawString("Name", 100, topSpace - HEADER_TEXT_HEIGHT - 5, MAIN_COLOR, HEADER_TEXT_HEIGHT);
        drawString("HighScores", 100 + getImage().getWidth() / 2, topSpace - HEADER_TEXT_HEIGHT - 5, MAIN_COLOR, HEADER_TEXT_HEIGHT);        
        
        drawUserPanel(GAP, topSpace, (getImage().getWidth() / 2) - GAP, topSpace + numUsers * pixelsPerUser, UserInfo.getTop(numUsers));
        drawUserPanel(GAP + getImage().getWidth() / 2, topSpace, getImage().getWidth() - GAP, topSpace + numUsers * pixelsPerUser, UserInfo.getNearby(numUsers));
    }
    
    private void drawUserPanel(int left, int top, int right, int bottom, List users)
    {
        getImage().setColor(MAIN_COLOR);
        getImage().drawRect(left, top, right - left, bottom - top);
        
        if (users == null)
            return;
        
        UserInfo me = UserInfo.getMyInfo();
        int y = top + GAP;
        for (Object obj : users)
        {
            UserInfo playerData = (UserInfo)obj;            
            Color c;
            
            if (me != null && playerData.getUserName().equals(me.getUserName()))
            {
                // Highlight our row in a sky blue colour:
                c = BACKGROUND_HIGHLIGHT_COLOR;
            }
            else
            {
                c = BACKGROUND_COLOR;
            }
            getImage().setColor(c);
            getImage().fillRect(left + 5, y - GAP + 1, right - left - 10, 50 + 2*GAP - 1);

            int x = left + 10;
            drawString("#" + Integer.toString(playerData.getRank()), x, y+18, MAIN_COLOR, 14);
            x += 50;
            drawString(Integer.toString(playerData.getScore()), x, y+18, SCORE_COLOR, 14);
            x += 80;
            getImage().drawImage(playerData.getUserImage(), x, y);
            x += 55;
            drawString(playerData.getUserName(), x, y + 18, MAIN_COLOR, 14);
            y += 50 + 2*GAP;
        }
    }
}
And this is the code I have for my ScoreBoard. I have an empty public ScoreBoard because I tried putting it in to the Game Over World with the "public ScoreBoard(int width, int height)" but the GameOver World has an error saying the "int" needed a ".class" Also sorry if I'm not wording everything right and understandable, as I am new to coding and this site.
danpost danpost

2018/11/29

#
Change line 28 in your GameOver class to:
ScoreBoard scoreboard = new ScoreBoard(600, 600);
Nate2002 Nate2002

2018/11/29

#
I did that and it worked (thank you very much), but I also wish to be able to put in a name for the person who has the highscores and then have it save the highscores until someone surpasses it. Is there any way to do that?
Nate2002 Nate2002

2018/11/29

#
Here is my revised code if you want to see it.
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.awt.Color;
import java.util.List;

/**
 * An actor class that can display a scoreboard, using Greenfoot's
 * UserInfo class.  
 * 
 * You typically use this by including some code into the world for when your game ends:
 * 
 * <pre>
 *   addObject(new ScoreBoard(800, 600), getWidth() / 2, getHeight() / 2); 
 * </pre>
 * 
 * Where 800 by 600 should be replaced by the desired size of the score board. 
 * 
 * @author Neil Brown 
 * @version 1.0
 */
public class ScoreBoard extends Actor
{
    // The vertical gap between user images in the scoreboard:
    private static final int GAP = 10;
    // The height of the "All Players"/"Near Me" text at the top:
    private static final int HEADER_TEXT_HEIGHT = 25;
    // The main text color:
    private static final Color MAIN_COLOR = new Color(0x60, 0x60, 0x60); // dark grey
    // The score color:ScoreBoard scoreboard = new ScoreBoard(600, 600);
    private static final Color SCORE_COLOR = new Color(0xB0, 0x40, 0x40); // orange-y
    // The background colors:
    private static final Color BACKGROUND_COLOR = new Color(0xFF, 0xFF, 0xFF, 0xB0);
    private static final Color BACKGROUND_HIGHLIGHT_COLOR = new Color(180, 230, 255, 0xB0);

    /**
     * Constructor for objects of class ScoreBoard.
     * <p>
     * You can specify the width and height that the score board should be, but
     * a minimum width of 600 will be enforced.
     */
    public ScoreBoard(int width, int height)
    {    
        setImage(new GreenfootImage(Math.max(600, width), height)); 
        
        drawScores();
    }
    
    public ScoreBoard()
    {
        
    }
    
    private void drawString(String text, int x, int y, Color color, int height)
    {
        getImage().drawImage(new GreenfootImage(text, height, color, new Color (0, true)), x, y);
    }
    
    private void drawScores()
    {
        // 50 pixels is the max height of the user image
        final int pixelsPerUser = 50 + 2*GAP;
        // Calculate how many users we have room for:
        final int numUsers = ((getImage().getHeight() - (HEADER_TEXT_HEIGHT + 10)) / pixelsPerUser);
        final int topSpace = getImage().getHeight() - (numUsers * pixelsPerUser) - GAP;
        
        getImage().setColor(BACKGROUND_COLOR);
        getImage().fill();

        drawString("Name", 100, topSpace - HEADER_TEXT_HEIGHT - 5, MAIN_COLOR, HEADER_TEXT_HEIGHT);
        drawString("HighScores", 100 + getImage().getWidth() / 2, topSpace - HEADER_TEXT_HEIGHT - 5, MAIN_COLOR, HEADER_TEXT_HEIGHT);        
        
        drawUserPanel(GAP, topSpace, (getImage().getWidth() / 2) - GAP, topSpace + numUsers * pixelsPerUser, UserInfo.getTop(numUsers));
        drawUserPanel(GAP + getImage().getWidth() / 2, topSpace, getImage().getWidth() - GAP, topSpace + numUsers * pixelsPerUser, UserInfo.getNearby(numUsers));
    }
    
    private void drawUserPanel(int left, int top, int right, int bottom, List users)
    {
        getImage().setColor(MAIN_COLOR);
        getImage().drawRect(left, top, right - left, bottom - top);
        
        if (users == null)
            return;
        
        UserInfo me = UserInfo.getMyInfo();
        int y = top + GAP;
        for (Object obj : users)
        {
            UserInfo playerData = (UserInfo)obj;            
            Color c;
            
            if (me != null && playerData.getUserName().equals(me.getUserName()))
            {
                // Highlight our row in a sky blue colour:
                c = BACKGROUND_HIGHLIGHT_COLOR;
            }
            else
            {
                c = BACKGROUND_COLOR;
            }
            getImage().setColor(c);
            getImage().fillRect(left + 5, y - GAP + 1, right - left - 10, 50 + 2*GAP - 1);

            int x = left + 10;
            drawString("#" + Integer.toString(playerData.getRank()), x, y+18, MAIN_COLOR, 14);
            x += 50;
            drawString(Integer.toString(playerData.getScore()), x, y+18, SCORE_COLOR, 14);
            x += 80;
            getImage().drawImage(playerData.getUserImage(), x, y);
            x += 55;
            drawString(playerData.getUserName(), x, y + 18, MAIN_COLOR, 14);
            y += 50 + 2*GAP;
        }
    }
}
danpost danpost

2018/11/29

#
You could use the ask method of the Greenfoot class and store the name entered in one of the data strings of the user's UserInfo instance.
Nate2002 Nate2002

2018/12/3

#
I'm quite new to coding, so can you please show me where it would all be located in the code?
danpost danpost

2018/12/3

#
Nate2002 wrote...
I'm quite new to coding, so can you please show me where it would all be located in the code?
Just before creating the GameOver world, which is not part of what has been provided so far.
Nate2002 Nate2002

2018/12/3

#
Here is what i attempted, and this is in my main actor's code when his life reaches 0. The thing is the name wouldn't save to the scoreboard and stay there. For all i know i'm probably missing one one simple thing.
 if(life == 0)
        {

                
            if(UserInfo.isStorageAvailable())
            {

                MyWorld world = (MyWorld)getWorld();
                
                score.setScore(world.score);
                Greenfoot.ask("What is your name");
            }
            Greenfoot.setWorld(new GameOver());

        }
danpost danpost

2018/12/3

#
Nate2002 wrote...
Here is what i attempted, and this is in my main actor's code when his life reaches 0. The thing is the name wouldn't save to the scoreboard and stay there. For all i know i'm probably missing one one simple thing. << Code Omitted >>
Probably more than one. First, line 11 will ask the user for a name, but where is that input going? And once an alternate name is given, will you need to ask for it again? Also, what if the current end game score is less than a previous end game score by that user? Before saving a score, I would first make sure the new end game score is greater than the current UserInfo score value. Once that is confirmed, I would ask if the current UserInfo score value was zero (indicating that this is first score saved for this user), and if so, ask for an alternate name (other than their user name) and save it in the first String location in the UserInfo data block; then set the score and save the modified UserInfo data. Finally, you can create the GameOver object and set it active. What are your intentions with the program? Are you preparing to upload it on the Greenfoot site? or, something else? I guess I just want to be sure all this is not for naught.
Nate2002 Nate2002

2018/12/3

#
I was going to upload it to Greenfoot at some point, when i get the scoreboard working
You need to login to post a reply.