简体   繁体   English

Libgdx音乐处理不当

[英]Libgdx music not disposing properly

I have this libgdx side scrolling game and the music file(mp3) keeps on playing over itself instead of being disposed and playing a single time.It sounds like multiple music files are playing at the same time and the game gets slow and crashes. 我有这个libgdx侧滚动游戏,音乐文件(mp3)继续播放,而不是被处理和播放一次。听起来好像多个音乐文件同时播放,游戏变慢和崩溃。

The game goes from MenuState(the menu)>>PlayState(the actual playing area)>>GameOverState(the gameover class)>>PlayState>>GameOverState and so on... 游戏从MenuState(菜单)>> PlayState(实际播放区域)>> GameOverState(gameover类)>> PlayState >> GameOverState等进行...

The music in the playstate keeps on playing without disposing itself and the game crashes. 播放状态中的音乐继续播放而不会自行处理并且游戏崩溃。

Here's my PlayState 这是我的PlayState

package com.mygdx.game.States;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.TimeUtils;
import com.mygdx.game.GrumpyDemo;
import com.mygdx.game.Sprites.Bird;
import com.mygdx.game.Sprites.Tube;

/**
 * Created by Kronos on 28-01-2017.
 */

public class PlayState extends State {
private static final int TUBE_SPACING = 75;
private static final int TUBE_COUNT = 4;

private Bird bird;
private Texture actualGamebg;
private Tube tube ;
private Texture ground;
private Vector2 groundPos1,groundPos2;
private static final int HIGHEST_GROUND_LIMIT = -30;
private Array<Tube> tubes;
private int k;
long startTime=0;
private Music mainMusic;
private Music scoreIncrease;
private Music wingFlap;
public BitmapFont font24;
public String SCORE;
public int l;

public PlayState(GameStateManager gsm) {
    super(gsm);
    bird = new Bird(0,300);
    actualGamebg = new Texture("bg.png");
    cam.setToOrtho(false, GrumpyDemo.WIDTH/2,GrumpyDemo.HEIGHT/2);

    tubes =new Array<Tube>();
    ground = new Texture("ground.png");
    mainMusic = Gdx.audio.newMusic(Gdx.files.internal("mainmusic.mp3"));
    scoreIncrease = Gdx.audio.newMusic(Gdx.files.internal("smw_coin.ogg"));
    wingFlap = Gdx.audio.newMusic(Gdx.files.internal("sfx_wing.ogg"));

    font24= new BitmapFont();
    SCORE = new String();
    fontGenerator();
    groundPos1 = new Vector2(cam.position.x -cam.viewportWidth/2, HIGHEST_GROUND_LIMIT);
    groundPos2 = new Vector2((cam.position.x - cam.viewportWidth/2) + ground.getWidth(),HIGHEST_GROUND_LIMIT);
    startTime = TimeUtils.nanoTime();

    for(int i=1 ; i<=TUBE_COUNT; i++){
        tubes.add(new Tube(i* (TUBE_SPACING + Tube.TUBE_WIDTH)));
    }
    mainMusic.play();
    mainMusic.setVolume(0.8f);
    mainMusic.setLooping(true);
}

@Override
protected void handleInput() {
    if (Gdx.input.justTouched())
        bird.jump();
    wingFlap.setLooping(false);
    wingFlap.play();
    wingFlap.setVolume(0.1f);
}

@Override
public void update(float dt) {
    handleInput();
    updateGround();
    bird.update(dt);
    if (TimeUtils.timeSinceNanos(startTime) > 1400000000)
    {
        Score();
        startTime = TimeUtils.nanoTime();
    }
    SCORE = String.valueOf(k);

    for(int i =0 ; i< tubes.size;i++)
    {
        Tube tube= tubes.get(i);
        if (cam.position.x - (cam.viewportWidth/2) > tube.getPosTopTube().x + tube.getTopTube().getWidth())
        {
            tube.reposition(tube.getPosTopTube().x + ((Tube.TUBE_WIDTH + TUBE_SPACING) *TUBE_COUNT));
        }
        if(tube.collides(bird.getBounds()))
        {
            cam.position.x = bird.getPosition().x;
            mainMusic.stop();
            gsm.set(new GameOverState(gsm));
            l=k;
        }

        else
            cam.position.x = bird.getPosition().x +80;
    }
    if (bird.getPosition().y <= ground.getHeight()){
        gsm.set(new GameOverState(gsm));
        l = k;
    }

    cam.update();
}

@Override
public void render(SpriteBatch sb) {

    sb.setProjectionMatrix(cam.combined);
    sb.begin();
    sb.draw(actualGamebg, cam.position.x - (cam.viewportWidth/2), 0);
    sb.draw(bird.getTexture(), bird.getPosition().x , bird.getPosition().y);
    for(Tube tube: tubes) {

        sb.draw(tube.getTopTube(), tube.getPosTopTube().x, tube.getPosTopTube().y);
        sb.draw(tube.getBottomTube(), tube.getPosBottomTube().x, tube.getPosBottomTube().y);
    }
    sb.draw(ground,groundPos1.x,groundPos1.y);
    sb.draw(ground,groundPos2.x,groundPos2.y);

    font24.draw(sb,SCORE,cam.position.x -2,cam.position.y + 15);
    sb.end();
}

/**
 * spritebatches must be drawn in order .The one at the bottommost acts as the top layer.
 */

@Override
public void dispose() {
    actualGamebg.dispose();
    bird.dispose();
    font24.dispose();
    for(Tube tube: tubes)
    {
        tube.dispose();
    }
    ground.dispose();

    System.out.println("Play State Disposed");
}

private void updateGround()
{
    if (cam.position.x-(cam.viewportWidth/2) > groundPos1.x + ground.getWidth())
    {
        groundPos1.add(ground.getWidth()*2,0);
    }
    if (cam.position.x-(cam.viewportWidth/2) > groundPos2.x + ground.getWidth())
    {
        groundPos2.add(ground.getWidth()*2,0);
    }
}

public void Score()
{
    k++;
    scoreIncrease.play();
    scoreIncrease.setVolume(0.3f);

}
public int getL(){
    return l;
}

public void fontGenerator(){
    FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal("bitmapfont/PressStart2P.ttf"));
    FreeTypeFontGenerator.FreeTypeFontParameter parameter= new FreeTypeFontGenerator.FreeTypeFontParameter();

    parameter.size=12;
    parameter.color= Color.GOLD;
    parameter.borderColor= Color.GOLDENROD;
    font24= generator.generateFont(parameter);
    font24.setUseIntegerPositions(false);
}
}

It then transitions into GameOverState which is: 然后它转换为GameOverState,它是:

package com.mygdx.game.States;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;
import com.badlogic.gdx.math.Vector2;
import com.mygdx.game.GrumpyDemo;
import com.mygdx.game.States.PlayState;

/**
  * Created by Kronos on 28-01-2017.
  */

public class GameOverState extends State {
private Texture gameOver;
private Texture gameOverBg;
private Texture playAgainBtn;
private Texture ground;
private Vector2 groundPos1;
private Music gameOverMusic;
private BitmapFont totalScore;
private String STRING;
public PlayState playState;
public Boolean AdStart = true;

public GameOverState(GameStateManager gsm) {
    super(gsm);
    cam.setToOrtho(false, GrumpyDemo.WIDTH/2,GrumpyDemo.HEIGHT/2);

    gameOver = new Texture("gameover.png");
    gameOverBg =  new Texture ("bg.png");
    playAgainBtn = new Texture("playbtn.png");
    ground = new Texture("ground.png");
    AdStart = new Boolean(true);
    gameOverMusic = Gdx.audio.newMusic(Gdx.files.internal("gameoversfx.ogg"));
    groundPos1 = new Vector2(cam.position.x -cam.viewportWidth/2, -30);
    totalScore =  new BitmapFont();
    STRING = new String();
    playState = new PlayState(gsm);
    gameOverMusic.play();
    gameOverMusic.setVolume(1.0f);
}

@Override
public void handleInput() {
    if (Gdx.input.justTouched())
    {
        gsm.set(new PlayState(gsm));
        gameOverMusic.stop();
        AdStart = false;
    }
}

@Override
public void update(float dt) {
    handleInput();
    STRING = "SCORE: " + playState.getL();
    fontGenerator();
}

@Override
public void render(SpriteBatch sb) {
    sb.setProjectionMatrix(cam.combined);
    sb.begin();
    sb.draw(gameOverBg,0,0);
    sb.draw(gameOver, cam.position.x-gameOver.getWidth()/2 , 5*(cam.position.y/3));
    sb.draw(ground,groundPos1.x,groundPos1.y);
    sb.draw(playAgainBtn,cam.position.x-playAgainBtn.getWidth()/2,2*(cam.position.y/3));
    totalScore.draw(sb,STRING,cam.position.x - gameOver.getWidth()/4 ,5*(cam.position.y/4));

    sb.end();
}

@Override
public void dispose() {
    gameOver.dispose();
    gameOverBg.dispose();
    playAgainBtn.dispose();
    ground.dispose();
    totalScore.dispose();
    playState.dispose();

    System.out.println("Game Over State Disposed");
}

public void fontGenerator(){
    FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal("bitmapfont/PressStart2P.ttf"));
    FreeTypeFontGenerator.FreeTypeFontParameter parameter= new FreeTypeFontGenerator.FreeTypeFontParameter();

    parameter.size=12;
    parameter.color= Color.GOLD;
    parameter.borderColor= Color.GOLDENROD;
    totalScore= generator.generateFont(parameter);
    totalScore.setUseIntegerPositions(false);
}

public Boolean getAdStart(){
    return AdStart;
}
}

I'm still new to this so forgive me if the question is asked inappropriately. 如果不恰当地提出这个问题,我仍然是新手,请原谅我。 Any help is highly appreciated thanks. 非常感谢任何帮助。

You need to stop music of PlayState when you're moving to GameOverState. 当你转移到GameOverState时,你需要停止PlayState的音乐。

As i check you forget to stop music of PlayState when bird position is less than ground height. 当我检查时,当鸟的位置小于地面高度时,你忘了停止播放PlayState的音乐。

if (bird.getPosition().y <= ground.getHeight()){
        gsm.set(new GameOverState(gsm));
        l = k;
}

No need to create music instance each time when PlayState or/and GameOverState called. 每次PlayState或/和GameOverState调用时都不需要创建音乐实例。 Make it at once and use it until you play your game. 立即制作并使用它直到你玩游戏。 Dispose your assets like music and all when you exit game. 当你退出游戏时,像音乐一样处理你的资产。

In some big/heavy game when Assets are very large then need to dispose some Assets when we move from one scene to another scene. 在资产非常庞大的大型/重型游戏中,当我们从一个场景移动到另一个场景时需要处理一些资产。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM