【发布时间】:2017-11-19 05:05:04
【问题描述】:
我正在尝试用两个形状的三角形和圆形制作介绍屏幕,如下图所示。
我想做的是在 2 秒内从一个点到最后一个像素逐个像素地绘制这些形状,使其看起来像动画。
我尝试使用ShapeRenderer,但它只是简单地将形状放在一起。如何制作动画?
【问题讨论】:
我正在尝试用两个形状的三角形和圆形制作介绍屏幕,如下图所示。
我想做的是在 2 秒内从一个点到最后一个像素逐个像素地绘制这些形状,使其看起来像动画。
我尝试使用ShapeRenderer,但它只是简单地将形状放在一起。如何制作动画?
【问题讨论】:
您可以创建一个反映动作类的类。 Actions 类用于制作动画,它需要演员才能发挥作用。我用一个空的演员设置它,它有点老套,但它有效。当动作完成动画时,它会从 SequenceAction 中删除 ifself 并停止渲染。在您的自定义动作类中,您需要将其设置为活动并在它完成动画时继续渲染。
private ShapeRenderer renderer;
private SequenceAction action;
@Override
public void create() {
Vector2 center = new Vector2( 0.5f * Gdx.graphics.getWidth(), 0.5f * Gdx.graphics.getHeight() );
renderer = new ShapeRenderer();
action = Actions.sequence(
new LineAction( 0.5f, new Vector2( 0, 0 ).add( center ), new Vector2( -20, 40 ).add( center ), 1, renderer ),
new LineAction( 0.5f, new Vector2( -20, 40 ).add( center ), new Vector2( -40, 0 ).add( center ), 1, renderer ),
new LineAction( 0.5f, new Vector2( -40, 0 ).add( center ), new Vector2( 20, 0 ).add( center ), 1, renderer ),
new CirleAction( 0.5f, center, 30, 20, 0, -315, 1, renderer )
);
action.setActor( new Actor() );
}
@Override
public void render() {
Gdx.gl.glClearColor( 0, 0, 0, 1 );
Gdx.gl.glClear( GL20.GL_COLOR_BUFFER_BIT );
renderer.begin( ShapeRenderer.ShapeType.Line );
action.act( Gdx.graphics.getDeltaTime() );
renderer.end();
}
LineAction 类。
class LineAction extends TemporalAction {
private Vector2 pointA = new Vector2(), pointB = new Vector2(), tmp = new Vector2();
private float lineWidth;
private ShapeRenderer renderer;
public LineAction( float duration, Vector2 pointA, Vector2 pointB, float lineWidth, ShapeRenderer renderer ){
super( duration );
this.pointA.set( pointA );
this.pointB.set( pointB );
this.lineWidth = lineWidth;
this.renderer = renderer;
this.actor = new Actor();
}
@Override
protected void update( float percent ) {
Vector2 point = tmp
.set( pointB )
.sub( pointA )
.scl( percent )
.add( pointA );
renderer.rectLine( pointA, point, lineWidth );
}
}
用矢量控制圆比使用圆弧绘制方法更容易。要更改圆的分段,请更改长度参数。
class CircleAction extends TemporalAction {
private Vector2[] points;
private float lineWidth;
private ShapeRenderer renderer;
public CirleAction( float duration, Vector2 offset, int length, float radius, float startAngle, float endAngle, float lineWidth, ShapeRenderer renderer ){
super( duration );
this.points = new Vector2[ length ];
this.lineWidth = lineWidth;
this.renderer = renderer;
this.actor = new Actor();
float degrees = (endAngle - startAngle) / (float) length;
for ( int i = 0; i < length; ++i ){
points[ i ] = new Vector2( radius, 0 ).rotate( degrees * i ).add( offset );
}
}
@Override
protected void update( float percent ) {
for ( int i = 0, l = MathUtils.floor( (points.length - 1) * percent ); i < l; ++i ) {
renderer.rectLine( points[ i ], points[ i + 1 ], lineWidth );
}
}
}
【讨论】: