Ren'Py Need help cycling through different scenes and speeds

siletris

Newbie
Dec 20, 2022
17
18
I got a nice scene on video with three different camera angles, and three different speeds for each camera angle.

I want the player to be able to cycle through the camera angles and select the speed, so I made the code below, and it mostly works but it shows some strange behaviour

for example if I don't try to cycle through the angles (scenes of different angle) the speed controls work fine and im able to jump again to the same label and thanks to the IF statement load the correct scene at correct speed, but if click on fast or slow and then click on angle it doesn't jump to the other sex2 or sex3 label on the first try, I have to click twice or thrice.

Another weird thing, once Im in a different angle scene if I try to use the speed controls it jumps to the next or previous angle scene first then the speed controls work fine.

Screen code:
Code:
#images/videos

image sex v01 = Movie(group = "sex", size=(1920,1080), play = "videos/sex_vid01.webm", loop=True)
image sex v02 = Movie(group = "sex", size=(1920,1080), play = "videos/sex_vid02.webm", loop=True)
#and so on


#variables

default animation = 1 #starting animation
default angles = 1  #star angle
default top_speed = 1 #max number of speeds available
default speed_int = 1 #starting speed
default def_scene = Null #default scene, set later through variable
default scene_end = Null #ending scene, set later through a variable

#screen
label multiview_test:   
    screen viewangle():               
        imagebutton: #this button cycles thorugh the different angles
            yalign 0.4
            xalign 0.99
            auto ("images/camera_%s.webp")           
            action (If( animation < angles, SetVariable( "animation", animation + 1 ), SetVariable( "animation", 1 ) ), Jump(def_scene + str(animation)))  

        if speed_int < top_speed:
            #textbutton "Fast": #this button changes the start speed then jumps to the desired label
            imagebutton:
                xalign 0.99 yalign 0.5               
                auto ("images/fast_%s.webp")     
                action (If( speed_int < top_speed, SetVariable( "speed_int", speed_int + 1 )), Jump(def_scene + str(animation)))     
            if speed_int >= 2:
                #textbutton "Slow":
                imagebutton:
                    xalign 0.99 yalign 0.6               
                    auto ("images/slow_%s.webp")     
                    action (If( speed_int >= top_speed - 1, SetVariable( "speed_int", speed_int - 1 )), Jump(def_scene + str(animation)))       
            pass           
        else:
            imagebutton:
                xalign 0.99 yalign 0.6               
                auto ("images/slow_%s.webp")     
                action (If( speed_int >= top_speed - 1, SetVariable( "speed_int", speed_int - 1 )), Jump(def_scene + str(animation)))       
            if speed_int == top_speed:
                imagebutton:
                    xalign 0.99 yalign 0.7
                    auto ("images/finish_%s.webp")     
                    action Jump(scene_end)
            pass
        pass
scene code:
Code:
label sex0:
    show screen viewangle
    $ animation = 1       
    $ angles = 3   
    $ top_speed = 3
    $ speed_int = 1       
    $ def_scene = "sex"
    $ scene_end = "finish_sex"           

label sex1:      
    if speed_int == 1: 
        show sex v01 with dissolve:
            zoom 0.667
        "[speed_int]"
    elif speed_int == 2:
        show sex v02 with dissolve:
            zoom 0.667
        "[speed_int]"
    elif speed_int == 3:
        show sex v03 with dissolve:
            zoom 0.667
        "[speed_int]"
    pass
    label sex1_loop:
    mc "Test1"       
    jump sex1_loop


label sex2:         
    if speed_int == 1: 
        show sex v04 with dissolve:
            zoom 0.667
        "[speed_int]"
    elif speed_int == 2:
        show sex v05 with dissolve:
            zoom 0.667
        "[speed_int]"
    elif speed_int == 3:
        show sex v06 with dissolve:
            zoom 0.667
        "[speed_int]"
    pass
    label sex2_loop:
    mc "Test1"       
    jump sex2_loop


