0
\$\begingroup\$

I'm currently working on a LibGDX Java Game Project inspired by the Space Invaders game where I have created 2 Scene Classes: LevelScene and PauseScene. For instance, when the player hits an enemy, the player's score should increase and retain the latest score before going to the Pause scene. When transitioning from Pause Scene to Level Scene, the score should be the latest score and not 0. However, When resuming the game, the score is reset back to 0. I have tried troubleshooting for hours but to no avail. Please enlighten me on how to retain the latest score when transitioning between the 2 scenes.

LevelScene.java

package com.mygdx.game.GameLayer.Scenes;

import java.util.List;

import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.InputAdapter;
import com.badlogic.gdx.Preferences;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.GlyphLayout;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.utils.ScreenUtils;
import com.badlogic.gdx.utils.viewport.ScreenViewport;
import com.mygdx.game.GameEngine.AssetsManager;
import com.mygdx.game.GameEngine.AudioSettings;
import com.mygdx.game.GameEngine.BehaviourManager;
import com.mygdx.game.GameEngine.IOManager;
import com.mygdx.game.LifeCycleManager;
import com.mygdx.game.GameEngine.Collision.CollisionManager;
import com.mygdx.game.GameEngine.Entities.Entity;
import com.mygdx.game.GameEngine.Entities.EntityManager;
import com.mygdx.game.GameEngine.Scene.SceneManager;
import com.mygdx.game.GameLayer.Entities.Enemy;
import com.mygdx.game.GameLayer.Entities.Player;

public class LevelScene extends SceneManager {
    private SpriteBatch batch;
    private Texture background;
    private String scoreText = "Score: ";
    private BitmapFont font;
    private GlyphLayout layout;
    public int currentScore;
    private Music playingSong;
    private Music music;
    private AudioSettings audioSettings = new AudioSettings();
    
    private float timer = 0;
    private float swapInterval = 5; // 5 seconds
    
    private int savedScore; // Variable to store the score before transitioning to PauseScene
    private Preferences preferences;
    
    public IOManager ioManager = IOManager.getInstance();
    public BehaviourManager behaviourManager = BehaviourManager.getInstance();
    public EntityManager entityManager = EntityManager.getInstance();
    public CollisionManager collisionManager = CollisionManager.getInstance();
    
    public LevelScene(Game game) {
        super(game);
        batch = new SpriteBatch();
        entityManager.create();
        background = new Texture(Gdx.files.internal("background/space.png"));
        font = new BitmapFont();
        layout = new GlyphLayout();
        
        // Initialize preferences
        preferences = Gdx.app.getPreferences("GamePreferences");
        // Load score when scene is shown
        currentScore = loadScore();
    }
    

    public LevelScene(Game game, int currentScore) {
        // TODO Auto-generated constructor stub
        super(game);
        batch = new SpriteBatch();
        entityManager.create();
        background = new Texture(Gdx.files.internal("background/space.png"));
        font = new BitmapFont();
        layout = new GlyphLayout();
        this.currentScore = currentScore; // Assign passed score to currentScore
    }


    @Override
    public void show() {
        AssetsManager.queueLevelMusic();
        AssetsManager.getManager().finishLoading();
        playingSong = AssetsManager.getManager().get(AssetsManager.playingSongPath);
        playingSong.setVolume(audioSettings.getAudioVolume());
        playingSong.setLooping(true);
        if (audioSettings.isAudioEnabled()) {
            playingSong.play();
        }
        // On create
        Gdx.input.setInputProcessor(new InputAdapter() {
            // Return to menu upon pressing Escape button 
            @Override
            public boolean keyDown(int keyCode) {
                if (keyCode == Input.Keys.ESCAPE) {
                    game.setScreen(new PauseScene(game, currentScore));
                }
                return true;
            }
        });
        

        entityManager.spawnEnemy();

    }


