Ren'Py Best way to show images

mr.moonmi

Newbie
Game Developer
Jun 21, 2020
52
1,347
Hi.
My question is what is the best way to show images in Renpy?
I tried to show my renders with simple:
Code:
scene image01
    mc "Text 1"
scene image02
    mc "Text 2"
This is the code I've seen in the most other games. But in my case text box disappearing and reappearing after the scene is changing. This is how the scene works as I understand. Clears everything. But why then the same code works fine in other games? Without text box flashing after changing a scene.

Another option I've tried was this:
Code:
image  image01 = "image01"
image  image02 = "image02"

scene image01
mc "text 01"
show image02
mc "text 02"
So the Renpy shows the scene with image 01 and then loads the next image on top of it. In this case the dialogue box doesn't disappear but as I understand it keeps everything in memory until I declare a new scene. Which is not good if I have a scene with 20+ renders, right?

So what is the best way to show images without dialogue box disappearing and reappearing and to keep memory light?
Thank you for help.
 

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,581
2,219
[...] in my case text box disappearing and reappearing after the scene is changing. This is how the scene works as I understand. Clears everything. But why then the same code works fine in other games? Without text box flashing after changing a scene.

As you say, it's just how scene works. And yes, it's happening in all those other games too.
The difference I suspect is that you've noticed it in your game and not noticed it in others. A bit like that cobweb in the corner of your room... it's probably been there for months, but now you've seen it... you'll be looking at it at least once a night.
The other thing is that you have one image followed by one line of text. With more dialogue (which is what all those other games have), it'll be less noticable.

I personally would also add with fade when moving between locations and with dissolve when changing images within the same location. But neither affect the thing you're describing.

So the Renpy shows the scene with image 01 and then loads the next image on top of it. In this case the dialogue box doesn't disappear but as I understand it keeps everything in memory until I declare a new scene. Which is not good if I have a scene with 20+ renders, right?

Yes, it can cause issues if you code it like that.


Firstly though... You don't need to declare the images explicitly like that.

As part of it's start up processing (or maybe it's during the build process), RenPy scans the /images/ folder and creates image statements automatically for every valid image it finds there and any sub directories.

The only kink is that the generated image displayables are named in lowercase. (So it's generally a good idea for files to be also named all in lowercase for your sanity).

/images/image01.png -> image image01 = "image01.png"
/images/faces/image99.png -> image image99 = "/faces/image01.png"
/images/DUMB01.png -> image dumb01 = "DUMB01.png"

/images/this_file_01.jpg -> image this_file_01 = "this_file_01.jpg"
/images/this file 01.jpg -> image this file 01 = "this file 01.jpg" (note the spaces in the filename).

This behavior is configurable, but I'll come back to that later.

Anyway, my point is that you rarely need to write your own image statements.


Back on topic...
First the hard way...

Python:
label start:
    scene black with fade             # black background when no other image is shown over it.
                                      # not strictly needed, you could do scene image01

    show image01 with fade
    mc "text 01"

    show image02 with dissolve
    hide image01
    mc "test 02"

    # effectively hiding the previous image by name each time a new one is shown. Memory issues... solved. Typing nightmare begins.

I hope you can see how painful that will become very quickly.

However, the way RenPy was original designed was to use full screen (background) images with foreground (character) sprites overlaid on top.

For this reason, RenPy has an image tagging system. Each displayable is tagged with the first part of it's image id preceding any spaces.

Now in most recent RenPy AVN games, there aren't any spaces in the image identifiers. (Mainly because they aren't using the sprite system).
So... image this_file_01 = "/images/this_file_01.jpg" would be tagged as "this_file_01".

However, if your image statements include spaces - things change.
image this file 01 = "this file 01.jpg" would be tagged as "this" only.

The critical part of this is that only one displayable tag can be displayed on screen at any time. Any previous ones are removed.

The way this is designed is for things like this:

Python:
define e = Character("Eileen", color="#04B486")

image eileen neutral = "eileen_neutral.png"
image eileen smiling = "eileen_smiling.png"
image eileen sad = "eileen_sad.png"

image bg myroom01 = "bg_myroom01.jpg"
image bg myroom02 = "bg_myroom02.jpg"


label start:

    scene bg myroom01 with fade

    show eileen neutral with dissolve
    e "Hi, my name is [e]."

    show eileen smiling at left with dissolve
    e "Today I'm happy."

    show eileen sad at right with dissolve
    e "Tomorrow I might be sad."

    scene bg myroom01 with dissolve
    "Some more dialogue."
    "Whatever."

    "*** THE END***"
    return

