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

Erro canvas

Boa tarde

Está dando um erro relacionado ao canvas abaixo está a lista, está sendo desenvolvido em Android Studio... fico no aguardo e desde já agradeço....

02-12 12:46:47.815 1008-1008/br.com.alura.jumper I/art: Not late-enabling -Xcheck:jni (already on) 
02-12 12:46:47.816 1008-1008/br.com.alura.jumper I/art: Late-enabling JIT 
02-12 12:46:47.898 1008-1008/br.com.alura.jumper I/art: JIT created with code_cache_capacity=2MB compile_threshold=1000 
02-12 12:46:48.493 1008-1008/br.com.alura.jumper W/System: ClassLoader referenced unknown path: /data/app/br.com.alura.jumper-2/lib/arm 
02-12 12:46:49.781 1008-1037/br.com.alura.jumper E/AndroidRuntime: FATAL EXCEPTION: Thread-139 
02-12 12:46:49.781 1008-1037/br.com.alura.jumper E/AndroidRuntime: Process: br.com.alura.jumper, PID: 1008 
02-12 12:46:49.781 1008-1037/br.com.alura.jumper E/AndroidRuntime: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.graphics.Canvas.drawCircle(float, float, float, android.graphics.Paint)' on a null object reference 
02-12 12:46:49.781 1008-1037/br.com.alura.jumper E/AndroidRuntime: at br.com.alura.jumper.elements.Passaro.desenhaNo(Passaro.java:21) 
02-12 12:46:49.781 1008-1037/br.com.alura.jumper E/AndroidRuntime: at br.com.alura.jumper.engine.Game.run(Game.java:34) 
02-12 12:46:49.781 1008-1037/br.com.alura.jumper E/AndroidRuntime: at java.lang.Thread.run(Thread.java:818) 
02-12 12:46:49.920 1008-1048/br.com.alura.jumper D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true 
02-12 12:46:49.949 1008-1008/br.com.alura.jumper D/: HostConnection::get() New Host Connection established 0xb23ff650, tid 1008 
02-12 12:46:50.332 1008-1048/br.com.alura.jumper I/OpenGLRenderer: Initialized EGL, version 1.4 
02-12 12:46:50.446 1008-1048/br.com.alura.jumper W/EGL_emulation: eglSurfaceAttrib not implemented 
02-12 12:46:50.446 1008-1048/br.com.alura.jumper W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xaca7f9e0, error=EGL_SUCCESS 
02-12 12:46:50.583 1008-1016/br.com.alura.jumper W/art: Suspending all threads took: 34.393ms 
02-12 12:46:51.001 1008-1008/br.com.alura.jumper I/Choreographer: Skipped 47 frames! The application may be doing too much work on its main thread. 
02-12 12:46:51.769 1008-1048/br.com.alura.jumper E/Surface: getSlotFromBufferLocked: unknown buffer: 0xaca79bf0 
02-12 12:51:50.204 1008-1037/br.com.alura.jumper I/Process: Sending signal. PID: 1008 SIG: 9
4 respostas

Olhando a stacktrace, dá pra ver o que causou o problema na sua aplicação:

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.graphics.Canvas.drawCircle(float, float, float, android.graphics.Paint)' on a null object reference

Dá uma olhada na linha 21 da sua classe Passaro, lá no método desenhaNo. Provavelmente você está fazendo algo como:

public void desenhaNo(Canvas canvas) {
    canvas.drawCircle(...);
}

Mas está recebendo null no lugar desse canvas.

Se for isso, confere quem é o canvas que você passa na linha 34 da classe Game, onde você faz:

passaro.desenhaNo(canvas);

Você provavelmente esqueceu de fazer:

canvas = holder.lockCanvas();

Boa noite

Ainda está dando erro vou colocar as duas classes aqui

package br.com.alura.jumper.elements;

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


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

public class Passaro {

    private static final float X = 100;
    private static final float RAIO = 50;
    private static final Paint VERMELHO = Cores.getCorDoPassaro();
    private float altura;

    public Passaro(){
        this.altura = 100;
    }

    public void desenhaNo(Canvas canvas){
        canvas.drawCircle(X,altura, RAIO, VERMELHO);    //linha 22
    }

    public void cai() {
        this.altura += 5;
    }
}
package br.com.alura.jumper.engine;


import android.content.Context;
import android.graphics.Canvas;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import br.com.alura.jumper.elements.Passaro;

public class Game extends SurfaceView implements Runnable{

    private boolean isRunning = true;
    private SurfaceHolder holder =  getHolder();
    private Passaro passaro;
    private Canvas canvas;

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

        inicializaElementos();
    }

    private void inicializaElementos(){
        passaro = new Passaro();
    }

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


            //desendo dos componentes do jogo
            passaro.desenhaNo(canvas);      // linha 37
            passaro.cai();

            holder.unlockCanvasAndPost(canvas);
        }
    }

    public void inicia() {
        isRunning = true;
    }

    public void pausa() {
        isRunning = false;
    }
}
solução!

Dentro do loop principal da classe Game, faltou você negar o que está no if, deixando-o com essa cara:

if(!holder.getSurface().isValid()) continue;

Com isso, seu código funcionará.

Obrigado deu certo, acabei não observando bem...