label sex3:         
    if speed_int == 1: 
        show sex v07 with dissolve:
            zoom 0.667
        "[speed_int]"
    elif speed_int == 2:
        show sex v08 with dissolve:
            zoom 0.667
        "[speed_int]"
    elif speed_int == 3:
        show sex v09 with dissolve:
            zoom 0.667
        "[speed_int]"
    pass
    label sex3_loop:
    mc "Test1"       
    jump sex3_loop
I know the code looks like crap, but that's the best i could come up with, any help would be greatly appreciated.
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
12,292
19,664
Screen code:
Oh god...


Code:
label multiview_test: 
    screen viewangle():
What the fucking fuck? Why do you even put the screen declaration into a label?


Code:
label sex0:
    show screen viewangle
[...]
    label sex1_loop:
    mc "Test1"     
    jump sex1_loop
Will one day people stop using this horror and learn that exist?


So...

Python:
screen videoHandler( videos ):

    #  Starting with the first animation.
    default animation = 0
    #  At the slowest speed.
    default speed = 0

    #  Get the number of animation from the provided scheme.
    default nbAnimation = len( videos )
    #  Get the maximal speed from the first video scheme.
    default maxSpeed = len( videos[0] )

    #  Display the currently selected video.
    #  /!\ A bit of doubt about the syntax here...
    add videos[animation][speed] pos( 100, 100 )

    #  Cycle through the animations.
    imagebutton:
           xalign 0.0
           ypos 0
           auto ("images/camera_%s.webp")
           action If( animation < nbAnimation - 1, SetScreenVariable( "animation", animation + 1 ), SetScreenVariable( "animation", 1 )

    # Lower the speed when it's possible.
    if speed > 1:
        imagebutton:
               xalign 0.0
               ypos 100   # Assume a height of 100 pixels by buttons
               auto ("images/slow_%s.webp")    
               action SetScreenVariable( "speed", speed - 1 )
    #  Increase the speed when it's possible.
    if speed < maxSpeed -1:
        imagebutton:
               xalign 0.0
               ypos 200   # Assume a height of 100 pixels by buttons
               auto ("images/fast_%s.webp")    
               action SetScreenVariable( "speed", speed + 1 )
    #  Finish if it's possible.
    if speed == maxSpeed:
        imagebutton:
               xalign 0.0
               ypos 300   # Assume a height of 100 pixels by buttons
               auto ("images/finish_%s.webp")    
               action Return

#  First series of videos.
#  One set/angle by tupple, increasing speed inside the tupple.
define videoSeries01 = [ ( "videos/sex_vid01.webm", "videos/sex_vid02.webm", "videos/sex_vid03.webm" ),
                         ( "videos/sex_vid04.webm", "videos/sex_vid05.webm", "videos/sex_vid06.webm" ),
                         ( "videos/sex_vid01.webm", "videos/sex_vid02.webm", "videos/sex_vid03.webm" ) ]

label sex0:
    call screen videoHandler( videoSeries01 )
    [whatever happen once the videos are played]


Edit: Fixed typo in the code.
 
Last edited:

siletris

Newbie
Dec 20, 2022
17
18
Oh god...




What the fucking fuck? Why do you even put the screen declaration into a label?




Will one day people stop using this horror and learn that exist?


So...

Python:
screen videoHandler( videos ):

    #  Starting with the first animation.
    default animation = 1
    #  At the slowest speed.
    default speed = 1

    #  Get the number of animation from the provided scheme.
    default nbAnimation = len( videos )
    #  Get the maximal speed from the first video scheme.
    default maxSpeed = len( videos[0] )

    #  Display the currently selected video.
    #  /!\ A bit of doubt about the syntax here...
    add videos[animation][speed] pos( 100, 100 )

    #  Cycle through the animations.
    imagebutton:
           xalign 0.0
           ypos 0
           auto ("images/camera_%s.webp")
           action If( animation < nbAnimation - 1, SetScreenVariable( "animation", animation + 1 ), SetScreenVariable( "animation", 1 )

    # Lower the speed when it's possible.
    if speed > 1:
        imagebutton:
               xalign 0.0
               ypos 100   # Assume a height of 100 pixels by buttons
               auto ("images/slow_%s.webp")    
               action SetScreenVariable( "speed", speed - 1 )
    #  Increase the speed when it's possible.
    if speed < maxSpeed:
        imagebutton:
               xalign 0.0
               ypos 200   # Assume a height of 100 pixels by buttons
               auto ("images/fast_%s.webp")    
               action SetScreenVariable( "speed", speed + 1 )
    #  Finish if it's possible.
    if speed == maxSpeed:
        imagebutton:
               xalign 0.0
               ypos 300   # Assume a height of 100 pixels by buttons
               auto ("images/finish_%s.webp")    
               action Return

#  First series of videos.
#  One set/angle by tupple, increasing speed inside the tupple.
define videoSeries01 = [ ( "videos/sex_vid01.webm", "videos/sex_vid02.webm", "videos/sex_vid03.webm" ),
                         ( "videos/sex_vid04.webm", "videos/sex_vid05.webm", "videos/sex_vid06.webm" ),
                         ( "videos/sex_vid01.webm", "videos/sex_vid02.webm", "videos/sex_vid03.webm" ) ]

label sex0:
    call screen videoHandler( videoSeries01 )
    [whatever happen once the videos are played]
Thanks for the reply, your code mostly works, and I say that cuz I found a couple errors from which I could only fix this one.

default animation = 0 #if not 0 it wont start from the first angle
default speed = 0 #if not 0 it wont start from the slowest speed

But these errors I can't find how to fix them, they are out of my skill, hope you can help:

The speed up button never hides even on top speed and if player clicks on it again it shows an out of tuple error

Once the first angle/scene is loaded if I click on the change scene button it changes to the second and then third and then back to second again, but it never goes back to the first angle/scene.

Once I call the screen it doesn't allow the player interact with the scene dialogue, I want the player to have interactive dialogue choices but no text appears once the screen is loaded.
 

siletris

Newbie
Dec 20, 2022
17
18
Nevermind, I was able to fix everything, here is the code I ended with, hope it helps someone else tryingto do the same:

Python:
#on your main script or whatever you use to store variables and screens

default scene_end = Null #after video scene, outside the screen as a global variable or it wont work later

screen videoHandler( videos ):
    modal False
    #Default scene  
    #  Starting with the first animation.
    default animation = 0 #has to start in 0
    #  At the slowest speed.
    default speed = 0 #has to start in 0
    #  Get the number of animation from the provided scheme.
    default nbAnimation = len( videos )
    #  Get the maximal speed from the first video scheme.
    default max_speed = len( videos )

    #  Display the currently selected video.
    #  /!\ A bit of doubt about the syntax here...
    add videos[animation][speed] pos( 0, 0 ) zoom 0.8 #Im using videos as images so i added zoom and set pos at 0,0 but you can do whatever you need here

    #  Cycle through the animations.
    imagebutton:
        xalign 0.99
        yalign 0.4
        auto ("images/camera_%s.webp") #remember to change this to whatever image you want to use
        action If( animation < nbAnimation - 1, SetScreenVariable( "animation", animation + 1 ), SetScreenVariable( "animation", 0 ))
    #multiple IF statements to show/hide buttons when they aren't needed.
    if speed < max_speed - 1:
        #textbutton "Fast":
        imagebutton:
            xalign 0.99
            yalign 0.5              
            auto ("images/fast_%s.webp")       #remember to change this to whatever image you want to use
            action SetScreenVariable( "speed", speed + 1 )
        if speed > 0:
            #textbutton "Slow":
            imagebutton:
                xalign 0.99
                yalign 0.6              
                auto ("images/slow_%s.webp")       #remember to change this to whatever image you want to use
                action SetScreenVariable( "speed", speed - 1 )
        pass          
    else:
        imagebutton:
            xalign 0.99
            yalign 0.6              
            auto ("images/slow_%s.webp")       #remember to change this to whatever image you want to use
            action SetScreenVariable( "speed", speed - 1 )
        if speed == max_speed - 1:
            imagebutton:
                xalign 0.99
                yalign 0.7
                auto ("images/finish_%s.webp")       #remember to change this to whatever image you want to use
                action Jump(scene_end)
        pass
    pass


#scene code
label sex0:
#  First series of videos.
#  One set/angle by tupple, increasing speed inside the tupple.
define videoSeries01 = [ ( "scene1_speed1", "scene1_speed2", "scene1_speed3" ), ( "scene2_speed1", "scene2_speed2", "scene2_speed3" ), ( "scene3_speed1", "scene3_speed2", "scene3_speed3" ) ]

label sex0:    #whatever label you start with
    $ scene_end = "sex_finish" #the label to where the player will jump to finish the scene
    show screen videoHandler( videoSeries01 ) #using show instead of call so player can interact with dialogue and choices, tried modal true/false but didn't work
label sex_loop: # a fancy loop to test your buttons
    "Text example1"
    "Text example2"
    jump sex_loop # restart of the fancy loop


label sex_finish:
    hide screen videoHandler with dissolve  #here you can chose to hide screen videoHandler with dissolve or do something else
    "here it finishes"
Thanks to anneO'nymous for the help and the original code.
 

osanaiko

Engaged Member
Modder
Jul 4, 2017
3,194
6,115
You don't need those is/else structures for the imasge buttons.

*shamelessly stolen from a le reddit post*

You can disable a button by adding "sensitive False" in the button. (works for imagebutton too)
And instead of using a hardcoded "False", you can have a variable to control it, *OR* have a computable expression such as "speed == 0".
Code:
default speed = 0

screen a_bunch_of_buttons:
    # slow button
    imagebutton:
        --blahblah--
        sensitive speed != 0
        action SetVariable("speed", 0)

    # med button
    imagebutton:
        --blahblah--
        sensitive speed != 1
        action SetVariable("speed", 1)

    # fast button
    imagebutton:
        --blahblah--
        sensitive speed != 2
        action SetVariable("speed", 2)

So, in your case you would add all three speed control buttons to the screen.
Then each button would have a "sensitive" attribute with an expression that evaluates to true or false. And you set the comparison to make the button clickable if it is NOT the current speed.
 
  • Like
Reactions: anne O'nymous

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
12,292
19,664
[...] I say that cuz I found a couple errors from which I could only fix this one.
Yeah, for once I forgot to point the fact that I wrote the code on the fly, based on your own code. Generally the code is good, but time to time I'm too much focused on the original code and there's a type or logical error here or there. Sorry about this.
 

siletris

Newbie
Dec 20, 2022
17
18
You don't need those is/else structures for the imasge buttons.

*shamelessly stolen from a le reddit post*

You can disable a button by adding "sensitive False" in the button. (works for imagebutton too)
And instead of using a hardcoded "False", you can have a variable to control it, *OR* have a computable expression such as "speed == 0".
Code:
default speed = 0

screen a_bunch_of_buttons:
    # slow button
    imagebutton:
        --blahblah--
        sensitive speed != 0
        action SetVariable("speed", 0)

    # med button
    imagebutton:
        --blahblah--
        sensitive speed != 1
        action SetVariable("speed", 1)

    # fast button
    imagebutton:
        --blahblah--
        sensitive speed != 2
        action SetVariable("speed", 2)

So, in your case you would add all three speed control buttons to the screen.
Then each button would have a "sensitive" attribute with an expression that evaluates to true or false. And you set the comparison to make the button clickable if it is NOT the current speed.
I didn't know that, will check it out.
 
  • Like
Reactions: osanaiko