Search code examples
androidlibgdx

trying to animate a coin in flappy bird android game using LibGDX


public class PlayState extends State {

private static final int TUBE_SPACING = 125;
private static final int TUBE_COUNT = 4;
private static final int GROUND_Y_OFFSET = -30;
private static final int COIN_SPACING = 100;
private static final int COIN_COUNT = 2;


public int SCORE = 0;

private Bird bird;
private Coin coin;

private Texture bg;
private Texture ground;
private Vector2 groundPos1, groundPos2;

private Array<Tube> tubes;

private Array<Coin> coins;

public PlayState(GameStateManager gsm) {
    super(gsm);
    bird = new Bird(50, 300);

    cam.setToOrtho(false, FlappyDemo.WIDTH / 2, FlappyDemo.HEIGHT / 2);
    bg = new Texture("bg.png");
    ground = new Texture("ground.png");
    groundPos1 = new Vector2(cam.position.x - cam.viewportWidth / 2, GROUND_Y_OFFSET);
    groundPos2 = new Vector2((cam.position.x - cam.viewportWidth / 2) + ground.getWidth(), GROUND_Y_OFFSET);

    tubes = new Array<Tube>();

    for(int i = 1; i <= TUBE_COUNT; i++){
        tubes.add(new Tube(i * (TUBE_SPACING + Tube.TUBE_WIDTH)));
    }

    coins = new Array<Coin>();
    for(int i = 1; i<= COIN_COUNT; i++){
        coins.add(new Coin(i * (COIN_SPACING + (Coin.COIN_WIDTH / 3))));
    }

}

@Override
protected void handleInput() {
    if(Gdx.input.justTouched()){
        bird.jump();
    }
}

@Override
public void update(float dt) {
    handleInput();
    updateGround();
    bird.update(dt);
    coin.update(dt);
    cam.position.x = bird.getPosition().x +80;
    updateCoin();
    updateTube();

    if(bird.getPosition().y <= ground.getHeight() + GROUND_Y_OFFSET){
        gsm.set(new MenuState(gsm));
        System.out.println("Score : "+SCORE);
    }
    cam.update();
}

@Override
public void render(SpriteBatch sb) {
    sb.setProjectionMatrix(cam.combined);
    sb.begin();
    sb.draw(bg, 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.getPosBotTube().x, tube.getPosBotTube().y);
    }
    for(Coin coin : coins){
        sb.draw(coin.getTexture(), coin.getPosCoin().x, coin.getPosCoin().y);
    }
    sb.draw(ground, groundPos1.x, groundPos1.y);
    sb.draw(ground, groundPos2.x, groundPos2.y);
    sb.end();
}

@Override
public void dispose() {
    bg.dispose();
    bird.dispose();
    ground.dispose();
    for(Tube tube : tubes)
        tube.dispose();
    for(Coin coin : coins)
        coin.dispose();
    System.out.println("PlayState 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);
}

private void updateTube(){
    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())){
            gsm.set(new MenuState(gsm));
            System.out.println("Score : "+SCORE);
        }
    }
}

private void updateCoin(){
    for(int i = 0; i< coins.size; i++){
        Coin coin = coins.get(i);

        if(cam.position.x - (cam.viewportWidth / 2) > coin.getPosCoin().x + coin.getTexCoin().getWidth()){
            coin.reposition(coin.getPosCoin().x + ((Coin.COIN_WIDTH + COIN_SPACING) * COIN_COUNT));
        }
        if(coin.collides(bird.getBounds())){
            SCORE = SCORE + 10;
            System.out.println("Collided");
        }
    }
}

}

public class Coin {

public static final int COIN_WIDTH  = 32;
public static final int COIN_HEIGHT  = 32;
public static final int COIN_SCORE = 10;
private static final int FLUCTUATION = 150;
private static final int COIN_GAP = 100;

private Texture texCoin;
private Vector2 posCoin;
private Rectangle boundsCoin;
private Random randCoin;
private Animation coinAnimation;


public Coin(int x){
    texCoin = new Texture("Coin.png");
    randCoin = new Random();

    posCoin = new Vector2(x, randCoin.nextInt(Tube.TUBE_GAP) + COIN_GAP);
    coinAnimation = new Animation(new TextureRegion(texCoin), 3, 0.5f);
    boundsCoin = new Rectangle(x, posCoin.y, texCoin.getWidth() / 3, texCoin.getHeight());
}

public void update(float dt){
   try{
       coinAnimation.update(dt);
       posCoin.set(randCoin.nextInt(FLUCTUATION) + COIN_GAP, randCoin.nextInt(FLUCTUATION)+ Tube.TUBE_GAP);
       boundsCoin.setPosition(posCoin.x, posCoin.y);
   }catch(Exception e){
       System.out.println("Errrrrr!");
   }
}

public Texture getTexCoin() { return texCoin;}

public Vector2 getPosCoin() { return posCoin;}

public TextureRegion getTexture() {
    return coinAnimation.getFrame();
}

public void reposition(float x){
    posCoin.set(x, randCoin.nextInt(FLUCTUATION) + COIN_GAP);
    boundsCoin.setPosition(posCoin.x, posCoin.y);
}

public boolean collides(Rectangle coinBound){
    return coinBound.overlaps(boundsCoin);
}

public void dispose(){
    texCoin.dispose();
}

}

Exception in thread "LWJGL Application" java.lang.NullPointerException at com.games.flappy.statess.PlayState.update(PlayState.java:75) at com.games.flappy.statess.GameStateManager.update(GameStateManager.java:31) at com.games.flappy.FlappyDemo.render(FlappyDemo.java:37) at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:223) at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:124)


Solution

  • Is it blowing up on:

    coin.update(dt);
    

    You have a coin variable, but doesn't look like you actually assign anything to it. The rest of your code acts on the coins array, which contains many individual coin objects, of course. But I don't think the coin variable references anything does it? (Hard to tell what line 75 is actually pointing to)