[SOLVED]Final Score Screen Effect Libgdx

Hey guys, i want to do this in my game :

exactly starting at 13 seconds, it will happen the score calculator.
That effect is awesome… Any ideas how to do that?

In my case, the high score is just calculated in the end of the game. And i may upload to a database… but thats off limits.
Anyway, i want to know how to make that effect :stuck_out_tongue:

Im using libgdx.

Any ideas , where can i start? How should i think the logic? Will i need a timer?

The score numbers rolling down to 0? Yeah, that shouldn’t be too bad. I’m not very knowledgeable about graphics or libgdx, but I can tell you the basic logic.

  1. Figure out the scores, along with how fast you want them to go down. Let’s say you’re dealing with scores in the tens of thousands and want them to go down at 10,000 per second. That rate should be saved in a variable.
  2. Display the scores. Note the time these are drawn to the screen.
  3. Every time you get another chance to draw another frame to the screen, for the score currently being counted down:
//set the score we'll display to be subtracted based on the amount of seconds that have passed * the amount we want to count down per second
currentScore = startingScore - (millisecondTimeRightNow - millisecondTimeOfStep2) / 1000 * rate
//check if we're done counting this score down, and if so, show 0 and add that score to the player's total score
if(currentScore < 0) { currentScore = 0; noMoreLooping = true; playerScore += startingScore }
//draw playerScore, currentScore, and any other scores you aren't currently counting down

  1. When you’ve counted down the last score, you’re done. Wait for the player to press a key or something.

Edit: And for the love of all that is good, don’t make it count down too slow. Otherwise, impatient players like me will get bored after the first couple times and keep tapping buttons or keys in vain, hoping to skip to the end of the countdown. (Or just make it skip to the end by setting all the countdown scores to 0 and updating the player’s score when you press a certain key.) It’s still a cool effect though.
Edit edit: Note that my syntax is wrong in a couple places at least. My code is just for an example of the logic. It won’t work just copy-pasted. :stuck_out_tongue:

Thanks for the reply.
I guess now i get it how to start but, what about the sound… Should i just get a normal sound and play it or, faster the points go down, faster the sound? idk
How do i manage the sound for it?

You should get a sound that fits your tick down time. So if you make the score go down every second, then you play a 1 second or less sound every tick.

Although, that’s really up to you how the sound works.

I see…

Well, in the final Screen, i have this :

[quote]package br.views.levels;

import br.data.Data;
import br.data.SaveData;
import br.dir.DirectoriesLevel_Extend;
import br.player.Player;
import br.tools.MyTimer;
import br.views.MenuView;
import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer;

