Solucionado (ver solução)
Solucionado
(ver solução)
6
respostas

Erro getAltura()

Bom dia

estou com um pequeno erro parece ser bem simples mas apesar de rever varias vezes e observar bem o codigo não consegui resolver... desde já agradeço pela atenção...

package br.com.alura.jumper.graphic;

import android.content.Context;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.WindowManager;

public class Tela {

    private DisplayMetrics metrics;

    public Tela(Context context) {
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        metrics = new DisplayMetrics();
        display.getMetrics(metrics);
    }

    public int getAltura(){
        return metrics.heightPixels;
    }
}
package br.com.alura.jumper.elements;

import android.graphics.Canvas;
import android.graphics.Paint;

import br.com.alura.jumper.graphic.Cores;
import br.com.alura.jumper.graphic.Tela;

public class Cano {

    private Tela tela;
    private int alturaDoCanoInferior;
    private int alturaDoCanoSuperior;
    private static final  int TAMANHO_DO_CANO = 250;
    private static final int LARGURA_DO_CANO = 100;
    private static final Paint VERDE = Cores.getCorDoCano();
    private int posicao;

    public Cano(Tela tela, int posicao){
        this.tela = tela;
        this.posicao = posicao;
        alturaDoCanoInferior = tela.getAltura() - TAMANHO_DO_CANO - valorAleatorio();
        alturaDoCanoSuperior = 0 + TAMANHO_DO_CANO + valorAleatorio();
    }

    private int valorAleatorio() {
        return (int) (Math.random() * 150);
    }

    public  void desenhaNo(Canvas canvas){
        desenhaCanoInferiorNo(canvas);
        desenhaCanoSuperiorNo(canvas);
    }

    private void desenhaCanoSuperiorNo(Canvas canvas){
        canvas.drawRect(posicao, 0, posicao + LARGURA_DO_CANO, alturaDoCanoSuperior, VERDE);
    }

    private void desenhaCanoInferiorNo(Canvas canvas) {
        canvas.drawRect(posicao, alturaDoCanoInferior, posicao + LARGURA_DO_CANO, tela.getAltura(), VERDE);
    }

    public void move() {
        this.posicao -= 5;
    }

    public boolean saiuDaTela() {
        return posicao + LARGURA_DO_CANO < 0;
    }

    public int getPosicao() {
        return posicao;
    }
}
02-17 13:27:34.282 8781-8781/br.com.alura.jumper I/art: Not late-enabling -Xcheck:jni (already on)
02-17 13:27:34.282 8781-8781/br.com.alura.jumper I/art: Late-enabling JIT
02-17 13:27:34.487 8781-8781/br.com.alura.jumper I/art: JIT created with code_cache_capacity=2MB compile_threshold=1000
02-17 13:27:35.078 8781-8781/br.com.alura.jumper W/System: ClassLoader referenced unknown path: /data/app/br.com.alura.jumper-2/lib/arm
02-17 13:27:35.643 8781-8788/br.com.alura.jumper W/art: Suspending all threads took: 22.908ms
02-17 13:27:36.122 8781-8788/br.com.alura.jumper W/art: Suspending all threads took: 8.303ms
02-17 13:27:36.576 8781-8792/br.com.alura.jumper I/art: Background sticky concurrent mark sweep GC freed 4829(334KB) AllocSpace objects, 0(0B) LOS objects, 0% free, 5MB/5MB, paused 1.335ms total 114.864ms
02-17 13:27:36.723 8781-8792/br.com.alura.jumper I/art: Background partial concurrent mark sweep GC freed 64(2656B) AllocSpace objects, 0(0B) LOS objects, 40% free, 5MB/9MB, paused 2.149ms total 107.200ms
02-17 13:27:37.623 8781-8788/br.com.alura.jumper W/art: Suspending all threads took: 6.736ms
02-17 13:27:38.631 8781-8788/br.com.alura.jumper W/art: Suspending all threads took: 13.725ms
02-17 13:27:39.176 8781-8788/br.com.alura.jumper W/art: Suspending all threads took: 56.069ms
02-17 13:27:40.141 8781-8788/br.com.alura.jumper W/art: Suspending all threads took: 19.782ms
02-17 13:27:40.489 8781-8832/br.com.alura.jumper D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true
02-17 13:27:40.531 8781-8781/br.com.alura.jumper D/: HostConnection::get() New Host Connection established 0xae9101e0, tid 8781
02-17 13:27:40.670 8781-8832/br.com.alura.jumper D/: HostConnection::get() New Host Connection established 0xae9102a0, tid 8832
02-17 13:27:40.684 8781-8832/br.com.alura.jumper I/OpenGLRenderer: Initialized EGL, version 1.4
02-17 13:27:40.759 8781-8832/br.com.alura.jumper W/EGL_emulation: eglSurfaceAttrib not implemented
02-17 13:27:40.759 8781-8832/br.com.alura.jumper W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xb08f7180, error=EGL_SUCCESS
02-17 13:27:41.043 8781-8815/br.com.alura.jumper D/: HostConnection::get() New Host Connection established 0xad15d4e0, tid 8815
02-17 13:27:58.281 8781-8815/br.com.alura.jumper E/AndroidRuntime: FATAL EXCEPTION: Thread-135
02-17 13:27:58.281 8781-8815/br.com.alura.jumper E/AndroidRuntime: Process: br.com.alura.jumper, PID: 8781
02-17 13:27:58.281 8781-8815/br.com.alura.jumper E/AndroidRuntime: java.lang.NullPointerException: Attempt to invoke virtual method 'int br.com.alura.jumper.graphic.Tela.getAltura()' on a null object reference
02-17 13:27:58.281 8781-8815/br.com.alura.jumper E/AndroidRuntime:     at br.com.alura.jumper.elements.Cano.<init>(Cano.java:22)
02-17 13:27:58.281 8781-8815/br.com.alura.jumper E/AndroidRuntime:     at br.com.alura.jumper.elements.Canos.move(Canos.java:43)
02-17 13:27:58.281 8781-8815/br.com.alura.jumper E/AndroidRuntime:     at br.com.alura.jumper.engine.Game.run(Game.java:58)
02-17 13:27:58.281 8781-8815/br.com.alura.jumper E/AndroidRuntime:     at java.lang.Thread.run(Thread.java:818)
02-17 13:27:59.912 8781-8788/br.com.alura.jumper W/art: Suspending all threads took: 82.694ms
02-17 13:32:58.715 8781-8815/br.com.alura.jumper I/Process: Sending signal. PID: 8781 SIG: 9
6 respostas

