Search code examples
androidanimationlibgdx

Removing animation logic from Render method in Libgdx


I want to delegate animations to a different class/entity so that render method is not bloated with code needed for animations. If the animation going on render method should execute that and move to its normal processing when the animation is done. Animation should except required sprites that involved in the animation. render method should render other sprites in normal way. (I am talking about animations of several sprites not sprite animations off of sprite sheet)

Is there a object oriented way to achieve this?

@Override
public void render ()
{

    long ctime = System.currentTimeMillis();
    Gdx.gl.glClearColor(backColor.r, backColor.g, backColor.b, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    float deltaTime = Gdx.graphics.getDeltaTime();
    if(!startGame)
        return;

    if(camera != null)
        batch.setProjectionMatrix(camera.combined);

batch.begin();
        for (int i = 0; i < clusterList.size(); i++) {
            clusterList.get(i).render(batch);

batch.end();
        if(!isFinished)
            scoreBar.setDeltaTime(deltaTime);

        Gdx.gl.glEnable(GL20.GL_BLEND);
        Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
        shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
        shapeRenderer.setProjectionMatrix(batch.getProjectionMatrix());
        shapeRenderer.setColor(Color.GRAY.r,Color.GRAY.g, Color.GRAY.b, 0.6f);
        shapeRenderer.rect(0, camH - barHeight, camW, barHeight);
        shapeRenderer.end();
        Gdx.gl.glDisable(GL20.GL_BLEND);

        batch.begin();
        scoreBar.render(batch);


        if (animateSpread) {
            timeLoopSpread += deltaTime;
            if (timeLoopSpread > duration) {
                timeLoopSpread = 0;
                animateSpread = false;
            } else
                animateCluster();
        }


}

private void animateCluster() {
        float factor = Interpolation.pow5Out.apply(timeLoopSpread /duration);
        for (int index =0; index < clusterList.size(); index++) {
            Cluster tempC = clusterList.get(index);
            currentPos.set(tempC.endPos);
            currentPos.sub(tempC.startPos);
            currentPos.scl(factor);
            currentPos.add(tempC.startPos);
            tempC.setCenterPosition(currentPos);
        }
    }

Solution

  • Object oriented way to do this is to make the clusters animate themselves. Instead of calling AnimateClusters() you would enable/disable them animating. Wherever you enable animateSpread you would call something like

    for (int i = 0; i < clusterList.size(); i++) {
        clusterList.get(i).spreadStart();
    }
    

    Then update each cluster in render(), each cluster would keep its own animation time.

    for (int i = 0; i < clusterList.size(); i++) {
        // update animation in there
        clusterList.get(i).update(delta);
    }
    

    You could also stop the animation in the same way as it was started.