Animate while music is playing [SOLVED]

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
Panzer Poodle
Newbie
Posts: 6
Joined: Thu Aug 10, 2017 12:44 pm
Soundcloud: Panzer Poodle
Contact:

Animate while music is playing [SOLVED]

#1 Post by Panzer Poodle »

Hello!
I'm brand new to both Ren'Py and coding in general so I apologize in advance for any painful facepalms my post may have induced.

On paper, my problem sounds insanely simple. All I want is to have an animation stop as soon as the music in my scene ends.

So while I know this is horribly wrong, I would like to illustrate what my little monkey brain was trying to do:

Code: Select all

image guyheadbob:
        "characters/guyheadup.png"
        pause 0.45
        "characters/guyheaddown.png"
        pause 0.45
        if renpy.music.is_playing(channel='music') == True:
        	repeat

$ renpy.play("song.mp3", channel="music")       
guy "Whoa! I love this tune!"
show guyheadbob at place
I've done a fair amount of perusing and experimenting since but haven't figured it out yet. I'm hoping maybe someone can give me some pointers.

Thanks! :)
Last edited by Panzer Poodle on Fri Aug 18, 2017 6:01 pm, edited 1 time in total.

Panzer Poodle
Newbie
Posts: 6
Joined: Thu Aug 10, 2017 12:44 pm
Soundcloud: Panzer Poodle
Contact:

Re: Animate while music is playing

#2 Post by Panzer Poodle »

I realize that I can't put an 'if' condition in an ATL block so I've been looking for ways around that. DynamicDisplayables are cool except they don't seem to work for animations. I also came across Creator-Defined Displayables but that feels just way too complex for what I want.
I guess I'm just wondering if it would be possible to call a function in the ATL block to magically stop the animation if: renpy.music.is_playing(channel='music') == False.
... Or to write a function with the animation in it but I don't know how to do that yet.

If anyone has any tips for me, I would very much appreciate the help.

Thanks.

User avatar
IrinaLazareva
Veteran
Posts: 399
Joined: Wed Jun 08, 2016 1:49 pm
Projects: Legacy
Organization: SunShI
Location: St.Petersburg, Russia
Contact:

Re: Animate while music is playing

#3 Post by IrinaLazareva »

Well, try this:

Code: Select all

image bob guyhead:
    "characters/guyheadup.png"
    .45
    "characters/guyheaddown.png"
    .45
    repeat
image bob stopanima = "characters/guyheaddown.png"
    
label start:
    "...."
    play music "song.mp3" noloop
    guy "Whoa! I love this tune!"
    show bob guyhead at place
    while renpy.music.is_playing(channel='music'):
        "{nw}"
    show bob stopanima at place
    guy "Ok. Let's go...."

Panzer Poodle
Newbie
Posts: 6
Joined: Thu Aug 10, 2017 12:44 pm
Soundcloud: Panzer Poodle
Contact:

Re: Animate while music is playing

#4 Post by Panzer Poodle »

Awesome, will do. I'm off to bed now but I'll try this out tomorrow! Thanks a lot. :)

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: Animate while music is playing

#5 Post by Remix »

DynamicDisplayables are fine for animations using a function as the first parameter...

Untested, so debug n tweak

Code: Select all

init python:

    def animate_image(st, at, *args, **kwargs):
        index = round( st / kwargs['repeat'] ) % len( kwargs['images'] )
        if not renpy.music.is_playing(channel='music'):
            kwargs['repeat'] = None
            index = index - 1 if index > 0 else len( kwargs['images'] ) - 1
        return kwargs['images'][ index ], kwargs['repeat']

    def animate_image_predict(*args, **kwargs):
        return kwargs['images']

image headbob = DynamicDisplayable(
                            animate_image,
                            _predict_function = animate_image_predict,
                            images = [ "characters/guyheadup.png", "characters/guyheaddown.png" ],
                            repeat = 0.45)
Sleep here too. Can help debug tomorrow if needed
Frameworks & Scriptlets:

Panzer Poodle
Newbie
Posts: 6
Joined: Thu Aug 10, 2017 12:44 pm
Soundcloud: Panzer Poodle
Contact:

Re: Animate while music is playing

#6 Post by Panzer Poodle »

IrinaLazareva wrote: Wed Aug 16, 2017 2:32 pm Well, try this:

Code: Select all

image bob guyhead:
    "characters/guyheadup.png"
    .45
    "characters/guyheaddown.png"
    .45
    repeat