/**
*

  • @author André Lopes
    */
    public class GameOver extends Level_Extend implements Screen {

    private Texture gameOver;
    private Texture gameOver1;
    private Texture gameOver2;
    private MyTimer timer;
    private int color;
    private Data data;
    private SaveData saveData;

    public GameOver(Data data) {
    this.data = data;
    }

    @Override
    public void updateCamera() {

    }

    @Override
    public void configLoadedLevelData(Data data) {

    }

    @Override
    public void configLevelData() {

    }

    @Override
    public void script() {

    }

    @Override
    public void nextLevel() {

    }

    @Override
    public void teleportTile(TiledMapTileLayer collisionLayer, Player player) {

    }

    @Override
    public void render(float delta) {
    if (!timer.isDone()) {
    Gdx.gl.glClearColor(0, 0, 0, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

         color++;
         if (color > 240) {
             color = 0;
         }
    
         batch.begin();
         if (color < 60) {
             batch.draw(gameOver, 0, 0);
         } else if (color < 120) {
             batch.draw(gameOver1, 0, 0);
         } else if (color < 240) {
             batch.draw(gameOver2, 0, 0);
         }
         batch.end();
    
     } else {
         saveData.saveData(data);
         ((Game) Gdx.app.getApplicationListener()).setScreen(new MenuView());
         dispose();
     }
    

    }

    @Override
    public void resize(int width, int height) {

    }

    @Override
    public void show() {
    color = 0;

     batch = new SpriteBatch();
     gameOver = new Texture(Gdx.files.internal("imagens/Resources/GameOver/GameOver.jpg"));
     gameOver1 = new Texture(Gdx.files.internal("imagens/Resources/GameOver/GameOver1.jpg"));
     gameOver2 = new Texture(Gdx.files.internal("imagens/Resources/GameOver/GameOver2.jpg"));
    
     DirectoriesLevel_Extend directoriesLevelExtend = new DirectoriesLevel_Extend();
     simpleRedFont = directoriesLevelExtend.getSimpleRedFont();
    
     timer = new MyTimer(5);
     timer.start();
     saveData = new SaveData();
    

    }

    @Override
    public void dispose() {

     batch.dispose();
     gameOver.dispose();
     gameOver1.dispose();
     gameOver2.dispose();
    

    }

    @Override
    public void hide() {

    }

}
[/quote]
So heres the logic,
I want to sum the

(quantity of diamonds the player was able to get * 1000)
+
(the normal score)


For now will be very simple. I have other better ideas, but for now, that will be ok.

So i will need three text fields, one for the score, one for the diamonds score, and other for the result.

After that, i need to set the timer in a appropriate way…Or just remove it. And once the score is calculated, just press enter and it goes?

If you want it to take a certain amount of time, no matter what the score, a timer might be appropriate. (I’ve never used one – just checking the current time via the System.getMilliseconds or System.getNanos methods (not their exact names).) If you want the speed at which it counts down to be constant, say 10,000 per second, so that it will take longer to count down big numbers than small numbers, I don’t see why you’d need a timer. Even if you want it to take a certain amount of time, regardless of score, you don’t need one. You just need to know when you started counting down and what time it is when you’re ready to show the numbers. Remember, you don’t need to actually change the score numbers. It’s just an effect. You’re just changing what the player sees. Whether you want to use a timer or not is up to you.

As for audio, that’s also up to you, man. It’s a matter of preference.

“Remember, you don’t need to actually change the score numbers. It’s just an effect. You’re just changing what the player sees.”

What you mean exactly?
I was thinking in subtracting certain amounts each frame and rendering…

You can either subtract the score each frame and add what you subtracted to the grand total (so, each frame you’re transferring score from the countdown score to the player’s total score) and then render the results, or you can just show the score minus: the amount of time passed times the amount to subtract per unit of time passed, and then transfer the score at the end.

You can treat it as subtracting from the score every frame and showing the result, or you can treat it as showing a countdown animation every frame. Either way will work. My point is that you don’t have to confine yourself to thinking, “I have to change the score every frame!” You just have to change what the player sees every frame.

http://img818.imageshack.us/img818/3774/4lmr.png

:stuck_out_tongue:


/**
 *
 * @author André Lopes
 */
public class GameOver extends Level_Extend implements Screen {

    private Texture gameOver;
    private MyTimer timer;

    private int color;

    private Data data;
    private SaveData saveData;
    private DrawText drawText;

    private TextField dataScore, diamondScore, totalScore;

    private Table scoreTable;

    public GameOver(Data data) {
        this.data = data;

    }

    @Override
    public void updateCamera() {

    }

    @Override
    public void configLoadedLevelData(Data data) {

    }

    @Override
    public void configLevelData() {

    }

    @Override
    public void script() {

    }

    @Override
    public void nextLevel() {

    }

    @Override
    public void teleportTile(TiledMapTileLayer collisionLayer, Player player) {

    }

    @Override
    public void render(float delta) {
        if (!timer.isDone()) {

            Gdx.gl.glClearColor(0, 0, 0, 1);
            Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

            color++;
            if (color > 240) {
                color = 0;
            }

            batch.begin();
            batch.draw(gameOver, 0, 0);

            batch.end();

            stage.act(delta);
            stage.draw();
            //Table.drawDebug(stage);
        } else {
            saveData.saveData(data);
            ((Game) Gdx.app.getApplicationListener()).setScreen(new MenuView());
            dispose();
        }
    }

    @Override
    public void resize(int width, int height) {

        stage.setViewport(width, height, true);

        int w = (Gdx.graphics.getWidth() / 2);
        int h = (Gdx.graphics.getHeight() - Gdx.graphics.getHeight() / 5);

        scoreTable.setPosition(w, h);

        scoreTable.invalidateHierarchy();
        camera.position.set(0, 0, 0f);
        camera.viewportWidth = 800;
        camera.viewportHeight = 600;

    }

    @Override
    public void show() {
        color = 0;
        stage = new Stage();
        camera = new OrthographicCamera();
        batch = new SpriteBatch();
        drawText = new DrawText();

        scoreTable = new Table();
        scoreTable.pad(15f);

        //
        gameOver = new Texture(Gdx.files.internal("imagens/Resources/GameOver/BlackScreen.png"));
        gameOver.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest);
        //

        DirectoriesLevel_Extend directoriesLevelExtend = new DirectoriesLevel_Extend();
        simpleRedFont = directoriesLevelExtend.getSimpleRedFont();
        simpleWhiteFont = directoriesLevelExtend.getSimpleWhiteFont();

        timer = new MyTimer(20);
        timer.start();
        saveData = new SaveData();

        LabelStyle ls = new LabelStyle();
        ls.font = simpleWhiteFont;
        Label titleLabel = new Label("Game Over", ls);

        TextField.TextFieldStyle textFieldDataScore = new TextField.TextFieldStyle();
        textFieldDataScore.font = simpleWhiteFont;
        textFieldDataScore.fontColor = Color.YELLOW;
        textFieldDataScore.background = (new SpriteDrawable(new Sprite(new Texture(Gdx.files.internal("imagens/Resources/ui/textField/natyyr/box.png")))));
        textFieldDataScore.background.setLeftWidth(10f);

        TextField.TextFieldStyle textFieldDiamondScore = new TextField.TextFieldStyle();
        textFieldDiamondScore.font = simpleWhiteFont;
        textFieldDiamondScore.fontColor = Color.RED;
        textFieldDiamondScore.background = (new SpriteDrawable(new Sprite(new Texture(Gdx.files.internal("imagens/Resources/ui/textField/natyyr/box.png")))));
        textFieldDiamondScore.background.setLeftWidth(10f);

        TextField.TextFieldStyle textFieldStyle1 = new TextField.TextFieldStyle();
        textFieldStyle1.font = simpleWhiteFont;
        textFieldStyle1.fontColor = Color.WHITE;
        textFieldStyle1.background = (new SpriteDrawable(new Sprite(new Texture(Gdx.files.internal("imagens/Resources/ui/textField/natyyr/box_lit.png")))));
        textFieldStyle1.background.setLeftWidth(10f);

        dataScore = new TextField("123456789", textFieldDataScore);
        dataScore.setSize(400, 55);
        diamondScore = new TextField("123456789", textFieldDiamondScore);

        totalScore = new TextField("246913578", textFieldStyle1);

        scoreTable.add(titleLabel);
        scoreTable.row();
        scoreTable.add(dataScore);
        scoreTable.row();
        scoreTable.add(diamondScore);
        scoreTable.row();
        scoreTable.add(totalScore);

        
        int w = (Gdx.graphics.getWidth() / 2);
        int h = (Gdx.graphics.getHeight() - Gdx.graphics.getHeight() / 5);

        scoreTable.setPosition(w, h);
        
        scoreTable.debug();

        stage.addActor(scoreTable);
        //stage.setCamera(camera);
        
    }

    @Override
    public void dispose() {
        batch.dispose();
        gameOver.dispose();
    }

    @Override
    public void hide() {

    }

}