Posta a classe Game também, por favor?

package br.com.alura.jumper.engine;


import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;

import br.com.alura.jumper.R;
import br.com.alura.jumper.elements.Cano;
import br.com.alura.jumper.elements.Canos;
import br.com.alura.jumper.elements.Passaro;
import br.com.alura.jumper.graphic.Tela;

public class Game extends SurfaceView implements Runnable, View.OnTouchListener {

    private boolean isRunning = true;
    private SurfaceHolder holder =  getHolder();
    private Passaro passaro;
    private Canos canos;
    private Canvas canvas;
    private Bitmap background;
    private Tela tela;

    public Game(Context context) {
        super(context);

        tela = new Tela(context);
        inicializaElementos();
        setOnTouchListener(this);

    }

    private void inicializaElementos(){
        passaro = new Passaro(tela);
        canos = new Canos(tela);
        Bitmap back = BitmapFactory.decodeResource(getResources(), R.drawable.background);
        background = Bitmap.createScaledBitmap(back, back.getWidth(), tela.getAltura(),false);
    }

    @Override
    public void run() {
        while (isRunning){
            if(!holder.getSurface().isValid()) continue;
            //Canvas canvas = holder.lockCanvas();
            canvas = holder.lockCanvas();

            //desendo dos componentes do jogo
            canvas.drawBitmap(background,0, 0, null);

            passaro.desenhaNo(canvas);
            passaro.cai();
            canos.desenhaNo(canvas);
            canos.move();

            holder.unlockCanvasAndPost(canvas);
        }
    }

    public void inicia() {
        isRunning = true;
    }

    public void pausa() {
        isRunning = false;
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        passaro.pula();
        return false;
    }
}

Tudo parece estar certo nessas classes. Me mostra a classe Canos agora, por favor?

package br.com.alura.jumper.elements;

import android.graphics.Canvas;

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

import br.com.alura.jumper.graphic.Tela;

public class Canos {

    private final List<Cano> canos = new ArrayList<Cano>();
    private static final int QUANTIDADE_CANOS = 5;
    private static final int DISTANCIA_ENTRE_CANOS = 200;
    private Tela tela;

    public Canos(Tela tela){
        int posicao = 400;

        for (int i = 0; i < QUANTIDADE_CANOS; i++){
            posicao += DISTANCIA_ENTRE_CANOS;
            Cano cano = new Cano(tela, posicao);
            canos.add(cano);
        }
    }

    public void desenhaNo(Canvas canvas) {
        for(Cano cano : canos){
            cano.desenhaNo(canvas);
        }
    }

    public void move(){
        ListIterator<Cano> iterator =  canos.listIterator();
        while (iterator.hasNext()){
            Cano cano = iterator.next();
            cano.move();

            if (cano.saiuDaTela()) {
                //criar outro cano
                iterator.remove();
                Cano outroCano = new Cano(tela, getMaximo() + DISTANCIA_ENTRE_CANOS);
                iterator.add(outroCano);
            }
        }
    }

    private int getMaximo() {
        int maximo = 0;
        for(Cano cano : canos){
            maximo =  Math.max(cano.getPosicao(), maximo);
        }
        return maximo;
    }
}
solução!

Você esqueceu de atribuir a tela recebida no construtor ao seu atributo:

    public Canos(Tela tela){
        this.tela = tela;
        int posicao = 400;

        for (int i = 0; i < QUANTIDADE_CANOS; i++){
            posicao += DISTANCIA_ENTRE_CANOS;
            Cano cano = new Cano(tela, posicao);
            canos.add(cano);
        }
    }

Obrigado era isso mesmo sabia que era algo simples...