Ren'Py [Solved] Overlay on movies

Porcus Dev

Engaged Member
Game Developer
Oct 12, 2017
2,582
4,689
Hi,

I'm going crazy trying to overlap a countdown to a video with renpy, but I'm starting to think it might not be possible.
I need the help of the experts of this forum :p

The code for the countdown is this:
Code:
init -1 python:

        def countdown(st, at, length=0.0):
            global temps_perdu
            remaining = length - st
   
            if remaining > 5.0:
                return Text("%.1f" % remaining, color="#fff", size=64), .1
            elif remaining > 0.0:
                return Text("%.1f" % remaining, color="#f00", size=64), .1
            else:
                return renpy.jump('temps_perdu')
The code used to display the video is this:
Code:
            window hide
            play movie "movies/video.webm"
            show movie with dissolve
            pause
If I use this code in a "normal" scene, it's shown without problem, but using the video, it doesn't overlap.
Code:
            image countdown = DynamicDisplayable(countdown, length=10.0)
            show countdown

What do you think... is there any way to do it?



Thnaks in advance!
 

9thCrux

--Waifu maker--
Game Developer
Oct 22, 2017
844
3,221
I may be wrong but... wouldn't you need to use something like z-order to specify what is supposed to be on top of what?
 
  • Like
Reactions: Porcus Dev

jon95

Member
Game Developer
Sep 29, 2018
176
392
I'm not sure what you want to exactly do but if it's just overlaying the countdown on a movie you can try this
Code:
    image video = Movie(play="video.webm")
    show video

    image countdown = DynamicDisplayable(countdown, length=10.0)
    show countdown
 
  • Like
Reactions: Porcus Dev

Porcus Dev

Engaged Member
Game Developer
Oct 12, 2017
2,582
4,689
Thank you for the answers!

I may be wrong but... wouldn't you need to use something like z-order to specify what is supposed to be on top of what?
But zorder is for screens only.
I tried to use screens too but it didn't work, although I didn't try it with zorder.
I'll try it, but I doubt it works because of how renpy play videos, according to their official documentation, it's not possible to overlap anything while playing a video... but I know that sometimes there are ways to trick it and do things that were not thought in principle, so I asked the question.

Translated with

I'm not sure what you want to exactly do but if it's just overlaying the countdown on a movie you can try this
Code:
    image video = Movie(play="video.webm")
    show video

    image countdown = DynamicDisplayable(countdown, length=10.0)
    show countdown
I've tried it but it still doesn't work, the countdown shows up for a second and disappears when the video starts playing.
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,302
15,171
Code:
        def countdown(st, at, length=0.0):
            global temps_perdu
[...]
            else:
                return renpy.jump('temps_perdu')
I'm confused here. What are you trying to do with the "global" ? Firstly you don't need it when the Python code is defined in a rpy file. Normally it should be covered in the tutorial thread made by 79flavors here. Secondly it seem that you used it thinking that you made the name of the label available from the function. But the label name is a string, so it will always be available ; Ren'py will retrieve the related label when the time will come.


This said, for your problem you don't need a custom displayable. A simple screen can do exactly the same :
Code:
screen countdown:
    default counter = 10

    timer 1.0:
        repeat True
        action If( counter > 0, SetScreenVariable( 'counter', counter - 1 ), [Hide( 'countown' ), Jump( 'temps_perdu' ) ] )

    add Movie( play="video.webm" )

    text "[counter]":
        xalign 0.5
        yalign 0.0

label start:

    window hide
    show screen countdown
    pause
    hide screen countdown
Starting with this, you can extend the code to make it reusable with all the movies :
Code:
# Arguments are :
# movie  -> File to play as movie
# label  -> Label where to jump at the end of the countdown.
# length -> Duration of the countdown ; this one is optional and at 10 seconds by default.
screen countdown( movie, label, length=10 ):

    # Locally store the duration of the countdown
    default counter = length

    # Then update it every second
    timer 1.0:
        repeat True
        # If there's still time left, just decrease the counter.
        # Else hide the screen and /jump/ somewhere else.
        action If( counter > 0, SetScreenVariable( 'counter', counter - 1 ), [Hide( 'countown' ), Jump( label )] )

    #  Display the movie. Declare the displayable as being a movie
    # here, to avoid tons of declaration somewhere else.
    add Movie( play=movie )

    #  And finally display the counter. Not that this way you can
    # also easilly style it since it's a regular text.
    text "[counter]":
        xalign 0.5
        yalign 0.0

label start:

    window hide
    # Display the countdown screen with the value needed for this time.
    show screen countdown( movie="video.webm", label="temps_perdu", length=10 )
    pause
    # If the movie was stopped by the player, then hide the screen and
    # continue. Else the game will automatically jump to /temps_perdu/.
    hide screen countdown
 
  • Like
Reactions: Porcus Dev

jon95

Member
Game Developer
Sep 29, 2018
176
392
I tried it on a simple game and it worked here is the whole code:

Code:
image black = "#000"
define ca = Character("Camille", color="#af0785")

init python:
    def countdown(st, at, length=0.0):
        remaining = length - st

        if remaining > 5.0:
            return Text("%.1f" % remaining, color="#fff", size=64), .1
        elif remaining > 0.0:
            return Text("%.1f" % remaining, color="#f00", size=64), .1
        else:
            return renpy.jump('temps_perdu')