Im having a problem.
The Drawable background is way bigger but it isnt showing up completely.
What am i doing wrong?

The background is 400x55 pixels…

Why isnt showing up as it should?

Ok Guys, its working ! But, i have a question, how do i calculate the rate “PASS_FRAME_SCORE” ? I want to calculate it in a way that the score calculus doesnt take more than 10 seconds.
Plus, the table is small… I will create a new topic about that. Anyway, heres the code :

package br.views.levels;

import br.data.Data;
import br.data.SaveData;
import br.dir.DirectoriesLevel_Extend;
import br.player.Player;
import br.tools.MyTimer;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.ui.TextField;
import com.badlogic.gdx.scenes.scene2d.utils.SpriteDrawable;

/**
 *
 * @author André Lopes
 */
public class GameOver extends Level_Extend implements Screen {

    private final int PASS_FRAME_SCORE = 50;


    private Texture gameOver;
    private MyTimer timer;

    private int color;

    private Data data;
    private SaveData saveData;
    private DrawText drawText;

    private TextField dataScore, diamondScore, totalScore;

    private Table scoreTable;

    public GameOver(Data data) {
        this.data = data;

    }

    @Override
    public void updateCamera() {

    }

    @Override
    public void configLoadedLevelData(Data data) {

    }

    @Override
    public void configLevelData() {

    }

