为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

函数式编程 2022-12-28 11:08:01
我有一个 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 stopbtn1.addAction(Actions.scaleBy(1,1,3));// button touchUp not continue it previous actions and complete stopbtn2.addAction(sequence(Actions.scaleBy(1,1,3))); // button touchUp give nullException errorbtn3.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 类停止的地方继续序列/并行操作?
查看完整描述

2 回答

?
Qyouu

TA贡献1786条经验 获得超11个赞

这是另一个想法。您可以将您的操作包装在一种新型的可暂停操作中,而不是处理删除和恢复操作以及随后处理池问题。


public class PausableAction extends DelegateAction {


    public static PausableAction pausable(Action wrappedAction){

        PausableAction action = Actions.action(PausableAction.class);

        action.setAction(wrappedAction);

        return action;

    }


    boolean paused = false;


    public void pause (){

        paused = true;

    }


    public void unpause (){

        paused = false;

    }


    protected boolean delegate (float delta){

        if (paused)

            return false;

        return action.act(delta);

    }


    public void restart () {

        super.restart();

        paused = false;

    }

}

现在,在获取您的操作时,将它们包装在一个可暂停的对象中,例如:


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

并在需要时暂停/取消暂停操作,例如:


//...

actor = event.getListenerActor();

actor.setScale(0.9f);

for (Action action : actor.getActions())

    if (action instanceof PausableAction)

        ((PausableAction)action).pause();

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


查看完整回答
反对 回复 2022-12-28
?
三国纷争

TA贡献1804条经验 获得超7个赞

来自池(比如来自 Actions 类)的动作的默认行为是当它们从 actor 中移除时重新启动它们自己。重用这些实例实际上并不安全,因为它们也已返回到池中并且可能意外地附加到其他一些参与者。


因此,在将它们从 actor 中移除之前,您需要将它们的池设置为 null。


private static void clearPools (Array<Action> actions){

    for (Action action : actions){

        action.setPool(null);

        if (action instanceof ParallelAction) //SequenceActions are also ParallelActions

            clearPools(((ParallelAction)action).getActions()); 

        else if (action instanceof DelegateAction)

            ((DelegateAction)action).getAction().setPool(null);

    }

}


//And right before actor.clearActions();

clearPools(actor.getActions());

然后,当您将它们添加回 actor 时,您需要将它们的池添加回来,以便它们可以返回到 Actions 池并在以后重用以避免 GC 搅动。


private static void assignPools (Array<Action> actions){

    for (Action action : actions){

        action.setPool(Pools.get(action.getClass()));

        if (action instanceof ParallelAction)

            assignPools(((ParallelAction)action).getActions()); 

        else if (action instanceof DelegateAction){

            Action innerAction = ((DelegateAction)action).getAction();

            innerAction.setPool(Pools.get(innerAction.getClass()));

        }

    }

}


//And call it on your actor right after adding the actions back:

assignPools(actor.getActions);


查看完整回答
反对 回复 2022-12-28
  • 2 回答
  • 0 关注
  • 65 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信