Programación de Juegos en Android 2. Dibujar una imagen utilizando SurfaceView.

En este tutorial vamos a imprimir una imagen directamente en la pantalla android.

Primero vamos a extender un View y después vamos a utilizar un objeto SurfaceView, que es una manera más directa (bajo nivel). Vamos a utilizar SurfaceView porque queremos tener el control de la pantalla.

Crear un nuevo proyecto android

 

Nombre del proyecto: killthemall-training

Nombre de la aplicación: Kill Them All

Nombre del paquete: com.edu4java.android.killthemall

Actividad: Main

 

Paso 1; dibujar con onDraw utilizando View

 

package com.edu4java.android.killthemall;

import android.app.Activity;

import android.os.Bundle;

import android.view.Window;

 

public class Main extends Activity {

    /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        requestWindowFeature(Window.FEATURE_NO_TITLE);

        setContentView(new GameView(this));

    }

}

package com.edu4java.android.killthemall;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.Canvas;

import android.graphics.Color;

import android.view.View;

public class GameView extends View {

      private Bitmap bmp;

 

      public GameView(Context context) {

            super(context);

            bmp = BitmapFactory.decodeResource(getResources(), R.drawable.icon);

      }

      @Override

      protected void onDraw(Canvas canvas) {

          canvas.drawColor(Color.BLACK);

          canvas.drawBitmap(bmp, 10, 10, null);

      }

}

En la implementación de View el método onDraw es llamado directamente por el holder a través de un código que no podemos ver cuando se crea el View. El holder es el objeto que contiene al View.

Cuando implementamos la versión que extiende de SurfaceView, no se llama al método onDraw. Tenemos que llamarlo de una manera explícita.

Para llamar al método onDraw, necesitamos que el objeto Canvas sea pasado como parámetro. Se puede pensar en el Canvas como una pizarra donde podemos pintar lo que queramos.

Para tener todo listo para pintar tenemos que crear un callback listener al holder. En el método surfaceCreated (que es llamado cuando el View se crea), conseguimos el Canvas del holder y después llamamos al método onDraw.

Para conseguir el Canvas, utilizamos el método lockCanvas que bloquea el Canvas para evitar que nadie más dibuje cuando otro está dibujando. Una vez que se termina de dibujar, se desbloquea el Canvas llamando al método unlockCanvasAndPost.

Hay que tener en cuenta que durante el tiempo que se tiene un recurso bloqueado, estamos perdiendo rendimiento y por ello es importante minimizar el tiempo de bloqueo.

 

Paso 1; dibujar con onDraw utilizando SurfaceView

 

public class GameView extends SurfaceView {

       private Bitmap bmp;

       private SurfaceHolder holder;

 

       public GameView(Context context) {

             super(context);

             holder = getHolder();

             holder.addCallback(new SurfaceHolder.Callback() {

 

                    @Override

                    public void surfaceDestroyed(SurfaceHolder holder) {

                    }

 

                    @Override

                    public void surfaceCreated(SurfaceHolder holder) {

                           Canvas c = holder.lockCanvas(null);

                           onDraw(c);

                           holder.unlockCanvasAndPost(c);

                    }

 

                    @Override

                    public void surfaceChanged(SurfaceHolder holder, int format,

                                  int width, int height) {

                    }

             });

             bmp = BitmapFactory.decodeResource(getResources(), R.drawable.icon);

       }

 

       @Override

       protected void onDraw(Canvas canvas) {

             canvas.drawColor(Color.BLACK);

             canvas.drawBitmap(bmp, 10, 10, null);

       }

}

<< Introducción y panorama general Game Loop y Animación >>