# The game starts here.

label start:

    ca "Welcome guys!"

    window hide
    image intro_video = Movie(play="intro_video.webm")
    show intro_video with dissolve

    image countdown = DynamicDisplayable(countdown, length=10.0)
    show countdown:
        xalign 0.5
        yalign 0.5    

    $ renpy.pause()


    label temps_perdu:
        scene black
        image thank = Text("Thank you for trying the game and I hope you had fun", style="fs")
        show thank with dissolve
        $ renpy.pause()
        hide thank with dissolve

    # This ends the game.

    return
You can also try the solution of anne O'nymous
 
Last edited:

Porcus Dev

Engaged Member
Game Developer
Oct 12, 2017
2,582
4,689
I'm confused here. What are you trying to do with the "global" ? Firstly you don't need it when the Python code is defined in a rpy file. Normally it should be covered in the tutorial thread made by 79flavors here. Secondly it seem that you used it thinking that you made the name of the label available from the function. But the label name is a string, so it will always be available ; Ren'py will retrieve the related label when the time will come.


This said, for your problem you don't need a custom displayable. A simple screen can do exactly the same :
Code:
screen countdown:
    default counter = 10

    timer 1.0:
        repeat True
        action If( counter > 0, SetScreenVariable( 'counter', counter - 1 ), [Hide( 'countown' ), Jump( 'temps_perdu' ) ] )

    add Movie( play="video.webm" )

    text "[counter]":
        xalign 0.5
        yalign 0.0

label start:

    window hide
    show screen countdown
    pause
    hide screen countdown
Starting with this, you can extend the code to make it reusable with all the movies :
Code:
# Arguments are :
# movie  -> File to play as movie
# label  -> Label where to jump at the end of the countdown.
# length -> Duration of the countdown ; this one is optional and at 10 seconds by default.
screen countdown( movie, label, length=10 ):

    # Locally store the duration of the countdown
    default counter = length

    # Then update it every second
    timer 1.0:
        repeat True
        # If there's still time left, just decrease the counter.
        # Else hide the screen and /jump/ somewhere else.
        action If( counter > 0, SetScreenVariable( 'counter', counter - 1 ), [Hide( 'countown' ), Jump( label )] )

    #  Display the movie. Declare the displayable as being a movie
    # here, to avoid tons of declaration somewhere else.
    add Movie( play=movie )

    #  And finally display the counter. Not that this way you can
    # also easilly style it since it's a regular text.
    text "[counter]":
        xalign 0.5
        yalign 0.0

label start:

    window hide
    # Display the countdown screen with the value needed for this time.
    show screen countdown( movie="video.webm", label="temps_perdu", length=10 )
    pause
    # If the movie was stopped by the player, then hide the screen and
    # continue. Else the game will automatically jump to /temps_perdu/.
    hide screen countdown
I've used your code, works like a charm, and I understand it better :p
As always, thousands of thanks!! :)

I tried it on a simple game and it worked here is the whole code:

Code:
image black = "#000"
define ca = Character("Camille", color="#af0785")

init python:
    def countdown(st, at, length=0.0):
        remaining = length - st

        if remaining > 5.0:
            return Text("%.1f" % remaining, color="#fff", size=64), .1
        elif remaining > 0.0:
            return Text("%.1f" % remaining, color="#f00", size=64), .1
        else:
            return renpy.jump('temps_perdu')


# The game starts here.

label start:

    ca "Welcome guys!"

    window hide
    image intro_video = Movie(play="intro_video.webm")
    show intro_video with dissolve

    image countdown = DynamicDisplayable(countdown, length=10.0)
    show countdown:
        xalign 0.5
        yalign 0.5   

    $ renpy.pause()


    label temps_perdu:
        scene black
        image thank = Text("Thank you for trying the game and I hope you had fun", style="fs")
        show thank with dissolve
        $ renpy.pause()
        hide thank with dissolve

    # This ends the game.

    return
You can also try the solution of anne O'nymous
Yes, I think, although I'm not sure, that the problem was the order of the lines only, first appeared the countdown and then the video, when it should be the other way around.
Sometimes something is so "simple" that I don't see... also today I have a very stressed day reviewing the last details for the publication of the new version and I have the head that spins me at the speed of light o_O:LOL:

Thanks a lot!




BTW, anne O'nymous, I used the help system (quest) that you told me, but I still have to check the programming in after_load (fingers crossed, hahaha).
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,302
15,171
Just a thing :

Code:
label start:
[...]
    image intro_video = Movie(play="intro_video.webm")
[...]
    image countdown = DynamicDisplayable(countdown, length=10.0)
[...]
    label temps_perdu:
[...]
        image thank = Text("Thank you for trying the game and I hope you had fun", style="fs")
[...]
While this works, it don't do what it seem since the image statement is at init level. This mean that whatever the place where you put it and the level of indentation, it will always be interpreted during the init phase.
Therefore, the following example will works fine and display the image. This even if the code seem to tell us that the image can never be defined.
Code:
label start:
   show myImage
   "END"
label myLabel:
   return
   label .subLabel:
      while True == False:
          if True == False:
             image myImage = "itsMagic.png"

BTW, anne O'nymous, I used the help system (quest) that you told me, but I still have to check the programming in after_load (fingers crossed, hahaha).
It's not really difficult. It's more a question of habit that anything else.
 
  • Like
Reactions: jon95