猿问

如何从 cachedActions Libgdx 继续序列/并行操作

我有一个 clicklistener 扩展类,旨在缓存 actor 在 touchDown 期间的任何当前动作,并在触发 touchUp 时将其分配回去。但是,它不适用于序列或并行操作。


public class MyClickListener extends ClickListener {


    public Actor actor;

    private final Array<Action> cachedActions = new Array<Action>();


    @Override

    public void touchUp(InputEvent event, float x, float y, int pointer, int button) {

        super.touchUp(event, x, y, pointer, button);

        actor = event.getListenerActor();

        actor.addAction(btnScaleBackActions());

        for(Action action:cachedActions)

        {

            //action.reset(); // i wants the actor to continue at where it stop

            action.setTarget(actor);

            action.setActor(actor);

            actor.addAction(action);

        }

        cachedActions.clear();

    }


    @Override

    public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {

        if(pointer==0)

        {

            actor = event.getListenerActor();

            actor.setScale(0.9f);

            cachedActions.addAll(actor.getActions());

            actor.clearActions();

            return super.touchDown(event, x, y, pointer, button);

        }

        else

        {

            return false;

        }

    }

我的按钮测试:


// button touchUp continue its previous action at where it stop

btn1.addAction(Actions.scaleBy(1,1,3));


// button touchUp not continue it previous actions and complete stop

btn2.addAction(sequence(Actions.scaleBy(1,1,3))); 


// button touchUp give nullException error

btn3.addAction(forever(Actions.scaleBy(1,1,3)));


//error :

Exception in thread "LWJGL Application" java.lang.NullPointerException

        at com.badlogic.gdx.scenes.scene2d.actions.RepeatAction.delegate(RepeatAction.java:29)

        at com.badlogic.gdx.scenes.scene2d.actions.DelegateAction.act(DelegateAction.java:43)

是否可以在 myClickListener 类停止的地方继续序列/并行操作?


函数式编程
浏览 79回答 2
2回答

Qyouu

这是另一个想法。您可以将您的操作包装在一种新型的可暂停操作中,而不是处理删除和恢复操作以及随后处理池问题。public class PausableAction extends DelegateAction {&nbsp; &nbsp; public static PausableAction pausable(Action wrappedAction){&nbsp; &nbsp; &nbsp; &nbsp; PausableAction action = Actions.action(PausableAction.class);&nbsp; &nbsp; &nbsp; &nbsp; action.setAction(wrappedAction);&nbsp; &nbsp; &nbsp; &nbsp; return action;&nbsp; &nbsp; }&nbsp; &nbsp; boolean paused = false;&nbsp; &nbsp; public void pause (){&nbsp; &nbsp; &nbsp; &nbsp; paused = true;&nbsp; &nbsp; }&nbsp; &nbsp; public void unpause (){&nbsp; &nbsp; &nbsp; &nbsp; paused = false;&nbsp; &nbsp; }&nbsp; &nbsp; protected boolean delegate (float delta){&nbsp; &nbsp; &nbsp; &nbsp; if (paused)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return false;&nbsp; &nbsp; &nbsp; &nbsp; return action.act(delta);&nbsp; &nbsp; }&nbsp; &nbsp; public void restart () {&nbsp; &nbsp; &nbsp; &nbsp; super.restart();&nbsp; &nbsp; &nbsp; &nbsp; paused = false;&nbsp; &nbsp; }}现在,在获取您的操作时,将它们包装在一个可暂停的对象中,例如:btn1.addAction(PausableAction.pausable(Actions.scaleBy(1,1,3)));并在需要时暂停/取消暂停操作,例如://...actor = event.getListenerActor();actor.setScale(0.9f);for (Action action : actor.getActions())&nbsp; &nbsp; if (action instanceof PausableAction)&nbsp; &nbsp; &nbsp; &nbsp; ((PausableAction)action).pause();return super.touchDown(event, x, y, pointer, button);

三国纷争

来自池(比如来自 Actions 类)的动作的默认行为是当它们从 actor 中移除时重新启动它们自己。重用这些实例实际上并不安全,因为它们也已返回到池中并且可能意外地附加到其他一些参与者。因此,在将它们从 actor 中移除之前,您需要将它们的池设置为 null。private static void clearPools (Array<Action> actions){&nbsp; &nbsp; for (Action action : actions){&nbsp; &nbsp; &nbsp; &nbsp; action.setPool(null);&nbsp; &nbsp; &nbsp; &nbsp; if (action instanceof ParallelAction) //SequenceActions are also ParallelActions&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; clearPools(((ParallelAction)action).getActions());&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; else if (action instanceof DelegateAction)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ((DelegateAction)action).getAction().setPool(null);&nbsp; &nbsp; }}//And right before actor.clearActions();clearPools(actor.getActions());然后,当您将它们添加回 actor 时,您需要将它们的池添加回来,以便它们可以返回到 Actions 池并在以后重用以避免 GC 搅动。private static void assignPools (Array<Action> actions){&nbsp; &nbsp; for (Action action : actions){&nbsp; &nbsp; &nbsp; &nbsp; action.setPool(Pools.get(action.getClass()));&nbsp; &nbsp; &nbsp; &nbsp; if (action instanceof ParallelAction)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; assignPools(((ParallelAction)action).getActions());&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; else if (action instanceof DelegateAction){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Action innerAction = ((DelegateAction)action).getAction();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; innerAction.setPool(Pools.get(innerAction.getClass()));&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}//And call it on your actor right after adding the actions back:assignPools(actor.getActions);
随时随地看视频慕课网APP

相关分类

Java
我要回答