    @Override
    public void render(float deltaTime) {
        // When running
        ScreenUtils.clear(0, 0.2f, 0, 0);
        batch.begin();
        batch.draw(background, 0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
        
        timer += deltaTime;
        
        
        // Spawn entities (Create objects)
        entityManager.spawnEnemyBullet();
        
        
        // Update entities
        entityManager.updatePlayerBullet(deltaTime);
        entityManager.updateEnemies(deltaTime);
        entityManager.updateEnemyBullet(deltaTime);

        
        //entityManager.swapEnemyRow(deltaTime);
        if (timer >= swapInterval) 
        {
            entityManager.swapEnemyRow(deltaTime);
            timer = 0; // Reset the timer
        }

        //Get playerHealth 
        
        if (entityManager.getPlayer().getPlayerHealth() == 0)
        {
            // Clear and reset entities
            entityManager.resetEntities();
            // Proceed to Game Over Scene once player is dead
            game.setScreen(new GameOverScene(game));
            System.out.println("Player is dead");
        }
        
        if (entityManager.getEnemyList().isEmpty() == true) {
            // Proceed to Game Over Scene once player has killed all enemies
            entityManager.respawnEnemies();
            entityManager.spawnEnemy();
            //entityManager.spawnEnemy();
        }
        
        
        if (entityManager.spaceWordExist() == 0)
        {
            entityManager.respawnEnemies();
            entityManager.spawnEnemy();
        }
        
        // Update current score based on player's score
        currentScore = entityManager.getPlayer().getScore();
        
        // Save the current score
        saveScore(currentScore);

        
        
        
        // Show score on top-right hand corner of screen 
        float x = Gdx.graphics.getWidth() - layout.width - 200;
        float y = Gdx.graphics.getHeight() - 50;
        scoreText = "Score: " + currentScore;
        
        font.setColor(255, 255, 255, 255);
        font.draw(batch, scoreText, x, y);
        font.getData().setScale(2, 2);
        
        // Display enemy words
        for (int i = 0; i < entityManager.getEnemyList().size(); i++)
        {
            layout = new GlyphLayout(font, entityManager.getEnemyList().get(i).getEnemyWord());
            float width = layout.width;
            x = entityManager.getEnemyList().get(i).getX() + (entityManager.getEnemyList().get(i).getWidth() - width) / 2;
            y = entityManager.getEnemyList().get(i).getY() + entityManager.getEnemyList().get(i).getHeight() + 30;
            
            font.draw(batch, entityManager.getEnemyList().get(i).getEnemyWord(), x, y);
        }
        
        // Render entities
        entityManager.renderPlayer(batch);
        entityManager.renderPlayerBullet(batch);
        entityManager.renderEnemies(batch);
        entityManager.renderEnemyBullet(batch);
        
        // Let IO Manager handle inputs
        ioManager.handleInput(entityManager.getPlayer());
        
        // Collisions
        collisionManager.collideBorder(entityManager.getPlayer(), -30, 30, 30, -30);
        collisionManager.collideAlien(entityManager.getPlayer(), game);
        collisionManager.collidePlayer(entityManager.getPlayer());
        
        batch.end();
    }
    
    @Override
    public void resize(int width, int height) {
    }
    
    @Override
    public void pause() {
    }
    
    @Override
    public void resume() {
    }
    
    @Override
    public void hide() {
        super.hide();
        playingSong.stop();
        // Save the score before transitioning to another scene
        savedScore = currentScore;
        saveScore(savedScore);
    }
    
    @Override
    public void dispose() {
        font.dispose();
        batch.dispose();
        background.dispose();
        
    }
    
    // Method to save the score
    public void saveScore(int score) {
        preferences.putInteger("Score", score);
        preferences.flush(); // Save changes immediately
    }
    
    // Method to load the score
    private int loadScore() {
        return preferences.getInteger("Score", 0); // Return default value if key not found
    }
}

PauseScene.java

package com.mygdx.game.GameLayer.Scenes;

import java.util.List;

import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
import com.badlogic.gdx.utils.viewport.ScreenViewport;
import com.mygdx.game.GameEngine.AssetsManager;
import com.mygdx.game.GameEngine.Scene.SceneManager;
import com.mygdx.game.GameLayer.Entities.Enemy;

public class PauseScene extends SceneManager {
    private Stage stage;
    private SpriteBatch batch;
    private Skin skin;
    private Texture background;
    private Label pauseLabel;
    private int currentScore;

