How to control self.play run at specific time point - manim

Suppose there are two self.play statements, the first starts at 1s, I want to the seconds start at precisely 3s from the begining.
Currently I use self.wait to control the steps:
self.wait(1)
self.play...... # first animation
self.wait(2) # because 1 + 2 = 3
self.play...... # second animation
However, because the first animation will take sometime (e.g. 1.5s) to finish, actually the second animation will start at 1 + 1.5 + 2 = 4.5s.
How can I make the second self.play start run at precisely 3s from the begining?
Thanks in advance.

Do you mean, this?
class SuccessionExample(Scene):
def construct(self):
number_line=NumberLine(x_min=-2,x_max=2)
triangle=RegularPolygon(3,start_angle=-PI/2)\
.scale(0.2)\
.next_to(number_line.get_left(),UP,buff=SMALL_BUFF)
text_1=TextMobject("1")\
.next_to(number_line.get_tick(-1),DOWN)
text_2=TextMobject("2")\
.next_to(number_line.get_tick(0),DOWN)
text_3=TextMobject("3")\
.next_to(number_line.get_tick(1),DOWN)
text_4=TextMobject("4")\
.next_to(number_line.get_tick(2),DOWN)
self.add(number_line)
self.play(ShowCreation(triangle))
self.wait(0.3)
self.play(
#The move of the triangle starts
ApplyMethod(triangle.shift,RIGHT*4,rate_func=linear,run_time=4),
AnimationGroup(
Animation(Mobject(),run_time=1),#<- one second pause
Write(text_1),lag_ratio=1 #<- then start Write animation
),
AnimationGroup(
Animation(Mobject(),run_time=2),#<- two seconds pause
Write(text_2),lag_ratio=1 #<- then start Write animation
),
AnimationGroup(
Animation(Mobject(),run_time=3),#<- three seconds pause
Write(text_3),lag_ratio=1 #<- then start Write animation
),
AnimationGroup(
Animation(Mobject(),run_time=4),#<- four seconds pause
Write(text_4),lag_ratio=1 #<- then start Write animation
),
)
self.wait()

Related

Logitech LUA Script: MoveMouseRelative not working as expected

