Thursday, September 19, 2013

LibGDX Tutorial 5: Tween Engine

The tween engine allows for animation of an object like position, color, rotation, etc.
Create the projects using gdx-setup.ui.jar


Notice that in the Library Selection, the Universal Tween Engine is being used (check box darkened), and it is green (as it was downloaded using last button).

Program
I will have a simple circle sprite:

I will animate it across the window in the x-direction using three of the many different Tween Equations. I will animate it across 11 times.

Now I will have two different packages. The first package if for the two tweening functions - setValues and getValues. Only the first index of the array is used for setting only 1 value. The second package is the standard libgdx file.

SpriteTween.java
package com.tutorials.spritetween;

import com.badlogic.gdx.graphics.g2d.Sprite;

import aurelienribon.tweenengine.TweenAccessor;

public class SpriteTween implements TweenAccessor<Sprite>{ //** Tweening a Sprite **//
    public static final int POSITION_X = 1; //** there will one int declaration per object **//

    @Override
    public int getValues(Sprite target, int tweenType, float[] returnValues) {
        switch(tweenType) {
            case POSITION_X: returnValues[0] = target.getX(); return 1; // ** one case for each object - returned one as only 1 value is being changed **//
            default: assert false; return -1;
        }
    }

    @Override
    public void setValues(Sprite target, int tweenType, float[] newValues) {
        switch (tweenType) {
            case POSITION_X: target.setX(newValues[0]); break;
            default: assert false; break;
        }
    }
}


For the main java file 3 managers are defined as 3 sprite objects are being controlled. In the render I will have to update each of the managers.

MyTweenGame.java
package com.tutorialse.mytweengame;

import aurelienribon.tweenengine.Tween;
import aurelienribon.tweenengine.TweenEquations;
import aurelienribon.tweenengine.TweenManager;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.utils.TimeUtils;
import com.tutorials.spritetween.SpriteTween;

public class MyTweenGame implements ApplicationListener {
    private OrthographicCamera camera;
    private SpriteBatch batch;
    private Texture texture;
    private Texture CircTxt, ElasticTxt, QuadTxt; //** text **//
    private Sprite sprite1, sprite2, sprite3;
    private TweenManager manager1, manager2, manager3;
    private long startTime;
    private long delta;
    private float w,h;
   
    @Override
    public void create() {       
        w = Gdx.graphics.getWidth();
        h = Gdx.graphics.getHeight();
       
        camera = new OrthographicCamera();
        camera.setToOrtho(false, 640, 480);
        batch = new SpriteBatch();
       
        texture = new Texture("circle.png");
        texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
       
        CircTxt = new Texture("CircTxt.png");
        CircTxt.setFilter(TextureFilter.Linear, TextureFilter.Linear);
       
        ElasticTxt = new Texture("ElasticTxt.png");
        ElasticTxt.setFilter(TextureFilter.Linear, TextureFilter.Linear);
       
        QuadTxt = new Texture("QuadTxt.png");
        QuadTxt.setFilter(TextureFilter.Linear, TextureFilter.Linear);
       
        sprite1 = new Sprite(texture);
        sprite1.setPosition(50,0.25f*h);
       
        sprite2 = new Sprite(sprite1); //** sprite2 identical to sprite1 **//
        sprite2.setY(0.5f*h);   //** except for the y position **//
       
        sprite3 = new Sprite(sprite1); //** sprite3 identical to sprite1 **//
        sprite3.setY(0.75f*h);  //** except for the y position **//
       
        Tween.registerAccessor(Sprite.class, new SpriteTween());
        manager1 = new TweenManager();
        Tween.to(sprite1,SpriteTween.POSITION_X,1000f) //** tween POSITION_X for a duration **//
            .target(w-100) // ** final POSITION_X **//
            .ease(TweenEquations.easeInOutQuad) //** easing equation **//
            .repeat(10,1000f) //** ten more times **//
            .start(manager1); //** start it
        manager2 = new TweenManager();
        Tween.to(sprite2,SpriteTween.POSITION_X,1000f) //** tween POSITION_X for a duration **//
            .target(w-100) // ** final POSITION_X **//
            .ease(TweenEquations.easeInOutCirc) //** easing equation **//
            .repeat(10,1000f) //** ten more times **//
            .start(manager2);
        manager3 = new TweenManager();
        Tween.to(sprite3,SpriteTween.POSITION_X,1000f) // ** tween POSITION_X for a duration **/
            .target(w-100) // ** final POSITION_X **//
            .ease(TweenEquations.easeInOutElastic) //** easing equation **//
            .repeat(10,1000f) //** ten more times **//
            .start(manager3);
        startTime = TimeUtils.millis();
    }
   
   
    @Override
    public void dispose() {
        batch.dispose();
        texture.dispose();
        //font.dispose();
    }

    @Override
    public void render() {       
        Gdx.gl.glClearColor(0, 1, 1, 1);
        Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
        delta = (TimeUtils.millis()-startTime)/1000; // **get time delta **//
        manager1.update(delta); //** update sprite1 **//
        manager2.update(delta); //** update sprite2 **//
        manager3.update(delta); //** update sprite3 **//
        batch.setProjectionMatrix(camera.combined);
        batch.begin();
        batch.draw(ElasticTxt, 150, 0.75f*h+50);
        batch.draw(CircTxt, 150, 0.5f*h+50);
        batch.draw(QuadTxt, 150, 0.25f*h+50);
        sprite1.draw(batch);
        sprite2.draw(batch);
        sprite3.draw(batch);
        batch.end();
    }

    @Override
    public void resize(int width, int height) {
    }

    @Override
    public void pause() {
    }

    @Override
    public void resume() {
    }
}


This is the output at a particular time:



2 comments:

  1. Hi ,
    How can I create the TweenAccessor class .
    thnks for the great tutorial.

    ReplyDelete
  2. First of all thanks for a good tutorial, but it is a bit annoying that the pictures you need to run the code isn't available.
    Regards

    ReplyDelete