您的位置:首页 > 其它

让程序活起来:用Universal Tween Engine创建动画

2014-08-01 09:18 351 查看

1.简介

在实现动画的时候,任何动画要表现运动或变化,至少前后要给出两个不同的关键状态,而中间状态的变化和衔接电脑可以自动完成,表示关键状态的帧叫做关键帧Universal TweenEngine是一个可以用来创建动画效果的动画库,从本质上来说是一个插值运算的引擎,可以在任何给定的值之间(类似关键帧)与规定时间内进行插值运算,并最终形成动画。Tween Engine还包含了其它的很多内容,包括插值的生命周期管理和更新控制,它是用java语言实现的库,所以它可以对任何java对象的任何属性进行计算,可以应用于Swing,OpenGL或Android程序。

通过Universal Tween Engine可以创建平滑的动画效果,比如循环,移动,旋转等。这些过程可以是加速移动,也可以是减速移动,这些不同的缓动方式就是Tween的各种ease。

Universal TweenEngine的网址是https://code.google.com/p/java-universal-tween-engine/,可以从上面获取库以及源代码。

2.简易教程

通过引擎来创建动画一般有下面4个主要的步骤:

1. 为想要实现动画的对象实现TweenAccessor接口,并且向引擎注册接口的实现;

2. 创建一个TweenManager来管理所有的tween,tween表示一个动画过程,TweenManager负责这些维护这些tween的生命周期、更新和时间线;

3. 利用Tween.to(), Tween.from() 或 Tween.set() 方法来创建一些tween并将其加入到manager中;

4. 循环调用manager的update(delta)方法来实现播放动画;

2.1实现TweenAccessor

在这里实现一个例子,先对想要动画化的对象实现该接口,比如想要移动一个组件,那么可对Component实现该接口

public
class ComponentAccessor implements TweenAccessor<Component>
{

public
static final
int X =
1;
public
static final
int Y =
2;
public
static final
int XY =
3;
public
static final
int W =
4;
public
static final
int H =
5;
public
static final
int WH =
6;
public
static final
int XYWH =
7;
@Override
public
int getValues(Component target,
int tweenType,
float[] returnValues)
{

/**
*对对象的不同属性提供设置值和获取值的方法
*target是要改变属性的对象
*tweenType自己定义的是改变属性的类型
*returnValues是属性值的数组,返回值是这个数组的长度
*/
switch
(
tweenType)
{

case X:
returnValues[0]
=
target.getX();
return
1;
case Y:
returnValues[0]
=
target.getY();
return
1;
case XY:
returnValues[0]
=
target.getX();
returnValues[1]
=
target.getY();
return
2;
case W:
returnValues[0]
=
target.getWidth();
return
1;
case H:
returnValues[0]
=
target.getHeight();
return
1;
case WH:
returnValues[0]
=
target.getWidth();
returnValues[1]
=
target.getHeight();
return
2;
case XYWH:
returnValues[0]
=
target.getX();
returnValues[1]
=
target.getY();
returnValues[2]
=
target.getWidth();
returnValues[3]
=
target.getHeight();
return
4;
default:
return -
1;
}
}

@Override
public
void setValues(Component target,
int tweenType,
float[] newValues)
{

switch
(
tweenType)
{

case X:
target.setLocation(Math.round(newValues[0]),
target.getY());
break;
case Y:
target.setLocation(target.getX(),
Math.round(newValues[0]));
break;
case XY:
target.setLocation(Math.round(newValues[0]),
Math.round(newValues[1]));
break;
case W:
target.setSize(Math.round(newValues[0]),
target.getHeight());
target.validate();
break;
case H:
target.setSize(target.getWidth(),
Math.round(newValues[0]));
target.validate();
break;
case WH:
target.setSize(Math.round(newValues[0]),
Math.round(newValues[1]));
target.validate();
break;
case XYWH:
target.setBounds(Math.round(newValues[0]),
Math.round(newValues[1]),
Math.round(newValues[2]),
Math.round(newValues[3]));
target.validate();
break;
}
}
}
}

向引擎注册该对象的实现,让引擎知道这个对象:

/**
* 向引擎注册该对象的实现
*/
Tween.registerAccessor(JComponent.class,
new
ComponentAccessor());

2.2 创建一个TweenManager来管理Tween

TweenManger manager =
new
TweenManager();

2.3 创建Tween

/**
* 将一个Button对象在0.5秒钟的时间内移动到(100,100)的位置
*/
JButton btn =
new
JButton();
Tween.to(btn, ComponentAccessor.XY,
0.5f).target(100,
100).start(manager);

2.4 调用manager.update(delta)

定时循环地调用update方法来实现动画,在Swing中通常使用一个单独的线程

running =
true;


Runnable runnable =
new
Runnable()
{

public
void run()
{

long lastMillis
=
System.currentTimeMillis();
long deltaLastMillis
=
System.currentTimeMillis();

while
(
running)
{

long newMillis
=
System.currentTimeMillis();
long sleep =
15 -
(
newMillis - lastMillis);
lastMillis = newMillis;

if
(
sleep >
1){
try
{

Thread.sleep(sleep);
}
catch
(
InterruptedException ex)
{

}
}

long deltaNewMillis
=
System.currentTimeMillis();
final
float delta =
(
deltaNewMillis - deltaLastMillis)
/
1000f;

try
{

SwingUtilities.invokeAndWait(new Runnable()
{

public
void run()
{

manager.update(delta);
}});
}
catch (
InterruptedException ex)
{

}
catch (
InvocationTargetException ex)
{

}

deltaLastMillis = newMillis;
}
}};

new Thread(runnable).start();

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: