Accurately tracking target location (shadows)

I’d like to update my shadow locations to accurate place them under their parent objects. I’m doing this by creating the parent object and another similar object which sits in a lower group. An enterFrame listener then updates the shadows with the parent (the target ‘object’) location plus offset. The issue is that, due to the test code using transition.to there is a slight lag when using enterFrame to update the shadows.

https://gist.github.com/HoraceBury/dd5e163a61458a1bcdbc36921cdf5bde

Any thoughts on how to keep pace with the transition?

#mighthavebeenawaytoolong

I’ve never been able to solve that.  i.e. Getting enterFrame to move object B to nicely track object A which is being moved by transition.*

I would really love to hear and see a working solution.

The only advice I can give is to apply equal transitions to A and B.

Put them in a group and transition the group instead?

I would, but I need the shadows all to be below all objects, which requires being in a different group. Also, even if they were in the same group, if the target object were a physics body there will still be a lag.

I’ve considered having *everything* represented by an enterFrame - but this would require having anything being implicitly moved as duplicated by an object controlled by an enterFrame, which would be wildly inefficient.

If you want a shadow to follow an object then how about storing a reference to the object being followed.  Then your shadow manager class simply needs to walk all objects and update their respective x,y - based on the references - in a single enterFrame()?

Then you only need transition the object and its shadow will automatically snap to the correct location.  Simply updating x,y for lots of objects is relatively low cost as the tweening is only done once by the object (being followed).

I do something similar in my space invaders mini game where a homing missile stores an internal reference to its target so it can react and update its path in real time.

Yep, that’s what I’m doing.

the problem isn’t how the “child” object is referenced by the “parent”, but in expecting a certain order of operations between transitions and frame listeners.  in particular, for this use you’d need transitions to be processed first, THEN enterFrame.  unfortunately, as you can discover for yourself by trial and error*, that is not the case, so your “follow” logic in enterFrame will always lag the transition’s movement by one frame.

*rant:  because Corona themselves refuses to properly document their internal frame update sequence.  this drove me CRAZY when I first started using Corona, and I couldn’t believe something so fundamental to properly using an SDK would be left so obscure.  it’s apparently intentional, as if they consider it some super-important trade secret, as if no-one else had EVER written a game-update loop before, geesh!  fe, see the tone of last response in this old thread:  https://forums.coronalabs.com/topic/17363-corona-app-execution-loop/ 

Slightly old post @dave but the response was very “we are mightier than you” and an issue I have had with certain Corona core devs for a while - I’m sure my vocal spats are well documented!

Personally, I use the track parent enterFrame() solution a lot and it works just fine for me… I use it in my main game to ensure shadows of floating objects track the parent - for example shadows cast by flying objects.  but saying that, this is only on a few animations and not core to my game.

If you are hitting a timing issue then simply defer your shadow processing 1 frame with

timer.performWithDelay(1, processShadows)

It’s a bit too hacky for my liking but may work for your implementation.

@sgs - exactly on point, particularly wrt “It’s a bit too hacky for my liking but may work for your implementation.” yet that type of code shows up all the time in this forum, precisely because timer/transition/enterframe have undocumented execution order.  (though it’s usually presented as “just do it, it might work” rather than knowing what the underlying cause is)

(aside:  I too use a single enterFrame for just about everything.  sure, if i’m feeling lazy i’d use a transition for purely visual effects, like an alpha fade, but NEVER EVER for game logic.  internally, under the hood, Corona’s timers and transitions are processed as frame-based events anyway, they’re merely convenience wrappers, and you can write your own if you wish, if you need a documented order of execution)

  @horacebury - a general solution would be to wrap both objects in a proxy and execute the transition on THAT instead.  then, within the proxy you could manually (and synchronously) adjust the positions of BOTH objects.

  Lerg, StarCrunch, myself (and probably others) have all posted proxy samples here in the forum if you search.  or, if you’d post a minimal self-contained demo (so that i wouldn’t have to rewrite your base code - just a couple of rects, one on a transition, one on an enterframe, would suffice) I could show how to restructure it as a proxy.

