2

Scene2d では、アクションが完了すると、アクタから削除されますが、プールには戻されません。

アクション.クラス

/** Sets the actor this action will be used for. This is called automatically when an action is added to an actor. This is also
     * called with null when an action is removed from an actor. When set to null, {@link #reset()} is called.
     * <p>
     * This method is not typically a good place for a subclass to query the actor's state because the action may not be executed
     * for some time, eg it may be {@link DelayAction delayed}. The actor's state is best queried in the first call to
     * {@link #act(float)}. For a TimedAction, use TimedAction#initialize(). */
    public void setActor (Actor actor) {
        this.actor = actor;

    }

    /** Resets the optional state of this action to as if it were newly created, allowing the action to be pooled and reused. State
     * required to be set for every usage of this action or computed during the action does not need to be reset.
     * <p>
     * The default implementation calls {@link #restart()}. Also, if the action has a {@link #setPool(Pool) pool} then the action is
     * {@link Pool#free(Object) returned} to the pool.
     * <p>
     * If a subclass has optional state, it must override this method, call super, and reset the optional state. */
    public void reset () {
        restart();
        if (pool != null) {
            pool.free(this);
            pool = null;
        }
    }

アクションの reset() メソッド (プールへの送信が行われる唯一の場所)(1) は、アクタのアクション配列がクリアされたときに呼び出されず、その後プールへのバックアップが行われないようです。 ..

(1) - 以前のバージョンでは、finish() メソッドをオーバーライドしてアクションをプールに送信できましたが、そのメソッドはもう使用できません...

Action クラスをこれに拡張しようとしたときに、この問題が発生しました。

TimelineAction.class

/**
 * Timeline action runs a Timeline (separate from the TweenManager to avoid a second manager/loop cycle)
 * with Scene2d
 */
public class TimelineAction extends Action {

    private static final Pool<TimelineAction> pool = new Pool<TimelineAction>() {

        @Override
        protected TimelineAction newObject() {

            Gdx.app.log("LOG", "TimelineAction action = new TimelineAction();");        
            TimelineAction action = new TimelineAction(); 

            return action;
        }

    };  

    private Timeline timeline;
    private boolean done;

    /**
     * Get instance from pool.
     * 
     * @param timeline
     *            The associated tween.
     * 
     * @return Pooled instance.
     */
    public static TimelineAction createTimelineAction(Timeline _timeline)   {

        TimelineAction action = pool.obtain();

        action.setPool(pool);

        action.setTimeline(_timeline);      

        return action;
    }

    @Override
    public boolean act(float delta) {

        done = timeline.isFinished(); 
        if (!done) {
            timeline.update(delta);
        } else {
            Gdx.app.log("LOG", "timeline.finished()");          
            timeline.free();
            timeline = null;                            
        }
        return done;
    }

    private void setTimeline(Timeline timeline) {

        this.timeline = timeline;
    }

}

からのオリジナルアイデアnetthreads

アクションが追加されるたびにTimelineAction action = new TimelineAction()、プールされたオブジェクトを返すのではなく、新しい object( ) が作成されることに気付きました。それから、彼のメソッドをオーバーライドして、Action のエンディングを追跡しreset()て、それが呼び出されたかどうかを調べようとしましたが、そうではありませんでした。

@Override
public void reset () {

    Gdx.app.log("LOG", "reset()");
    super.reset();
}

ところで、タイムラインとその Tweens オブジェクトは、TimelineAction が完了した後、それぞれのプールに正常に送信されます (2):

(2) - Timeline.getPoolSize() は 1 を返し、Tween.getPoolSize() は 2 を返します。

actor1.addAction(TimelineAction.createTimelineAction(
            Timeline.createSequence()
                    .push( Tween.to(logo_MUTANT, Element2DAccessor.POS_XY, 3f)
                            .waypoint(400, 800)
                            .waypoint(200, 400)
                            .waypoint(100, 200)
                            .target(0,0)
                         )
                    .ease(Quad.INOUT).path(TweenPaths.catmullRom)).push(Tween.call(callback).setCallbackTriggers(TweenCallback.BACK_COMPLETE)).repeatYoyo(1, 0.5f).start()));

だから、ここで助けが必要です、お願いします!:S

よろしくお願いします。下手な英語をお許しください。;)

libgdx バージョン 0.9.6 (24-07-2012)

4

1 に答える 1

1

まだ問題がありますか。私はTimelineActionのnetthreadsバージョンの作成者であり、このバージョンを使用している限り、問題が発生することはないと思います。

    public class TimelineAction extends Action
    {
        private static final ActionResetingPool<TimelineAction> pool = new ActionResetingPool<TimelineAction>(10, 100)
        {
            @Override
            protected TimelineAction newObject()
            {
                TimelineAction action = new TimelineAction();

                return action;
            }
        };

        private Timeline timeline;
        private Actor target;
        protected boolean done;

        /**
         * Get instance from pool.
         * 
         * @param timeline
         *            The action time-line to execute.
         * 
         * @return Pooled instance.
         */
        public static TimelineAction $(Timeline timeline)
        {
            TimelineAction action = pool.obtain();

            action.setTimeline(timeline);

            return action;
        }

        @Override
        public void act(float delta)
        {
            if (!isDone())
            {
                timeline.update((int) (delta * 1000));
            }
            else
            {
                Gdx.app.log("TimelineAction", "!!!Executing finished timeline, " + timeline.getClass().hashCode());
            }

        }

        @Override
        public boolean isDone()
        {
            return timeline.isFinished();
        }

        @Override
        public Action copy()
        {
            return this;
        }

        @Override
        public void setTarget(Actor actor)
        {
            this.target = actor;
        }

        @Override
        public Actor getTarget()
        {
            return target;
        }

        @Override
        public void finish()
        {
            super.finish();

            pool.free(this);

            timeline.free();
        }

        private void setTimeline(Timeline timeline)
        {
            this.timeline = timeline;
        }

        /**
         * Fetch TimeLine reference.
         * 
         * @return The TimeLine reference.
         */
        public Timeline getTimeline()
        {
            return timeline;
        }

        /**
         * Set done status.
         * 
         * @param done
         */
        public void setDone(boolean done)
        {
            this.done = done;
        }

}

0.9.6バージョンのLibGDXは、削除のマークが付けられたアクターの関連するすべてのアクションで「finish」メソッドが呼び出されるように変更されました。アクターが削除のマークを付ける前にアクションが終了すると、その「完了」フラグが設定され、アクターの「act」メソッドが「finish」を呼び出します。

public void act (float delta) {
        actions.iter();
        Action action;

        while ((action = actions.next()) != null) {
            action.act(delta);
            if (action.isDone()) {
                action.finish();
                actions.remove();
            }
        }
    }

現在、すべてのデモを0.9.6に更新しています。

于 2012-09-01T17:36:22.520 に答える