I am trying to write a script which will spin my character 180 degrees in game while holding lctrl and right clicking. This script works, but takes forever to spin around because of the sleep timer:
EnablePrimaryMouseButtonEvents(true)
function OnEvent(event, arg)
if (event == "MOUSE_BUTTON_PRESSED" and arg == 2 and IsModifierPressed("lctrl")) then
for i = 0, 96 do
MoveMouseRelative (125,0)
Sleep (1)
end
end
end
If I increase MouseMoveRelative beyond 125, it starts to move the mouse in the wrong direction. No matter what value I use (I've tried lots of values between 100 and 12,000), it always moves the mouse a very small distance either left or right.
If I eliminate the Sleep function, the results are inconsistent. It usually rotates my character between 80-140 degrees. I suspect this is because MoveMouseRelative starts by getting the current mouse position and it requires a delay before the position it gets is accurate.
Any guidance as to why MouseMoveRelative doesn't work correctly for values above 125? Or any advice on how to quickly move the mouse 12,000 relative units on the x-axis instantaneously?
If I increase MouseMoveRelative beyond 125, it starts to move the mouse in the wrong direction.
The allowed range is -127...+127
I suspect this is because MoveMouseRelative starts by getting the current mouse position
No.
It does not ask the current mouse position.
It invokes SendInput() without flag MOUSEEVENTF_ABSOLUTE to simulate relative mouse movement.
how to quickly move the mouse 12,000 relative units on the x-axis instantaneously?
for i = 0, 96 do
MoveMouseRelative (125,0)
end
If I eliminate the Sleep function, the results are inconsistent. It usually rotates my character between 80-140 degrees.
Try more precise version of Sleep()
for i = 0, 96 do
MoveMouseRelative (125,0)
FastSleep(1)
end
Or any advice on how to quickly move the mouse 12,000 relative units
on the x-axis instantaneously?
If you want to move relative 12000 instantaneously, why do you move 97 steps of 125 with 1ms delays?
97*125 is 12125
Why not MoveMouseRelative(12125, 0) ?
According to the manual MoveMouseRelative takes "a few milliseconds" to complete.
1 ms is not a few. Reading the mouse position too early will give you the starting position. So I would presume that spamming relative movements which refer to that position might cause problems.

How to implement countdown function like Yahoo's APP News Digest

I can use CAShapeLayer and UIBezierPath to draw the circle, I can also use this property CAShapeLayer.strokeEnd to control the progress. But the fast scrolling of path and time , I do not know how to implement.
Now I think the approach is to calculate the time difference between the two , and then use the time difference to circulation .
For example, The time difference between the two is 1000 seconds , should I have to set strokeEnd and the middle of the Label 1000 cycles ? Or that implement good results it ?
thanks in advance!
Note : StrokeEnd accepts value between 0 - 1
Lets Say,
See in your case circle represents the remaining time it will take to appear new feed. lets say 3PM.
so 3 PM will be your nextFeedTime = 3PM and,
you got this feed at 12PM so feedTime = 12PM.
So now you will have start and end value of feedTime=12PM - nextFeedTime=3PM
So feedTime is 0 for strokeEnd and nextFeedTime is 1 for StrokeEnd.
When you open app you will got currentTime which is initially initialised with feedTime and later it will be replaced all the time with current time stamp.
Lets assume currentTime is 1 PM.
Now we can calculate ratio to animate strockEnd property
strokeEnd = currentTime / nextFeedTime
and animate strokeEnd accordingly. hope this will helps you!

Dispatch and Delay between calls

I'm making a clone for that old game Simon (a.k.a. Genius, in Brazil), the one with the for coloured buttons which the player needs to press following a sequence of colors.
For testing, interface has 4 coloured buttons
I created an array for the button outlets, for easy access:
var buttonArray:[UIButton] = [self.greenButton, self.yellowButton, self.redButton, self.blueButton]
Also, created another array to store the sequence of colors
var colors:[Int] = []
When a game starts it calls a function which adds a random number from 0 to 3 (index on buttonArray), and add this number to the colors array
After adding a new color the color sequence, the app needs to show the sequence for the user, so he can repeat it
For that, it calls the playMoves function, which uses a for loop the run through the colors array and change the alpha from the button, simulating a 'blink'
func playMoves(){
let delay = 0.5 * Double(NSEC_PER_SEC)
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))
for i in self.colors{
self.buttonArray[i].alpha = 0.2
dispatch_after(time, dispatch_get_main_queue(), {
self.buttonArray[i].alpha = 1
})
}
}
It changes the alpha from the button to 0.2 and then, after half a second it returns the alpha to 1. I was using dispatch_after, passing the 0.5 seconds and on the code block it returns the alpha, as you guys can see on the code above.
On the first run, it appears to do it correctly, but when the colors array has 2 or more items, when it runs the loop, although it has a 0.5 sec delay, it blinks all the buttons on the same time.
It's probably some dumb mistake I'm making, but I'm clueless on the moment.
I would appreciate very much all the help!
Thanks!
All of these dispatch_after calls are scheduled at nearly the same time, making them appear to blink at the same time. There are a couple of approaches that would solve this:
You could, for example, adjust the when parameter (the dispatch_time_t parameter) for each button to be offset from the original time (such that delay was, effectively i * 0.5 * Double(NSEC_PER_SEC)).
You could also use key-frame animation, but I'd suggest you first try fixing the delay in your dispatch_after approach first.

Animation in LOGO

I have created a nice pattern using the following one line code
repeat 36 [repeat 10[fd 10 rt 36] rt 10]
Now I want this to appear as if it is rotating. I have tried to clear the screen and then rotate the turtle a at a specific angle and then print the pattern again. But there is something completely wrong in my logic. Can anybody help?
In order to accomplish animation, you need an interpreter which supports it. The interpreter must be one which renders the entire output before displaying it (doesn't show the turtle movement during drawing), and it also must support the wait command (or something similar to it). An example of an interpreter that meets these qualifications would be the one at www.logointerpreter.com. Here's an example which spins your wheel a full rotation and works with that interpreter:
ht
repeat 360
[
clean
repeat 36 [repeat 10[fd 10 rt 36] rt 10]
wait 10
rt 1
]
As you can see, the outer loop draws 360 separate frames. After drawing each frame, it waits 10 milliseconds, so you can see the frame. It then rotates the turtle one degree before clearing the screen and beginning the drawing of the next frame. If you need a little more control, you could also store the starting angle for each frame in a variable, like this:
ht
make "start 0
repeat 360
[
cs
rt :start
repeat 36 [repeat 10[fd 10 rt 36] rt 10]
wait 10
make "start (:start + 1)
]

Decimal in slider value

I have a button that I press and a loop does:
NSLog(#"on");
sleep(slider.value);
NSLog(#"off");
sleep(slider.value);
However if I want to have the slider somewhere between 1 and 0 it either sleeps 1 second or not at all, how do I make it sleep half a second?
sleep() takes in seconds. You want to do sub seconds, so try using usleep(), which will sleep in milliseconds (.001 of a second). You may need to import unistd.h
So what you'd want to do is something like this:
usleep((int)(slider.value * 1000.0));

Resources