miércoles, 28 de septiembre de 2011

Animación de sprites en libGDX

El funcionamiento de la aplicación se basa en que debe mostrar una moneda y como gira una serie aleatoria de veces.

Aunque se podría haber hecho de diferente manera en el caso de la primera versión de esta animación la realizaremos mediante un sprite para lo que en primer lugar debemos contar con una imagen en la que se define cada uno de los frames que definiran esta animación. En el caso de la moneda de Head or Tails es la siguiente imagen:

Para utilizar cualquier imagen en libGDX esta debe tener un tamaño en pixeles múltiplo de potencia de 2 (p.ej. 64x64, 128x256, etc.). Y dentro del proyecto en Eclipse, al igual que para cualquier recurso adicional se deberá poner en la carpeta assets o una subcarpeta en este.

Ahora ya podemos empezar a programar la animación de la moneda. Dentro de la clase ViewCoin que se creo al crear el proyecto se debe implementar los métodos create() y render().

En primer lugar se crean las variables y constantes necesarias:


    // Constantes que definen el número de columnas y filas que definen los frames de la imagen.
    private static final int        FRAME_COLS = 5;
    //Hay que tener en cuenta que en nuestro caso el número de filas real es 4.
    private static final int        FRAME_ROWS = 5;
    // Objeto que define los propiedades de la animación.
    Animation coinAnim;
    // Imagen que contiene la imagen cargada.
    Texture coinSheet;
    // Array con cada uno de los frames definidos en la imagen.
    TextureRegion[] coinFrames;
    // Objeto que se encarga de dibujar la imagen (en nuestro caso región de la imagen (es decir cada frame)).
    SpriteBatch spriteBatch;
    // Frame que se dibuja actualmente en la pantalla.
   
TextureRegion currentFrame;
     // Tiempo transcurrido desde el inicio de la animación.
    float stateTime;

 En el caso del método create(), se carga la imagen y a partir de esta se define cada uno de los frames de la animación teniendo en cuenta que la última fila de la imagen está vacía, lo que se muestra en el siguiente código:

public void create() {
        // Se carga la imagen desde la imgs en la carpeta asstes
        coinSheet = new Texture(Gdx.files.internal("imgs/hot_coin_anim.png"));
        // Se divide primero en un array bidimensional de frames que convertimos a uno unidimesional que es el que puede tratar libGDX.
       
TextureRegion[][] tmp = TextureRegion.split(coinSheet, coinSheet.getWidth()/FRAME_COLS, coinSheet.getHeight()/FRAME_ROWS);
        coinFrames = new TextureRegion[FRAME_COLS * (FRAME_ROWS - 1)];
        int index = 0;
        // !! La última fila no se carga.
        for (int i = 0; i < FRAME_ROWS - 1; i++) {
            for (int j = 0; j < FRAME_COLS; j++) {
                    coinFrames[index++] = tmp[i][j];
            }
        }
        // Se define la animación con un tiempo entre frames de 0.035 segundos y los frames cargados.
        coinAnim = new Animation(0.035f,  coinFrames);
        spriteBatch = new SpriteBatch();
        stateTime = 0f;
    }


Por último en el método render() se define, según el tiempo que haya pasado desde la última transición entre frames, el frame actual y se dibuja en la región de la pantalla deseada:

    public void render() {
                // Se limpia la pantalla.
               
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
                // Se selecciona el frame actual.
                stateTime += Gdx.graphics.getDeltaTime();
                currentFrame = coinAnim.getKeyFrame(stateTime, true);
                // Se dibuja.
                spriteBatch.begin();
                spriteBatch.draw(currentFrame, 50, 50);
                spriteBatch.end();
    }

Si ejecutamos el proyecto nos debería aparecer una moneda que gira constantemente desde que se inicia la aplicación.

1 comentario:

  1. Hola que tal te felicito es un gran aporte lo que tu haces tengo una gran inquietud he probado tu codigo pero me da error en las siguientes lineas :
    coinAnim = new Animation(0.035f, coinFrames);
    y en
    currentFrame = ((Object) coinAnim).getKeyFrame(stateTime, true);

    en la primera linea es error de: Cannot instantiate the type Animation

    y en la segunda error de : The method getKeyFrame(float, boolean) is undefined for the type Object
    talvez me puedes ayudar no se que hacer garcias

    ResponderEliminar