    @Override
    public void script() {

    }

    @Override
    public void nextLevel() {

    }

    @Override
    public void teleportTile(TiledMapTileLayer collisionLayer, Player player) {

    }

    @Override
    public void render(float delta) {

        Gdx.gl.glClearColor(0, 0, 0, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        color++;
        if (color > 240) {
            color = 0;
        }

        batch.begin();
        batch.draw(gameOver, 0, 0);

        batch.end();

        stage.act(delta);
        stage.draw();
        Table.drawDebug(stage);

        update();

    }

    @Override
    public void resize(int width, int height) {

        stage.setViewport(width, height, true);

        int w = (Gdx.graphics.getWidth() / 2);
        int h = (Gdx.graphics.getHeight() - Gdx.graphics.getHeight() / 5);

        scoreTable.setPosition(w, h);

        scoreTable.invalidateHierarchy();
        dataScore.invalidate();
        totalScore.invalidate();
        diamondScore.invalidate();
        camera.position.set(0, 0, 0f);
        camera.viewportWidth = 800;
        camera.viewportHeight = 600;

    }

    @Override
    public void show() {

        color = 0;
        stage = new Stage();
        camera = new OrthographicCamera();
        batch = new SpriteBatch();
        drawText = new DrawText();

        scoreTable = new Table();
        scoreTable.pad(15f);

        //
        gameOver = new Texture(Gdx.files.internal("imagens/Resources/GameOver/BlackScreen.png"));
        gameOver.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest);
        //

        DirectoriesLevel_Extend directoriesLevelExtend = new DirectoriesLevel_Extend();
        simpleRedFont = directoriesLevelExtend.getSimpleRedFont();
        simpleWhiteFont = directoriesLevelExtend.getSimpleWhiteFont();

        timer = new MyTimer(60);
        timer.start();
        saveData = new SaveData();

        LabelStyle ls = new LabelStyle();
        ls.font = simpleWhiteFont;
        Label titleLabel = new Label("Game Over", ls);

        TextField.TextFieldStyle textFieldStyleDataScore = new TextField.TextFieldStyle();
        textFieldStyleDataScore.font = simpleWhiteFont;
        textFieldStyleDataScore.fontColor = Color.YELLOW;

        Sprite sprite = new Sprite(new Texture(Gdx.files.internal("imagens/Resources/ui/textField/natyyr/box.png")));
        SpriteDrawable sd = new SpriteDrawable(sprite);

        textFieldStyleDataScore.background = sd;
        textFieldStyleDataScore.background.setLeftWidth(10f);

        TextField.TextFieldStyle textFieldStyleDiamondScore = new TextField.TextFieldStyle();
        textFieldStyleDiamondScore.font = simpleWhiteFont;
        textFieldStyleDiamondScore.fontColor = Color.RED;
        textFieldStyleDiamondScore.background = (new SpriteDrawable(new Sprite(new Texture(Gdx.files.internal("imagens/Resources/ui/textField/natyyr/box.png")))));
        textFieldStyleDiamondScore.background.setLeftWidth(10f);

        TextField.TextFieldStyle textFieldStyleTotalScore = new TextField.TextFieldStyle();
        textFieldStyleTotalScore.font = simpleWhiteFont;
        textFieldStyleTotalScore.fontColor = Color.WHITE;
        textFieldStyleTotalScore.background = (new SpriteDrawable(new Sprite(new Texture(Gdx.files.internal("imagens/Resources/ui/textField/natyyr/box_lit.png")))));
        textFieldStyleTotalScore.background.setLeftWidth(10f);

        dataScore = new TextField("123456789", textFieldStyleDataScore);

        diamondScore = new TextField("123456789", textFieldStyleDiamondScore);

        totalScore = new TextField("246913578", textFieldStyleTotalScore);

        scoreTable.add(titleLabel);
        scoreTable.row();
        scoreTable.add(dataScore);
        scoreTable.row();
        scoreTable.add(diamondScore);
        scoreTable.row();
        scoreTable.add(totalScore);

        int w = (Gdx.graphics.getWidth() / 2);
        int h = (Gdx.graphics.getHeight() - Gdx.graphics.getHeight() / 5);

        scoreTable.setPosition(w, h);

        scoreTable.debug();

        stage.addActor(scoreTable);
        int current_Red_Diamond = data.getCurrent_Red_Diamond();
        int current_Blue_Diamond = data.getCurrent_Blue_Diamond();

        setDiamondScore(10 * (100 * current_Red_Diamond + 100 * current_Blue_Diamond));
        setDataScore(data.getCurrent_Score());
        setTotalScore(0);
    }

