[SOLVED]Queue animated image after a looping animated image?

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Post Reply
Message
Author
User avatar
Semicolonkid
Regular
Posts: 51
Joined: Tue Feb 14, 2017 6:13 pm
Projects: Summoned
itch: semicolonkid
Contact:

[SOLVED]Queue animated image after a looping animated image?

#1 Post by Semicolonkid »

This might be a little complicated to describe.
So, let's say I have two images that are defined as looping animations:

Code: Select all

image Animation1:
	"Frame1.jpg"
	0.04
	"Frame2.jpg"
	0.04
	"Frame3.jpg"
	0.04
	"Frame4.jpg"
	0.04
	## etc.
	repeat
image Animation2:
	"OtherFrame1.jpg"
	0.04
	"OtherFrame2.jpg"
	0.04
	"OtherFrame3.jpg"
	0.04
	"OtherFrame4.jpg"
	0.04
	## etc.
	repeat
I want to show one animation, and then when the user is viewing the next animation, for it to wait until the first animation reaches the end of its current loop to start playing. For example:

Code: Select all

label start:
	show Animation1						## This animation is looping
	
	"Blah blah, talking about things and stuff! Animation1 will loop forever!!"
	
	show Animation2						## except WAIT for the current loop to finish somehow
	
	"Blah blah, Animation1 could still be playing right now,"
	"especially if it's more than 4 frames or if the user is clicking very fast,"
	"but I don't care! I'm in no rush. Let's show Animation2 only when we've shown the last frame of Animation1."
My goal is a seamless transition from one looping animation to another (they both have the same start/end frame), without pausing the text.
Any ideas how one might accomplish this?
Last edited by Semicolonkid on Sat Jan 09, 2021 8:39 pm, edited 1 time in total.
Image

User avatar
_ticlock_
Miko-Class Veteran
Posts: 910
Joined: Mon Oct 26, 2020 5:41 pm
Contact:

Re: Queue animated image after a looping animated image?

#2 Post by _ticlock_ »

Hi, Semicolonkid,

I don't think there's any direct way. However, you can try, for example, DynamicDisplayable:

Code: Select all

init python:
    def dd(st, at):
        if store.trigger == 0:
            return "Animation1", 0.01
        elif store.trigger == 1:
            if (duration - st % duration)  < 0.02:
                store.trigger = 2
            return "Animation1", 0.01
        else:
            return "Animation2", None

image anim = DynamicDisplayable(dd)

default trigger = 0
label start:
	show Animation1
	
	"Blah blah"
	
	$ trigger = 1
	
	show Animation2
	"Blah blah, Animation1 could still be playing right now,"
	"especially if it's more than 4 frames or if the user is clicking very fast,"
	"but I don't care! I'm in no rush. Let's show Animation2 only when we've shown the last frame of Animation1."
duration is total time of single cycle of Animation1

I think similar can be reached using function inside animation and ConditionSwitch. Function can trigger switch in ConditionSwitch in same manner as above.

User avatar
Semicolonkid
Regular
Posts: 51
Joined: Tue Feb 14, 2017 6:13 pm
Projects: Summoned
itch: semicolonkid
Contact:

Re: Queue animated image after a looping animated image?

#3 Post by Semicolonkid »

Hmmm, I'm not sure if that's a feasible solution for what I had in mind...
I didn't want to get off-topic, but some context is probably necessary. Truth is, I'm still stumped on a question I asked a week or two ago about changing an animation's speed seamlessly (i.e. not needing to start it over first). I got an answer that...worked, but only partially (like the animation would work at 40% faster, 100% faster, but was not different in the slightest at 15% faster, or many other speeds (I tested carefully)).

So instead, this was my idea for a workaround. Loop the animation, and then just wait till it's done to play it again at a faster rate. Not ideal, but still a seamless speed increase.
But I'd like to be able to gradually change the speed at many different thresholds. With this solution, that would require building 6 or so of the same animation, one for each speed, and this would need to be done for all animations that do this. Am I wrong?

Not your fault; I didn't make my real problem clear. This is still a pretty cool idea that I could very well use!
But yeah, it feels like what I'm trying to do may just be a bit too greedy to have a clean answer.
Image