I could, but that would not solve the problem for, eg, physics objects. 

I’m not too worried about matching animations which I directly control - the timer hack above has pretty much solved the original question.

The link in my first post is very easily modified to provide only one example object:

https://gist.github.com/HoraceBury/dd5e163a61458a1bcdbc36921cdf5bde

I’m familiar with animating a proxy object with a transition and then using enterFrame to update representatives of both the target and shadow (to use the earlier terms.) I could even do that with physics objects.

I guess, now the original question has been solved (though as pointed out above, with a hack) the question is how to solve it elegantly.

physics shouldn’t be a problem as the physics update DOES occur before all frame-based updates (enterFrame, timer, transition) so your original enterFrame listener approach on the shadow should properly follow a target moved by physics during a synchronous frame.

(aside re “proxy” - we’re probably using the term differently, as the type of transition proxy I was thinking of wouldn’t require an enterFrame listener at all.  however, it’s probably a moot point if the scope of your problem is wider than conveyed, ie want ONE solution for ANY potential mechanism that moves the target.)

>> the question is how to solve it elegantly.

it has previously been requested that transition support something equivalent to an “onUpdated” event, essentially a per-frame callback that occurs just AFTER the interpolated value has been applied for that frame.  IFF that existed, you could tie into it (you might potentially end up doing double work: once if shadow still updates on enterFrame too early before target transitions, then again after target transitions and onUpdated callback occurs; but at least it’d occur during the correct frame)

I think an onUpdated or preEnterFrame event for the transition library would be fantastic.

I think an option to bounce transitions would be great, too - ie: once the transition completes rather than repeating it can be set to do the same but in reverse. For example, making an object slide left to right requires two transitions, but could easily be handled with a single ‘bouncing’ transition. I’m guessing that this is common enough for it to warrant at least consideration.

if we’re considering wish-list features, then perhaps even better (as in:  more general purpose) would be if Runtime supported an exit Frame event.  That is, an event that is guaranteed to occur last , rather than first, after timer/transition/etc, the final processing that could occur just prior to rendering.*  such an event would in theory be exactly what your shadow/follower code needs for a single solution.

(*same rant:  seems unlikely to occur though, as it would imply a need to document the frame execution order)

I’ve never been able to solve that.  i.e. Getting enterFrame to move object B to nicely track object A which is being moved by transition.*

I would really love to hear and see a working solution.

The only advice I can give is to apply equal transitions to A and B.

Put them in a group and transition the group instead?

I would, but I need the shadows all to be below all objects, which requires being in a different group. Also, even if they were in the same group, if the target object were a physics body there will still be a lag.

I’ve considered having *everything* represented by an enterFrame - but this would require having anything being implicitly moved as duplicated by an object controlled by an enterFrame, which would be wildly inefficient.

If you want a shadow to follow an object then how about storing a reference to the object being followed.  Then your shadow manager class simply needs to walk all objects and update their respective x,y - based on the references - in a single enterFrame()?

Then you only need transition the object and its shadow will automatically snap to the correct location.  Simply updating x,y for lots of objects is relatively low cost as the tweening is only done once by the object (being followed).

I do something similar in my space invaders mini game where a homing missile stores an internal reference to its target so it can react and update its path in real time.

Yep, that’s what I’m doing.

the problem isn’t how the “child” object is referenced by the “parent”, but in expecting a certain order of operations between transitions and frame listeners.  in particular, for this use you’d need transitions to be processed first, THEN enterFrame.  unfortunately, as you can discover for yourself by trial and error*, that is not the case, so your “follow” logic in enterFrame will always lag the transition’s movement by one frame.

*rant:  because Corona themselves refuses to properly document their internal frame update sequence.  this drove me CRAZY when I first started using Corona, and I couldn’t believe something so fundamental to properly using an SDK would be left so obscure.  it’s apparently intentional, as if they consider it some super-important trade secret, as if no-one else had EVER written a game-update loop before, geesh!  fe, see the tone of last response in this old thread:  https://forums.coronalabs.com/topic/17363-corona-app-execution-loop/