In this case, each image tagged eileen automatically removes the previous eileen tagged displayable.
Then the scene statement means not having to remove that final eileen sad image.

Note that I've had to add the image statements manually, because the tagging system needs those spaces, but my imaginary filenames use underscores (which is pretty common).

Now think beyond just eileen. The same system would work for the background images tagged as bg.
As long as the first element (the tag) is unique, only one can be displayed at once.
So...

show bg myroom01 followed later by show bg myroom02 would replace one bg displayable with another.

Doing so would avoid the problem of the dialogue box fading out and in again. However, you might now need to add a hide eileen with dissolve to hide the "eileen sad" image, since there would no longer be a scene statement to do it.

Now... you're probably thinking about renaming your image files to use spaces rather than underscores. That way, you don't need to manually add all those extra image statements. It's a pain in the arse. Better to stick to underscores, which is what applications like Daz3D will want to use anyway.

RenPy already has you covered.

Add these lines into your options.rpy file...

define config.automatic_images = [' ','_','-','/']
define config.automatic_images_strip = [ 'images' ]


This will strip any of those characters out of the filename and create an image statement using the removed characters as separators for the tagging system.
Because of the "/" in the list, that also means any subdirectory names are also processed too.
The second line is needed to avoid the generated defintions being things like images eileen smiling rather than just eileen smiling.

Depending on how you structure your folders, you might even want to do things like:
define config.automatic_images_strip = [ 'images', 'characters"' ]

You can make use of this by picking directory names to aid the tagging system.

/images/bg/myroom01.jpg -> image bg myroom01 = "/bg/myroom01.jpg"
/images/bg/myroom02.jpg -> image bg myroom02 = "/bg/myroom01.jpg"
/images/eileen/smiling.png -> image eileen smiling = "/eileen/smiling.png"
/images/eileen/neutral.png -> image eileen neutral = "/eileen/neutral.png"
/images/eileen/sad.png -> image eileen sad = "/eileen/sad.png"

All of which is a very long way to say that if you name your files correctly and use that options override, you can use show rather than scene without running into those potential memory issues in order to not have the dialogue box disappear and reappear.

All that explained... honestly, I'd stick to using scene statements like every other game. Most RenPy devs know nothing of this displayable tagging system - and they just do things like scene myroom2 with fade without all that tagging. Which is fine, because most of them aren't using foreground sprites any more either.

Edit: The "best" way is to use scene. The rest of the post is just explaining a way to do it how you want. It really isn't as complicated as it sounds to implement - but it's fixing a problem almost everyone thinks is normal behavior. So take the path of least resistance and keep things simple.
 
Last edited:

Penfold Mole

Engaged Member
Respected User
May 22, 2017
2,989
6,994
Are you sure you need or want to have that box at all?
What if you have text without the box, creating high contrast between the letters and background image by using outlines and a shadow instead of a large opaque or semi-transparent box?

Python:
init:
# color and outlines for dialog text
    style say_dialogue:
        color "#FFFFFF"
        outlines [ (2, "#000", 1, 1) ]

# outlines for the name box (you can set individual colors in the Character() statement)
    style say_label:
        outlines [ (2, "#000", 1, 1) ]

# removing dialog text background
    style window:
        background None

# color and outlines for input prompt
    style input_prompt:
        color "#FFFFFF"       
        outlines [ (2, "#000", 1, 1) ]

# color and outlines for input text
    style input:
        color "#FFFFFF"
        outlines [ (2, "#000", 1, 1) ]
Flickering box problem solved.
Give it a try ;)
 
  • Like
Reactions: Ludvinae

Playstorepers

Member
May 24, 2020
160
79
if you use:

window show

you're gonna force the box to appear even during a scene command, which is what you want, right?

and window auto is the default choice, which you can configure on your own:

define config.window_auto_hide = [ 'scene', 'call screen', 'menu']
define config.window_auto_show = [ 'say', 'menu-with-caption', 'show' ]

for example
 
  • Like
Reactions: 79flavors

mr.moonmi

Newbie
Game Developer
Jun 21, 2020
52
1,347
As you say, it's just how scene works. And yes, it's happening in all those other games too.
The difference I suspect is that you've noticed it in your game and not noticed it in others. A bit like that cobweb in the corner of your room... it's probably been there for months, but now you've seen it... you'll be looking at it at least once a night.
The other thing is that you have one image followed by one line of text. With more dialogue (which is what all those other games have), it'll be less noticable.

