over 4 years ago

java-universal-tween-engineは何らかのオブジェクトに変化を与えるJavaライブラリです。具体的には、オブジェクトが X, Y座標の位置を意味する情報を持っていた時、それらにアクセスして変化を与えることができます。ゲーム上に表示する物体にダイナミックな変化を与えたいならこのライブラリが便利です。

java-universal-tween-engine

このライブラリはJavaのライブラリなので、名前通りAndroidでも利用できますし、何らかのグラフィックス描画機能と一緒に利用できるはずです。

このライブラリを使うにはTweenAccessorを実装する必要があります。このクラスは、変化を与える対象のオブジェクトのアクセス機構になります。これが無いと変化を与えられません。

TweenAccessorを用意できたら、Tween.registerAccessorでTweenAccessorの登録を行います。これでTweenクラスのメソッドを通じて変化内容を記述できます。

Tween.to(particle1, ParticleAccessor.POSITION_XY, 1.0f).target(500, 500).ease(Bounce.OUT)

particle1は、変化対象のオブジェクトのインスタンスです。ParticleAccessor.POSITION_XYはTweenAccessorの実装で定義した変化させたいパラメータです。1.0fは持続時間です。もっと大きな時間を設定するとそれだけ長く変化を与える時間が増加することになります。ただし、targetに達するまで時間がかかります。targetは変化完了後の値です。toメソッドは0からtargetの値へ変化させることを意味します。easeは加速/減速効果を与えます。Bounceの他にも色々あります。


package com.example.tweendemo;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.view.View;
import aurelienribon.tweenengine.Timeline;
import aurelienribon.tweenengine.Tween;
import aurelienribon.tweenengine.TweenManager;
import aurelienribon.tweenengine.equations.Bounce;
import aurelienribon.tweenengine.equations.Expo;
import aurelienribon.tweenengine.equations.Quart;

public class TweenView extends View {
    private TweenManager tweenManager;
    private final long startTime = System.currentTimeMillis();
    private long privTime = System.currentTimeMillis();
    private Particle particle1 = new Particle();
    private Particle particle2 = new Particle();
    private Particle particle3 = new Particle();
    private Matrix matrix = new Matrix();
    private Paint paint = new Paint();
    private float delta = 0.0f;
    
    public TweenView(Context context, Bitmap bitmap) {
        super(context);
        Tween.registerAccessor(Particle.class, new ParticleAccessor());
        tweenManager = new TweenManager();
        particle1.setBitmap(bitmap);
        particle2.setBitmap(bitmap);
        particle3.setBitmap(bitmap);
        Timeline.createSequence()
                .beginParallel()
                .push(Tween.to(particle1, ParticleAccessor.POSITION_XY, 1.0f).target(500, 500).ease(Bounce.OUT))
                .push(Tween.to(particle2, ParticleAccessor.POSITION_Y, 1.0f).target(500,0).ease(Quart.OUT))
                .push(Tween.to(particle3, ParticleAccessor.POSITION_X, 1.0f).target(500,0).ease(Expo.INOUT))
                .end()
                .repeat(10, 2.0f).start(tweenManager);
    }
    
    @Override
    protected void onDraw(Canvas canvas) {
        if ((startTime + 2000) < System.currentTimeMillis()) {
            tweenManager.update(delta);
        }
        
        matrix.setTranslate(particle1.getX(), particle1.getY());
        canvas.drawBitmap(particle1.getBitmap(), matrix, paint);
        
        matrix.setTranslate(particle2.getX(), particle2.getY());
        canvas.drawBitmap(particle2.getBitmap(), matrix, paint);
        
        matrix.setTranslate(particle3.getX(), particle3.getY());
        canvas.drawBitmap(particle3.getBitmap(), matrix, paint);
        
        delta = (float) ((System.currentTimeMillis() - privTime) / 1000.0);
        privTime = System.currentTimeMillis();

        invalidate();
    }
}
package com.example.tweendemo;

import aurelienribon.tweenengine.TweenAccessor;

public class ParticleAccessor implements TweenAccessor<Particle> {

    public static final int POSITION_X = 1;
    public static final int POSITION_Y = 2;
    public static final int POSITION_XY = 3;

    @Override
    public int getValues(Particle target, int tweenType, float[] returnValues) {
        switch (tweenType) {
            case POSITION_X: returnValues[0] = target.getX(); return 1;
            case POSITION_Y: returnValues[0] = target.getY(); return 1;
            case POSITION_XY:
                returnValues[0] = target.getX();
                returnValues[1] = target.getY();
                return 2;

            default: assert false; return -1;
        }
    }

    @Override
    public void setValues(Particle target, int tweenType, float[] newValues) {
        switch (tweenType) {
            case POSITION_X: target.setX(newValues[0]); break;
            case POSITION_Y: target.setY(newValues[0]); break;
            case POSITION_XY:
                target.setX(newValues[0]);
                target.setY(newValues[1]);
                break;
            default: assert false; break;
        }
    }
}
package com.example.tweendemo;

import android.graphics.Bitmap;

public class Particle {

    private float x, y;
    private Bitmap bitmap;

    public float getX() {
        return x;
    }

    public void setX(float x) {
        this.x = x;
    }

    public float getY() {
        return y;
    }

    public void setY(float y) {
        this.y = y;
    }

    public Bitmap getBitmap() {
        return bitmap;
    }

    public void setBitmap(Bitmap bitmap) {
        this.bitmap = bitmap;
    }

}
package com.example.tweendemo;

import android.os.Bundle;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
        TweenView tweenView = new TweenView(getApplicationContext(), bitmap);
        setContentView(tweenView);
    }

}
← OrmLite - SQLiteに関する処理を簡潔にする Simple - オブジェクトをXMLファイルに保存、復元する →