    public PauseScene(Game game) {
        super(game);
        // TODO Auto-generated constructor stub
        batch = new SpriteBatch();
        stage = new Stage(new ScreenViewport());

        AssetsManager assetsManager = getAssetManager();
        assetsManager.queueAddSkin();
        assetsManager.getManager().finishLoading();
    }


    public PauseScene(Game game, int currentScore) {
        // TODO Auto-generated constructor stub
        super(game);
        this.currentScore = currentScore;

        batch = new SpriteBatch();
        stage = new Stage(new ScreenViewport());

        AssetsManager assetsManager = getAssetManager();
        assetsManager.queueAddSkin();
        assetsManager.getManager().finishLoading();
    }


    @Override
    public void show() {
        background = new Texture(Gdx.files.internal("background/space.png"));
        stage.clear();
        Gdx.input.setInputProcessor(stage);

        Table table = new Table();
        table.setFillParent(true);

        stage.addActor(table);

        skin = getAssetManager().getSkin();


        // Resume button
        TextButton resumeButton = new TextButton("Resume", skin);
        resumeButton.addListener(new ChangeListener() {
            @Override
            public void changed(ChangeEvent event, Actor actor) {
                game.setScreen(new LevelScene(game));
            }
        });

        // Settings button
        TextButton settingsButton = new TextButton("Settings", skin);
        settingsButton.addListener(new ChangeListener() {
            @Override
            public void changed(ChangeEvent event, Actor actor) {
                game.setScreen(new SettingsScene(game));
            }
        });

        // Main Menu Button
        TextButton mainMenuButton = new TextButton("Main Menu", skin);
        mainMenuButton.addListener(new ChangeListener() {
            @Override
            public void changed(ChangeEvent event, Actor actor) {
                // Save the score when transitioning to another scene
                game.setScreen(new LevelScene(game, currentScore));
            }
        });


        table.row().pad(5, 0, 5, 0);;
        table.add(resumeButton);
        table.row().pad(5, 0, 5, 0);;
        table.add(settingsButton);
        table.row().pad(5, 0, 5, 0);;
        table.add(mainMenuButton);
    }


    @Override
    public void render(float deltatime) {
        Gdx.gl.glClearColor(0f, 0.2f, 0f, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        batch.begin();

        batch.draw(background, 0, 0 , Gdx.graphics.getWidth(), Gdx.graphics.getHeight());

        batch.end();

        stage.act(Math.min(Gdx.graphics.getDeltaTime(), 1/30f));
        stage.draw();
    }

    @Override 
    public void resize(int width, int height) {
        // Resize stage
        stage.getViewport().update(width, height, true);
    }

    @Override
    public void pause() {
    }

    @Override
    public void resume() {
    }


    @Override
    public void hide() {
        super.hide();
        Gdx.input.setInputProcessor(null); // Clear input processor when hiding the scene
    }


    @Override
    public void dispose() {
        stage.dispose();
    }
}
\$\endgroup\$
1

1 Answer 1

0
\$\begingroup\$

You resumeButton does not pass the score when creating the new LevelScene:

TextButton resumeButton = new TextButton("Resume", skin);
resumeButton.addListener(new ChangeListener() {
    @Override
    public void changed(ChangeEvent event, Actor actor) {
        game.setScreen(new LevelScene(game));
    }
});

You need to pass the currentScore:

TextButton resumeButton = new TextButton("Resume", skin);
resumeButton.addListener(new ChangeListener() {
    @Override
    public void changed(ChangeEvent event, Actor actor) {
        // Call the second constructor of LevelScene here instead, and pass the current score
        game.setScreen(new LevelScene(game, currentScore));
    }
});
\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.