简体   繁体   中英

Draw shape pixel by pixel in LibGDX

I'm trying to make intro screen with two shaped Triangle and Circle which would look as following image.

在此处输入图片说明

What I want to do is that draw these shape pixel by pixel from one point to last in span of 2 seconds so that it appears like animation. I tried using ShapeRenderer but it just simply put the shape in one go. How do I animate it?

You could make a class that mirrors the action class. The Actions class is for making an animation and it requires an actor to function. I set it with an empty actor, its kinda hacky but it works. When the action is done with animating it removes ifself from the SequenceAction and stops rendering. In your custom action class you'll when need to set it to active and keep rendering when it finishes the animation.

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.

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 );
    }
}

Its easier to control a circle with vectors than to use the arc draw method. To change the segments of the circle change the length argument.

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 );
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM