-
-
Notifications
You must be signed in to change notification settings - Fork 931
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat!: New AlternatePattern
argument for SequenceEffect
#3322
base: main
Are you sure you want to change the base?
feat!: New AlternatePattern
argument for SequenceEffect
#3322
Conversation
…the direction of the delta offset vec. Corrected progress getter overload in SequenceEffect to correctly map to the progess when _index < 0. Added onStart() in the initial conidition of ecede() so that effects like MoveEffect can recalculate their initial data. Removed unnecessary math in DurationEffectController to avoid potential negative zeros. Replaced �lternate boolean for SequenceEffect with a new type AlternatePattern which allows users to include or exlude the last effect in the sequence when the pattern reverses. Default value is now AlternatePattern.none. Updated all SequenceEffect examples and tests to reflect changes. Made the TiledGame example project more aesthetically interesting. The camera now pans to all 4 corners WRT the bounds of the loaded map and uses the new AlternatePattern feature along with all the new fixes.
feature!:
AlternatePattern
for SequenceEffect
. fix:
bad math in MoveToEffect
.feature!:
AlternatePattern
for SequenceEffect
(and fix wrong math in MoveToEffect
).
feature!:
AlternatePattern
for SequenceEffect
(and fix wrong math in MoveToEffect
).feat!:
AlternatePattern
for SequenceEffect
(and fix wrong math in MoveToEffect
).
…ing so that is fixed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea, it needs tests and docs though.
EDIT: Ah you already wrote that in the PR description.
@@ -40,7 +40,7 @@ class MoveToEffect extends MoveEffect { | |||
@override | |||
void apply(double progress) { | |||
final dProgress = progress - previousProgress; | |||
target.position += _offset * dProgress; | |||
target.position += _offset * dProgress.abs(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, is this really correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After thinking about it some more yesterday I think the issue wasn't the reflected vector itself, but rather that the direction vector was incorrect when the camera has a viewport-aware bounds behavior. This causes it to never reach its destination and so the reflective vector is incorrect. That's why taking the absolute value was ok after I added the step to recalculate the vector.
The camera won't be the only component that may never complete its effect with regards to MoveToEffect
so this matter should be resolved in the PR imo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But this will potentially overshoot the destination right? And also it won't be matching the time anymore?
If you are at 0.99 progress and the delta progress is -0.02 when the effect is going forward it should have moved 0.03 "steps", since it'll start going back again, but with this it will simply move to 1.01.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I'm understanding your question precisely, but it seems that you've noticed the possibility of under-fitting the expected step amounts, time-wise. Yes this does happen with the viewport-aware behavior as described (the camera cannot exceed the bounds, and therefore never arrives to its destination). ATM with the changes I've added, I have not seen any noticeable problems.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Simply put; I don't think it will always be at the expected place at each time step when abs
is used, that was what I tried to describe in the last comment, the delta doesn't become correct. If it overshoots its destination it should start going back, in the cases where it is alternating.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
progress
will be decrementing dt
units from 1.0
during the reverse phase of the alternating pattern, while previousProgress
retains the progress+dt
value from before. Therefore dProgress = progress - previousProgress
would be negative, which we don't want to use. It's better to recalculate the starting position and use positive scalars instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But it'll surely overshoot the end value then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi. No it never does for this effect or any as far as I can tell. The same math could have overshot in the reverse direction when dProgress
was negative.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the case that dProgress
becomes negative it is supposed to go backwards. Say that the previous progress is 0.9 and it it supposed to move backwards to 0.8, then dProgress
should be -0.1
, not 0.1
.
Try running only the the MoveToEffect
with alternate: true
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi. A negative progress value for this effect specifically is not only unintuitive but also does not solve the MoveToEffect
starting vector issue.
enum AlternatePattern { | ||
none(0), | ||
includeLast(1), | ||
excludeLast(2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If infinite
(or N runs) is used together with alternate
, shouldn't the first also be excluded on runs that are after the first and not the last?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It already behaved this way. Only the last one was ever being repeated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've corrected the default pattern behavior. The alternating pattern now plays both the first and last Effect
elements in the list, instead of just the last element as it did before this PR. This default behavior is AlternatePattern.repeatLast
. The term "last" used here is relative to the playback direction.
To avoid playing first and last Effect
s twice-in-a-row when the sequence reverses, AlternatePattern.doNotRepeatLast
is appropriate.
feat!:
AlternatePattern
for SequenceEffect
(and fix wrong math in MoveToEffect
).AlternatePattern
for SequenceEffect
(and fix wrong math in MoveToEffect
)
AlternatePattern
for SequenceEffect
(and fix wrong math in MoveToEffect
)AlternatePattern
argument for SequenceEffect
…o skip start element whendoNotRepeatLast is true and the pattern is playing in reverse.
There's still the topic to discuss: I'm in favor of providing |
if (alternate) { | ||
totalDuration *= 2; | ||
|
||
if (alternatePattern == AlternatePattern.doNotRepeatLast) { | ||
totalDuration -= effects.first.controller.duration ?? 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How come the first one is removed here too? 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi. This has been explained in the PR, code comments, and here:
#3322 (comment)
@@ -136,7 +197,7 @@ class _SequenceEffectEffectController extends EffectController { | |||
} | |||
|
|||
@override | |||
double get progress => (_index + 1) / n; | |||
double get progress => (_index < 0 ? -_index : _index + 1) / n; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you explain this a bit? In what cases is the _index
negative? This doesn't seem like it would follow how progress
works for the rest of the effects.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The way the SequenceEffect
has been written for some time now is that it uses a negative _index
to determine if the pattern is in its reverse phase. To be clear, I did not write it this way. This code was like this when I started this PR,
@@ -40,7 +40,7 @@ class MoveToEffect extends MoveEffect { | |||
@override | |||
void apply(double progress) { | |||
final dProgress = progress - previousProgress; | |||
target.position += _offset * dProgress; | |||
target.position += _offset * dProgress.abs(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the case that dProgress
becomes negative it is supposed to go backwards. Say that the previous progress is 0.9 and it it supposed to move backwards to 0.8, then dProgress
should be -0.1
, not 0.1
.
Try running only the the MoveToEffect
with alternate: true
.
Please try running the |
I'll give it a proper try when I'm back home again next week! |
@TheMaverickProgrammer I haven't had the time to test it properly yet unfortunately (forgot that it was on my table 😅), but there is a test failing, could you have a look at that first?
|
The test failing is related to the issue at hand. I have thought a lot about it and can propose a quick solution but it's not ideal: There can be a |
Hmm, I'm not too fond of that idea, it feels like a less clean API. |
Because in the PR I said I added a new callsite to |
MoveToEffect
so that negative progress did not reflect the direction of the delta offset vec.SequenceEffect
to correctly map to the progress when_index < 0
.onStart()
inrecede()
initial condition so that effects likeMoveToEffect
can recalculate their initial data.DurationEffectController
to avoid potential negative zeros.AlternatePattern
which allows users to include or exclude the last effect in the sequence when the pattern reverses. NOTE: When playing forward, the last effect isList.last
, but in reverse it isList.first
.AlternatePattern.repeatLast
.AlternatePattern
feature along with all the new fixes.docs
and added dartdoc comments with///
.examples
ordocs
.TO DISCUSS
onEnd()
forEffect
s. Or provideonStart()
with an initialprogress
value to calculate from.Breaking Change?
Related Issues
I looked but didn't immediately see anyone reporting these issues. I discovered them myself.