User avatar
Remix
Eileen-Class Veteran
Posts: 1628
Joined: Tue May 30, 2017 6:10 am
Completed: None... yet (as I'm still looking for an artist)
Projects: An un-named anime based trainer game
Contact:

Re: Queue animated image after a looping animated image?

#4 Post by Remix »

Answers for all...

You can use the ATL keyword "function" to call a Python function and have that function return:
float numeric : Re-call/re-interpret the function again (maybe repeatedly) after that many seconds.
None : allow the following normal ATL to continue

First a blocker setup (where on ATL sets a block flag and another only activates when unblocked)

Code: Select all

default atl_blocked = False

init python:

    def block_atl(*args):
        store.atl_blocked = True

    def unblock_atl(*args):
        store.atl_blocked = False

    def check_block_atl(*args):
        return 0.05 if store.atl_blocked else None

transform blocker_anim:
    # set block to True
    function block_atl
    ## do the animation
    # ...
    "last_frame.png"
    # set block to False
    function unblock_atl
    pause 0.1 # to give enough "unblocked" time
    repeat

transform check_block_anim:
    # you could show first frame and let it hang until ready
    function check_block_atl ### this will effectively pause until unblocked
    # do the animation
    repeat
Not entirely sure how useful that really is though.

Variable Speed Animation: (Yes, this *Should* solve your variable speed animation question)
Rather than using "pause", use "function" toggling a boolean to dictate block/unblock...

Code: Select all

default pause_complete = True
default pause_duration = 0.2

init python:

    def variable_pause(*args):
        # toggle the variable
        store.pause_complete = not pause_complete
        # return None to continue or pause duration
        return None if pause_complete else pause_duration

image variable_anim:
    Solid("#F00", xysize=(20, 20)) 
    function variable_pause ### <--- function rather than pause
    Solid("#0F0", xysize=(20, 20))
    function variable_pause
    Solid("#00F", xysize=(20, 20))
    function variable_pause
    repeat

label start:

    scene expression "#876"

    show variable_anim
    pause

    $ pause_duration = 0.4
    pause

    $ pause_duration = 0.05
    pause

    $ pause_duration = 0.8
    pause
Frameworks & Scriptlets:

User avatar
Semicolonkid
Regular
Posts: 51
Joined: Tue Feb 14, 2017 6:13 pm
Projects: Summoned
itch: semicolonkid
Contact:

Re: Queue animated image after a looping animated image?

#5 Post by Semicolonkid »

Remix wrote: Sat Jan 09, 2021 9:48 am Variable Speed Animation: (Yes, this *Should* solve your variable speed animation question)
Rather than using "pause", use "function" toggling a boolean to dictate block/unblock...
Right, so the solution I got last time also involved using the "function" keyword to build the animation. It was built a little differently, but after testing for a while, I can confirm that this has the same issue. I've been trying to figure out a good way to present the issue, but uuuugghh, it's so hard to test well and describe. I hope you can bear with me.

Let me try to demonstrate, with a more elaborate version of the animation (that won't give you a seizure, heh).
(code in the init python block is identical, so I'm ignoring that here)

Code: Select all

default preferences.gl_framerate = 10 ## I'll bring this up in a bit
default pause_complete = True
default pause_duration = 0.04

image variable_anim:
    Solid("#F00", xysize=(20, 20), yalign=0.5)
    function variable_pause
    Solid("#F00", xysize=(25, 25), yalign=0.5)
    function variable_pause
    Solid("#F00", xysize=(30, 30), yalign=0.5)
    function variable_pause
    Solid("#F00", xysize=(35, 35), yalign=0.5)
    function variable_pause
    Solid("#F00", xysize=(40, 40), yalign=0.5)
    function variable_pause
    Solid("#F00", xysize=(45, 45), yalign=0.5)
    function variable_pause
    Solid("#F00", xysize=(50, 50), yalign=0.5)
    function variable_pause
    Solid("#F00", xysize=(55, 55), yalign=0.5)
    function variable_pause
    Solid("#F00", xysize=(50, 50), yalign=0.5)
    function variable_pause
    Solid("#F00", xysize=(45, 45), yalign=0.5)
    function variable_pause
    Solid("#F00", xysize=(40, 40), yalign=0.5)
    function variable_pause
    Solid("#F00", xysize=(35, 35), yalign=0.5)
    function variable_pause
    Solid("#F00", xysize=(30, 30), yalign=0.5)
    function variable_pause
    Solid("#F00", xysize=(25, 25), yalign=0.5)
    function variable_pause
    Solid("#F00", xysize=(20, 20), yalign=0.5)
    function variable_pause
    repeat
label start:
    scene expression "#876"

    show variable_anim
    "Normal."

    $ pause_duration = 0.02
    "Double speed."

    $ pause_duration = 0.04
    while True:
        $ pause_duration -= 0.002
        "[pause_duration]"
Ignoring the while loop, just try playing this at regular speed, and then double speed.
At "preferences.gl_framerate = 10," I see expected behavior on my machine. It goes twice as fast.
However, at "preferences.gl_framerate = None" (which will draw at max framerate), It does not. It goes faster than normal, but definitely not twice as fast. This is just one example; throughout the while loop, there seem to be periods where it just feels stubborn, until it jumps up. At framerate 10, though, it behaves as I would expect.

The PROBLEM IS, I don't know if you'll see the same thing on your machine. For my VN (setting framerate to 10), one of my friends reported the animations looking smooth/fine, while for another there was clear stuttering (both were on gaming computers).

I don't know if this is just some simple math thing with framerate that I don't understand, but I've been hung up on this for days.
Image

User avatar
Semicolonkid
Regular
Posts: 51
Joined: Tue Feb 14, 2017 6:13 pm
Projects: Summoned
itch: semicolonkid
Contact:

Re: Queue animated image after a looping animated image?

#6 Post by Semicolonkid »

Alright, I eventually set up a slider to really help test the problem, and I think this is the most notable thing I found:

When preferences.gl_framerate = None: lowering the "pause time" really does work gradually - there's just a limit to how fast it can go. (I do not know why).

Whereas when the framerate is 10 (or certain other numbers), lowering the "pause time" to 0 makes it go...you know, infinitely fast like you'd expect (constant flickering).

I suppose the best way to illustrate this would be to copy/paste the code from the above two posts (with preferences.gl_framerate = None, plus the necessary init block stuff) and follow the while loop all the way down to 0, and note that the animation seems to have a speed ceiling - it does not flicker (if it DOES flicker for anyone willing to test this, I'd love to know).

So, in short, I suppose my solution is going to be to offer calibration for these two framerates (for now). I'm already well on my way to developing a clean enough way to do that.

I appreciate the help! I'm going to remember both these answers in regards to the original question and have some fun experimenting. Sorry about the dense tangent, but thanks for the help!
Image

Post Reply

Who is online

Users browsing this forum: Bing [Bot], Google [Bot]