image bob stopanima = "characters/guyheaddown.png"
    
label start:
    "...."
    play music "song.mp3" noloop
    guy "Whoa! I love this tune!"
    show bob guyhead at place
    while renpy.music.is_playing(channel='music'):
        "{nw}"
    show bob stopanima at place
    guy "Ok. Let's go...."
Hm, for some reason the 'no wait' tag doesn't work... Either way, I'm not sure this is a viable solution to my problem given that he stops bobbing his head as soon as you move the game forward. What I'm trying to accomplish is to have him keep bobbing his head as you're playing the game and just stop of his own 'accord' the minute the music ends... If that makes sense.
Anyways, thanks for the effort. I'll keep cracking at it. :)
Remix wrote: Thu Aug 17, 2017 7:04 pm DynamicDisplayables are fine for animations using a function as the first parameter...

Untested, so debug n tweak

Code: Select all

init python:

    def animate_image(st, at, *args, **kwargs):
        index = round( st / kwargs['repeat'] ) % len( kwargs['images'] )
        if not renpy.music.is_playing(channel='music'):
            kwargs['repeat'] = None
            index = index - 1 if index > 0 else len( kwargs['images'] ) - 1
        return kwargs['images'][ index ], kwargs['repeat']

    def animate_image_predict(*args, **kwargs):
        return kwargs['images']

image headbob = DynamicDisplayable(
                            animate_image,
                            _predict_function = animate_image_predict,
                            images = [ "characters/guyheadup.png", "characters/guyheaddown.png" ],
                            repeat = 0.45)
Sleep here too. Can help debug tomorrow if needed
Wow, awesome! Sorry for the late reply, had an internet shortage. I'll check this out ASAP and see... Thanks!

Panzer Poodle
Newbie
Posts: 6
Joined: Thu Aug 10, 2017 12:44 pm
Soundcloud: Panzer Poodle
Contact:

Re: Animate while music is playing

#7 Post by Panzer Poodle »

Hmm, I'm getting an uncaught exception...
Does this make any sense? Might be something on my end but it's hard for me to tell.

Code: Select all

While running game code:
  File "game/script.rpy", line 246, in script
    m "..." with quickdissolve
  File "game/script.rpy", line 44, in animate_image
    return kwargs['images'][ index ], kwargs['repeat']
TypeError: list indices must be integers, not float

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: Animate while music is playing

#8 Post by Remix »

Ah yup, needs int()'ing ...

A slight upgrade version:

Code: Select all

init python:

    shown_image = None
    def conditional_animate(st, at, *args, **kwargs):
        global shown_image
        index = int( round( st / kwargs['anim_repeat'] ) % len( kwargs['anim_images'] ) )
        if callable(kwargs['anim_condition']) and not kwargs['anim_condition']():
            index = 0 if not shown_image else kwargs['anim_images'].index( shown_image )
            if kwargs['anim_stop']:
                kwargs['anim_repeat'] = None
        shown_image = kwargs['anim_images'][ index ]
        return kwargs['anim_images'][ index ], kwargs['anim_repeat']

    def conditional_animate_predict(*args, **kwargs):
        return kwargs['anim_images']

    def conditional_function():
        return renpy.music.is_playing(channel='music')

image headbob = DynamicDisplayable(
                            conditional_animate,
                            _predict_function = conditional_animate_predict,
                            anim_condition = conditional_function,
                            anim_images = [ "characters/guyheadup.png", 
                                            "characters/guyheaddown.png",
                                          ],
                            anim_repeat = 0.45,
                            anim_stop = False)
Allows passing a function name as the condition and allows pausing (while condition False) as well as full stop

Seems to work for me, though I was just using a variable test rather than renpy.music.is_playing
Frameworks & Scriptlets:

Panzer Poodle
Newbie
Posts: 6
Joined: Thu Aug 10, 2017 12:44 pm
Soundcloud: Panzer Poodle
Contact:

Re: Animate while music is playing

#9 Post by Panzer Poodle »

Holy s***!!! It works! :O
I'd been banging my head for days.
Looking at your code, it would have taken me forever to figure it out...
Nothing more to say about it really. Just works perfectly.

Thank you so much for the help Remix!
I will feature you in the credits and the millions (more like 5-6) of people who play my game will know your name. :D :D

Post Reply

Who is online

Users browsing this forum: Google [Bot], MagicBuns