I have animations working and a Timer. I understand that the Timer is the best way to get the Second Ticks ticking at exactly the second mark. For Animations I have used both AnimationController and the Timer with a small duration time (100ms). I think I must be missing something in that I don't completely understand when a Timer and AnimationController should each be used. They both cause a setState() and thus a Build(and thus redraw). I suppose one idea is if I could retain all the screen, and just redraw a small change in an animation.
full disclosure: I am working on the Flutter Clock Challenge!!!
Timer is unrelated to Flutter, and is just a timer like you'd fine in any other language.
On the other hand, AnimationController (and Ticker, its equivalent of Timer) is Flutter specific.
The difference with a Timer is that, by using AnimationController, the "ticker" can be muted, slowed, or mocked.
As such, using AnimationController we have a few benefits:
if the associated widget isn't visible, the animation is paused (that's what that vsync arg is used for)
we get access to a "slow animations" devtool which makes the seconds slower for animations only
tests can "mock" these timers. As such, if an animation last 3 seconds, a test can simulate the entire animation without having to actually wait for 3 seconds.
Related
What it's supposed to do:
I'm making a game on Scratch in which the character has a walking animation. The walking animation is supposed to switch their costume to a walking stance, wait 0.5 seconds then go to an idle stance, wait 0.5 seconds then go to a walking stance, and repeat that until they let go of the button.
The image below is an image of the animation blocks put together that play the animation when walking left.
What it does do and suspected reason for the bug:
It worked perfectly until I added a block function for the same character, when suddenly the animations broke for that character and the other one (who also has a walking animation with the same code). The second image below is an image of the blocking code.
After adding the block function, instead of waiting 0.5 seconds in between costume switches, it seems to switch to the walking stance and then immediately switch to the idle stance instead of waiting.
The image below is showing the blocking blocks and the movement it controls. While they are blocking it isn't supposed to be able to move. That part works fine but I included it in case it has something else to do with my problem.
What I have tried:
I tried running the peice of code shown individually (seperate from the other animation parts) but the bug still occurs and the animation doesn't wait 0.5 seconds. I also tried changing the other character's animation so that it wouldn't activate when the animation broadcast was sent but it still bugged, which means:
The problem isn't because it runs with another sprite too. (Because if it was it would have fixed when I deactivated the other animation).
The problem also isn't because it's connected with the right side walking and idle animations (Because if it was it would have fixed when I ran it alone).
Link to shared game:
https://scratch.mit.edu/projects/690164519/
I think the issue is with this part of your code. The forever loop is always trying to set the costume to the idle state when BlockStatus is NonBlocking.
This is then fighting with the loop that is trying to manage the swap between the idle and the walking costumes.
You may need to set a flag when the key is pressed and move the walking animation into this loop?
I can't do this at the moment because the system I'm using to detect input runs once every frame, meaning that the animation will continue looping every frame. I tried making it so that the animation would only run when the spacebar is being held down, but it just made it start and then pause when the spacebar is unheld, which is not what I'm going for. Is there any way to make it such that when a certain key is pressed, an animated sprite runs its animation once and then stops? Thanks for your help.
Telling the animation that currently playing to play is fine. I believe the issue is with stopping it. For that I suggest having an "idle" animation. So that instead of stopping the current animation, you can tell it to play the "idle" animation (which could be as simple as one frame).
Now, if you don't want to tell the animation to play every frame, use Input.is_action_just_pressed and Input.is_action_just_released, and that will tell you when to start and stop the animation.
And if you prefer to only run code if there is some input event, you can use _input. See also _process vs. _physics_process vs. *_input and Using InputEvent.
Addendum: I paid little attention to "only one time". In the SpriteFrames editor, where you define the animations, there is a toggle in the bottom where you can tell Godot if you want the animation to loop or not.
In the odd case where you might want to change that from code, it would be something like this $AnimatedSprite.frames.set_animation_loop("animation_name", false) to make the animation not loop (you still need to tell Godot to play it, this changes how it plays from there on). Or you can replace false with true to make it loop again.
I need to play animation just one time.
Something like this:
public Animation[] animations;
animations[0].play();
I've looked through StackOverflow, all I found is:
animation["AnimationName"].wrapMode = WrapMode.Once;
animation.Play("AnimationName");
But it makes nothing.
Is this method actually for Unity3D 5?
Are there new ways to play animation one shoot?
I have one way for playing animation on mouse down.
For that open animator controller and add that dropping animation and one will be idle animation(this will have initial stage of dropping). Now make idle animation as default and add transition from idle to dropping animation.
Add parameter to this transition of type "Trigger". Set this parameter in transition condition.
And add one more transition from dropping animation to idle state.
So after dropping animation complete , it will come again in idle state.
Now For scripting :
int dropHash = Animator.StringtoHash("parameterName");
onmouseDown :
animator.SetTrigger(dropHash);
Hope you get some idea. This may help you. Thanks.
You have to use wrapMode. In your case, it can be something like
foreach(Animation anim in animations) {
anim.wrapMode = WrapMode.Once;
anim.Play();
}
What is the use of tick function in easeljs. When to use it? What exactly does it do to a stage? What is the exact format? I see different ways in which it has been called in different tutorials.
What is difference between tick and ticker?
The tick function on the Stage (and other display objects) advances all the child animations. Things like MovieClip and Sprite have frame-based animation, which are advanced the the next frame whenever they are ticked. You can turn off updateOnTick on the stage to prevent this.
The Ticker is a utility class that manages an actual heartbeat. It is a totally optional utility, but it creates an interval (using timeouts or requestAnimationFrame), and then dispatches events at a ~constant rate (the rate will be dependant on the performance on the device).
You can set the stage as a listener to the Ticker (instead of a custom handler function), and it will automatically call update() (and hence tick()) on the stage. This is the easiest usage. You can also manually call stage.update() in your own function to tick and redraw the stage. Note that using the stage as a listener guarantees that the stage will constantly update - so if you want to control it, then listen to the Ticker yourself, and manually call stage.update().
I have a simple app that I am creating with a countdown timer that uses a DispatcherTimer for the time base. I have an event handler setup for On_Tick of the DispatcherTimer (set for 1 sec interval). I have three (3) pivot pages using three different instances of AdControl and all are "live" with a real ApplicationID and AdUnitID. This timer is setup on one of the pivot pages.
What I am seeing is that when I open my app and the AdControl starts, after 60 seconds, the adControl wants to refresh. My timer works fine for the first minute, then starts to lose a second every three seconds, like it is missing a tick event (coincidentally when the adcontrol "scrolls" to a new message every three seconds?). I've tried using a background worker for the dispatcherTimer but that did not seem to do anything for me. The code in the event handler is fairly short, with just a couple of "if-then" statements and a few textBlock updates.
Anyone else seen similar issues with the AdControl?
I would say the reason is that the ad control and the timer both want to do something on the UI thread. Thus when the ad control is busy the timer action is blocked during this time. To quote MSDN:
Timers are not guaranteed to execute exactly when the time interval
occurs, but they are guaranteed to not execute before the time
interval occurs. This is because DispatcherTimer operations are placed
on the Dispatcher queue like other operations. When the
DispatcherTimer operation executes is dependent on the other jobs in
the queue and their priorities.
It also explains why using a background worker does not help. As soon as you go back from another thread to the UI thread you have the same problem again. So this issue is basically by design.
Oh and it can also be the other way round. If you would be doing intensive work in the UI thread then the ad control would be blocked. As well as the rest of your UI. This is the reason why you should do as much work as possible in background threads. Maybe the ad control doesn't adhere to this advice.
So far this probably won't help you much. But perhaps it is possible to just use one AdControl and move this from Pivot to Pivot as the user pans around?
I've experienced the same problem with my own timer style app. In my case it only appears to happen when there is animation in the current advertisement.
According to the DispatcherTimer documentation, the delay is expected behaviour, so the solution it to use a different timer... eg System.Threading.Timer
...
//create the timer
var timer = new System.Threading.Timer(
new System.Threading.TimerCallback(TimerTick),
null,
//Set the due time to infinite so the timer wont start immediately
System.Threading.Timeout.Infinite,
0);
//start the timer
timer.Change(0, 1000);
//stop the timer
timer.Change(System.Threading.Timeout.Infinite, 0);
}
void TimerTick(object state)
{
//Dont forget to update the UI on the UI thread.
Dispatcher.BeginInvoke(() =>
{
MyTextBox.Text = "New Text";
});
}
Problem solved!