I personally would also add with fade when moving between locations and with dissolve when changing images within the same location. But neither affect the thing you're describing.




Yes, it can cause issues if you code it like that.


Firstly though... You don't need to declare the images explicitly like that.

As part of it's start up processing (or maybe it's during the build process), RenPy scans the /images/ folder and creates image statements automatically for every valid image it finds there and any sub directories.

The only kink is that the generated image displayables are named in lowercase. (So it's generally a good idea for files to be also named all in lowercase for your sanity).

/images/image01.png -> image image01 = "image01.png"
/images/faces/image99.png -> image image99 = "/faces/image01.png"
/images/DUMB01.png -> image dumb01 = "DUMB01.png"

/images/this_file_01.jpg -> image this_file_01 = "this_file_01.jpg"
/images/this file 01.jpg -> image this file 01 = "this file 01.jpg" (note the spaces in the filename).

This behavior is configurable, but I'll come back to that later.

Anyway, my point is that you rarely need to write your own image statements.


Back on topic...
First the hard way...

Python:
label start:
    scene black with fade             # black background when no other image is shown over it.
                                      # not strictly needed, you could do scene image01

    show image01 with fade
    mc "text 01"

    show image02 with dissolve
    hide image01
    mc "test 02"

    # effectively hiding the previous image by name each time a new one is shown. Memory issues... solved. Typing nightmare begins.

I hope you can see how painful that will become very quickly.

However, the way RenPy was original designed was to use full screen (background) images with foreground (character) sprites overlaid on top.

For this reason, RenPy has an image tagging system. Each displayable is tagged with the first part of it's image id preceding any spaces.

Now in most recent RenPy AVN games, there aren't any spaces in the image identifiers. (Mainly because they aren't using the sprite system).
So... image this_file_01 = "/images/this_file_01.jpg" would be tagged as "this_file_01".

However, if your image statements include spaces - things change.
image this file 01 = "this file 01.jpg" would be tagged as "this" only.

The critical part of this is that only one displayable tag can be displayed on screen at any time. Any previous ones are removed.

The way this is designed is for things like this:

Python:
define e = Character("Eileen", color="#04B486")

image eileen neutral = "eileen_neutral.png"
image eileen smiling = "eileen_smiling.png"
image eileen sad = "eileen_sad.png"

image bg myroom01 = "bg_myroom01.jpg"
image bg myroom02 = "bg_myroom02.jpg"


label start:

    scene bg myroom01 with fade

    show eileen neutral with dissolve
    e "Hi, my name is [e]."

    show eileen smiling at left with dissolve
    e "Today I'm happy."

    show eileen sad at right with dissolve
    e "Tomorrow I might be sad."

    scene bg myroom01 with dissolve
    "Some more dialogue."
    "Whatever."

    "*** THE END***"
    return

In this case, each image tagged eileen automatically removes the previous eileen tagged displayable.
Then the scene statement means not having to remove that final eileen sad image.

Note that I've had to add the image statements manually, because the tagging system needs those spaces, but my imaginary filenames use underscores (which is pretty common).

Now think beyond just eileen. The same system would work for the background images tagged as bg.
As long as the first element (the tag) is unique, only one can be displayed at once.
So...

show bg myroom01 followed later by show bg myroom02 would replace one bg displayable with another.

Doing so would avoid the problem of the dialogue box fading out and in again. However, you might now need to add a hide eileen with dissolve to hide the "eileen sad" image, since there would no longer be a scene statement to do it.

Now... you're probably thinking about renaming your image files to use spaces rather than underscores. That way, you don't need to manually add all those extra image statements. It's a pain in the arse. Better to stick to underscores, which is what applications like Daz3D will want to use anyway.

RenPy already has you covered.

Add this line into your options.rpy file...

define config.automatic_images = [' ','_','-','/']

This will strip any of those characters out of the filename and create an image statement using the removed characters as separators for the tagging system.
Because of the "/" in the list, that also means any subdirectory names are also processed too.

You can make use of this by picking directory names to aid the tagging system.

/images/bg/myroom01.jpg -> image bg myroom01 = "/bg/myroom01.jpg"
/images/bg/myroom02.jpg -> image bg myroom02 = "/bg/myroom01.jpg"
/images/eileen/smiling.png -> image eileen smiling = "/eileen/smiling.png"
/images/eileen/neutral.png -> image eileen neutral = "/eileen/neutral.png"
/images/eileen/sad.png -> image eileen sad = "/eileen/sad.png"