    private void update() {
        int dataScoreInt = getDataScore();
        int diamondScoreInt = getDiamondScore();
        int totalScoreInt = getTotalScore();

        
        if (dataScoreInt - PASS_FRAME_SCORE > 0) {
            
            totalScoreInt = totalScoreInt + PASS_FRAME_SCORE;
            setDataScore(dataScoreInt - PASS_FRAME_SCORE);
            
        } else if (dataScoreInt > 0) {

            totalScoreInt = totalScoreInt + dataScoreInt;
            setDataScore(0);

        }

        if (diamondScoreInt - PASS_FRAME_SCORE > 0) {
            
            totalScoreInt = totalScoreInt + PASS_FRAME_SCORE;
            setDiamondScore(diamondScoreInt - PASS_FRAME_SCORE);

        } else if (diamondScoreInt > 0) {

            totalScoreInt = diamondScoreInt + totalScoreInt;
            setDiamondScore(0);

        }

        setTotalScore(totalScoreInt);

    }

    private int getDiamondScore() {
        String text = diamondScore.getText();
        int parseInt = Integer.parseInt(text);
        return parseInt;
    }

    private int getTotalScore() {
        String text = totalScore.getText();
        int parseInt = Integer.parseInt(text);
        return parseInt;
    }

    private int getDataScore() {
        String text = dataScore.getText();
        int parseInt = Integer.parseInt(text);
        return parseInt;
    }

    private void setDiamondScore(int score) {
        diamondScore.setText("" + score);
    }

    private void setTotalScore(int score) {
        totalScore.setText("" + score);
    }

    private void setDataScore(int score) {
        dataScore.setText("" + score);
    }

    @Override
    public void dispose() {
        batch.dispose();
        gameOver.dispose();
    }

    @Override
    public void hide() {

    }

}

There are 600 frames in 10 seconds. Do the math.
600/score = score reduction per frame.

There is no “right” way to do it. Just do it. After you have done it, you will know a better way to do it.

Ok! It was my first Score Calculator… So yeah ! Thanks guys! :stuck_out_tongue:

I just want to let this here for any comments…

 //There are 600 frames in 10 seconds. Do the math.
        //600/score = score reduction per frame.
        //5 Seconds
        PASS_FRAME_SCORE = ((data.getCurrent_Score() + data.getCalculatedDiamondScore())/300);
        System.out.println("data.getCurrent_Score() = " + data.getCurrent_Score());
        System.out.println("data.getCalculatedDiamondScore()) = " + data.getCalculatedDiamondScore());
        System.out.println("Total Score = " + (data.getCurrent_Score() + data.getCalculatedDiamondScore()));
        System.out.println("PFS " + PASS_FRAME_SCORE);

[quote]data.getCurrent_Level()8
data.getCurrent_Score() = 8000
data.getCalculatedDiamondScore()) = 10000
Total Score = 18000
PFS60
[/quote]