在LibGDX中逐个像素地绘制形状

时间:2017-11-17 16:14:51

标签: java android libgdx

我正在尝试制作带有两个形状的三角形和圆形的介绍屏幕,它们看起来如下图。

enter image description here

我想要做的是在2秒的范围内从一个点到另一个点逐个像素地绘制这些形状,使其看起来像动画。 我尝试使用ShapeRenderer,但它只是简单地将形状放在一起。我该如何设置动画?

1 个答案:

答案 0 :(得分:3)

您可以创建一个镜像动作类的类。 Actions类用于制作动画,它需要一个actor才能运行。我设置了一个空的演员,它有点hacky但它​​的工作原理。当动画完成动画时,它会从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 );
        }
    }
}