All of which is a very long way to say that if you name your files correctly and use that options override, you can use show rather than scene without running into those potential memory issues in order to not have the dialogue box disappear and reappear.

All that explained... honestly, I'd stick to using scene statements like every other game. Most RenPy devs know nothing of this displayable tagging system - and they just do things like scene myroom2 with fade without all that tagging. Which is fine, because most of them aren't using foreground sprites any more either.

Edit: The "best" way is to use [icode]scene[/icode]. The rest of the post is just explaining a way to do it how you want. It really isn't as complicated as it sounds to implement - but it's fixing a problem almost everyone thinks is normal behavior. So take the path of least resistance and keep things simple.
Thank you for your answer!
So yeah, the best way for me is to use "scene" and to play with "window" config.
 

mr.moonmi

Newbie
Game Developer
Jun 21, 2020
52
1,347
Are you sure you need or want to have that box at all?
What if you have text without the box, creating high contrast between the letters and background image by using outlines and a shadow instead of a large opaque or semi-transparent box?

Python:
init:
# color and outlines for dialog text
    style say_dialogue:
        color "#FFFFFF"
        outlines [ (2, "#000", 1, 1) ]

# outlines for the name box (you can set individual colors in the Character() statement)
    style say_label:
        outlines [ (2, "#000", 1, 1) ]

# removing dialog text background
    style window:
        background None

# color and outlines for input prompt
    style input_prompt:
        color "#FFFFFF"      
        outlines [ (2, "#000", 1, 1) ]

# color and outlines for input text
    style input:
        color "#FFFFFF"
        outlines [ (2, "#000", 1, 1) ]
Flickering box problem solved.
Give it a try ;)
Yes, I've thought about that. I want to test different options first. Thank you.
 

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,581
2,219
define config.window_auto_hide = [ 'scene', 'call screen', 'menu']
define config.window_auto_show = [ 'say', 'menu-with-caption', 'show' ]

That's a new one on me. So good call.

And now I'm wondering if simply using scene and removing "scene" from the auto_hide list and adding it to the auto_show list instead would be a solution.

I can imagine there might be some unintended consequences, so I'd need to play through a full (semi complex) game with it set like that to see if something goes pear shaped. But I'm thinking perhaps this...

Python:
define config.window_auto_hide = [ 'call screen', 'menu']
define config.window_auto_show = [ 'say', 'menu-with-caption', 'scene' ]

Then use scene as normal. With maybe manually added window hide and window show statements before and after anywhere that doesn't feel right. The only thing that is coming to mind right now is that fullscreen animations displayed with a timed pause will be shown with the dialogue box at the bottom of the screen. Perhaps that is a price worth paying.

A solution to this theoretical problem would be to not add "scene" to the auto_show list, but instead manually do window show after any call screen code. Bahh... but now I see menu: in the mix too... Nope... I'm back to plan-A... Use scene and accept the box disappearing and reappearing just like it does in practically every other game.
 

Penfold Mole

Engaged Member
Respected User
May 22, 2017
2,989
6,994
And in the options.rpy there are default transitions for the text box:

Python:
## Transitions used to show and hide the dialogue window

define config.window_show_transition = Dissolve(.2)
define config.window_hide_transition = Dissolve(.2)
In case you are missing these, the flicker may not be as smooth as it normally should be. And you can increase the time of dissolve to make it smoother.

Personally I hate it when an image is covered up by a text box, any kind of box. I'm used to subtitles on TV and there is no background there, so I prefer a game to have a similar setup that can be achieved by using the configuration in my previous post.
You can adjust the thickness of the outlines by changing the first parameter and the thickness and direction of the shadow by changing shifting coordinates of the outline (the third and fourth parameter). The color is obviously determined by the second one.
 
Last edited:

Playstorepers

Member
May 24, 2020
160
79
That's a new one on me. So good call.

And now I'm wondering if simply using scene and removing "scene" from the auto_hide list and adding it to the auto_show list instead would be a solution.

I can imagine there might be some unintended consequences, so I'd need to play through a full (semi complex) game with it set like that to see if something goes pear shaped. But I'm thinking perhaps this...

Python:
define config.window_auto_hide = [ 'call screen', 'menu']
define config.window_auto_show = [ 'say', 'menu-with-caption', 'scene' ]

Then use scene as normal. With maybe manually added window hide and window show statements before and after anywhere that doesn't feel right. The only thing that is coming to mind right now is that fullscreen animations displayed with a timed pause will be shown with the dialogue box at the bottom of the screen. Perhaps that is a price worth paying.

