在Scene2d中,当一个Action完成后,它将从Actor中移除,但它不会被放回到Pool中。
Action.class
/** 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;
}
}
似乎Action reset()方法(这是发送到Pool的唯一地方)(1)当Actor的actions数组被清除时,它永远不会被调用,并且随后对池的备份没有发生......
(1) - 在以前的版本中,我们可以覆盖finish()方法并将Action发送到池中,但是它不再可用的方法......
当我尝试将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;
}
}
的原创想法
我注意到每次添加一个Action时,它都会创建一个新对象(TimelineAction action = new TimelineAction()
)而不是返回一个池。
然后我尝试通过覆盖他的reset()
方法来追踪Action结尾,以确定它是否被调用过......但事实并非如此。
@Override
public void reset () {
Gdx.app.log("LOG", "reset()");
super.reset();
}
顺便说一句,在TimelineAction完成后,时间轴和它的Tweens对象被成功发送到各个池:(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)
答案 0 :(得分:0)
你还有问题吗?我是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,以确保在已标记为要删除的Actor的所有相关操作上调用“finish”方法。如果一个动作在演员被标记为删除之前终止,那么它的'done'标志将被设置,演员的'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。