A solution to this theoretical problem would be to not add "scene" to the auto_show list, but instead manually do window show after any call screen code. Bahh... but now I see menu: in the mix too... Nope... I'm back to plan-A... Use scene and accept the box disappearing and reappearing just like it does in practically every other game.
The implementation, I chose was

define config.window_auto_hide = [ 'call screen', 'menu']
define config.window_auto_show = [ 'say', 'menu-with-caption', 'scene' ]

and then, when I want something deviating from this pattern:
window hide/window show (depending on what I want)
action (screen, scene, etc.)
window auto

Works for me, at least, but maybe I misunderstood your problem, OP.
 
  • Like
Reactions: 79flavors

palumbra

Member
Nov 20, 2019
185
474
there is a way for not repeat 1000 times

Python:
show img behind t with dissolve
hide prev_img
with a function:
Code:
python:
    showme(img)
        show img behind t with dissolve
        if prev_img != "":
            hide prev_img_stored
        prev_img_stored = img
then call with
Code:
prev_img = ""


....



image a1 = "black.jpg"
image a2 = "white.jpg"


....

$ showme(a1)

"blablabla"


$ showme(a2)
i tried in many different way, but no way
 
Last edited:

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,369
15,285
there is a way for not repeat 1000 times

Python:
show img behind t with dissolve
hide prev_img
Yes there's a way, and you aren't really far to the solution, just missing an important point : Ren'py script language is not the same thing than Python language.

Therefore, your :
Code:
python:
    showme(img)
        show img behind t with dissolve
        if prev_img != "":
            hide prev_img_stored
        prev_img_stored = img
Have no way to works. Firstly because it's not how you define a function in Python, secondly because both show and hide aren't Python instructions.
What you're looking for are the "Python equivalent" ; Python function doing the same thing than Ren'py statements. More precisely, and .


This being said, this approach will only works if you show only one image at the time. What imply that showing the image is probably not what you should do here. As previously said, it should be used only when you display a sprite on top of a background, or in top of a constructed image. if your image isn't a sprite, and so take the whole screen, it's that should be used.
 

palumbra

Member
Nov 20, 2019
185
474
anne O'nymous
tnx for the reply.

I tried but no luck:


Python:
init python:

    def showme(img):
        renpy.show(img,behind=t)
        if prev_img != "":
            renpy.hide(prev_img_stored)
        prev_img_stored = img
then

Python:
define prev_img_stored = ""


label start:

    image a1 = "black.jpg"
    image a2 = "white.jpg"
   
    $ showme(a1)
Immagine 2021-03-16 085426.jpg

name a1 is not defined, very frustrating... lol


Why show and not scene?

Scene with 1080p videos like:

image bar_2-1 = Movie(play="bar2/1.webm", loop=True, size=(1920,1080))
image bar_2-2 = Movie(play="bar2/2.webm", loop=True, size=(1920,1080))
image bar_2-3= ........


not so good,
flash of trasparent background in the transitions,
in skip mode (with 10 video) very evident .

Show/hide work much better.
 
Last edited:

Playstorepers

Member
May 24, 2020
160
79
anne O'nymous
tnx for the reply.

I tried but no luck:


Python:
init python:

    def showme(img):
        renpy.show(img,behind=t)
        if prev_img != "":
            renpy.hide(prev_img_stored)
        prev_img_stored = img
then

Python:
define prev_img_stored = ""


label start:

    image a1 = "black.jpg"
    image a2 = "white.jpg"
  
    $ showme(a1)
View attachment 1086798

name a1 is not defined, very frustrating... lol


Why show and not scene?

Scene with 1080p videos like:

image bar_2-1 = Movie(play="bar2/1.webm", loop=True, size=(1920,1080))
image bar_2-2 = Movie(play="bar2/2.webm", loop=True, size=(1920,1080))
image bar_2-3= ........


not so good,
flash of trasparent background in the transitions,
in skip mode (with 10 video) very evident .

Show/hide work much better.

I'm not an expert, so I can't tell you why you should pick scene over show (I do it, at least), but from my understanding scene wipes everything, which is a catch-all measure, but that's just my speculation.

And your thing probably doesn't work because:
$ showme(a1)
should be
$ showme("a1")
 

palumbra

Member
Nov 20, 2019
185
474
And your thing probably doesn't work because:
$ showme(a1)
should be
$ showme("a1")
yes thanks (and its so strange, in python a1 is an obj, and "a1" a string)

now

Python:
init python:
   
    def showme(img,prev):
        #img behind t with dissolve
        renpy.show(img,behind="t")
        renpy.with_statement(Dissolve(0.5))
        if prev != "":
            renpy.hide(prev)
        prev = img
        return prev

then

Python:
define prev = ""


label start:

   
   
    image a1 = "black.jpg"
    image a2 = "white.jpg"
   
    $ prev = showme("a1", "prev")
   
    pause
   
    $ prev = showme("a2", "prev")
works as expected

Tnx for the helps
;)
 
Last edited:

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,581
2,219
[...] so I can't tell you why you should pick scene over show (I do it, at least)

The thread originally started because the OP had noticed that when you use scene, there is a brief moment where the text box at the bottom of the screen is hidden to show the full screen image before reappearing to show the dialogue the mc or other characters are speaking/thinking.

Their example was 1 image + 1 line of dialogue repeated 4 or 5 times, making it slight more "in your face". My guess is that despite the fact that practically every other game does exactly the same thing, because it was their own game - they'd noticed it. And having noticed it, they couldn't not see it every time it happened.

Using show avoids that brief disappearance of the text box, because (in this case) only the background image is being swapped out.

But, if you only use show each image is overlaid over the previous image, effectively hiding it. But because RenPy needs to keep track of everything on screen, each new image takes up additional resources. In some recent examples, at least one dev had their game crash on Android because the device ran out of memory trying to keep track of the literal hundreds of images being on screen at one time (despite the fact the player can only see the most recent one). It think it also caused saved file issues too, if memory serves.

The workaround is to hide the previous image after showing the new one. RenPy then only has to keep track of 2 full screen images at any given point, and never accumulates so much data that the game crashes. RenPy can do this automatically, but you need to use a very specific naming style - which most devs are not aware of.

The thing is... now you're having to use two commands rather than just one for each image. And if you misalign the statements, get them out of order or make a simple typo... it's more prone to fuckup. Plus it's twice the work for the developer. All for the sake of a transition effect that every other RenPy game does anyway and everyone is already used to. Basically it's a lot of effort to fix a "problem" that is really just "working as intended".
 
  • Like
Reactions: Playstorepers

palumbra

Member
Nov 20, 2019
185
474
The thing is... now you're having to use two commands rather than just one for each image. And if you misalign the statements, get them out of order or make a simple typo... it's more prone to fuckup. Plus it's twice the work for the developer. All for the sake of a transition effect that every other RenPy game does anyway and everyone is already used to. Basically it's a lot of effort to fix a "problem" that is really just "working as intended".
$ prev = showme("a2", "prev")
is one command only. and keep track of the image show

The power of a language is to build own functions to semplify repeat and teadious stuff.
and i repeat scene work fine with images, but some problems with a sequence of 1080 videos.
show in this case work better.

I fix a problem i see, if u dont see, dont need to fix
;)
 

palumbra

Member
Nov 20, 2019
185
474
you can also add a set of transitions

Python:
init python:


    def showme2(img,prev,trans):
        #img behind t with dissolve
        renpy.show(img,behind="t")
        if trans == "":
            renpy.with_statement(Dissolve(0.5))
        elif trans == "cut":
            pass
        elif trans == "slow":
            renpy.with_statement(Dissolve(1.5))
        elif trans == "right":
            renpy.with_statement(PushMove(1.0, "pushright"))
        elif trans == "left":
            renpy.with_statement(PushMove(1.0, "pushleft"))
        
        if prev != "":
            renpy.hide(prev)
        prev = img
        return prev
and use with


Python:
$ prev = showme2("a2", "prev", "right")

# or
$ prev = showme2("a2", "prev", "left")

# or
$ prev = showme2("a2", "prev", "")

# or
$ prev = showme2("a2", "prev", "slow")

# or
$ prev = showme2("a2", "prev", "cut")
 

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,581
2,219
Also... a slight clarification of this latest suggestion...

Python:
init python:

    def showme(img):
        renpy.show(img, behind="t")
        renpy.with_statement(Dissolve(0.5))
        if store.previmg is not None:
            renpy.hide(store.previmg)
        store.previmg = img


default previmg = None

The version slightly higher in this thread wasn't working because it was using a local variable. The workaround of parsing the image name back and then passing it again does work, but is a bit cumbersome. But storing the image name as part of the function was always an option, you just needed a global variable instead.

I'm not familiar with the behind="t" but copied it because... well, why not.