Need function/transformation to fade between two sprites

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
generalzoi
Newbie
Posts: 5
Joined: Tue Jun 09, 2015 10:31 pm
Contact:

Need function/transformation to fade between two sprites

#1 Post by generalzoi »

I'm trying to learn my way around Ren'py. For some reason, although I'm proficient in Python, I find it a difficult language to use. I'm working on a VN game, and the plan is for character sprites to dissolve in and out as the speaker changes. So I figured the easiest thing to do would be to write a function where I could give it the two sprites I want to swap and the screen position they should appear in, and have that do the fading. But I can't figure out how to do actual Ren'py image manipulation in a Python function.

Or am I approaching it wrong? Should I be using a transformation? I see that I can give a transformation parameters, but I don't know how to them apply that transformation to an image. For example, how do I write a fade in transformation that will take as a parameter the position on screen where the sprite should be when it appears, and apply that to arbitrary images?

Basically I'm getting very tired of writing:

Code: Select all

hide A
show B at right
with Dissolve(0.3)
...
hide B
show A at right
with Dissolve(0.3)
...
and on and on and on. There has to be a better way to do it.

philat
Eileen-Class Veteran
Posts: 1912
Joined: Wed Dec 04, 2013 12:33 pm
Contact:

Re: Need function/transformation to fade between two sprites

#2 Post by philat »

You may want to look into side images. http://www.renpy.org/doc/html/side_image.html

generalzoi
Newbie
Posts: 5
Joined: Tue Jun 09, 2015 10:31 pm
Contact:

Re: Need function/transformation to fade between two sprites

#3 Post by generalzoi »

That page raises more questions than it answers. It doesn't actually explain what side images are, and how they're different than any other kind of images. What's the difference between "image eileen happy" and "image side eileen happy"? Is it saying that when you call "eileen happy", it'll show "side eileen happy"? If so, what's the point of declaring "eileen happy" at all? Does the image literally appear on the side of the screen, and that's the only difference between the two? The page doesn't really explain anything, which is my big problem with all Ren'py documentation.

I have characters declared. Here's an example of what my code looks like now:

Code: Select all

show tom tired at left
show joan smiling at right
joan "Hi!"

hide joan
show bob angry at right
with Dissolve(0.3.)
bob "You're late."

hide bob
show joan stern at right
with Dissolve(0.3)
joan "Hey now, he's had a hard time."

hide joan
show bob frowning at right
with Dissolve(0.3)
bob "Well, let's get started."
Which is just redundant and annoying to write. What I'd like is something like this:

Code: Select all

show tom tired at left
show joan smiling at right
joan "Hi!"

swap_sprites('joan', 'bob angry', 'right')
bob "You're late."

swap_sprites('bob', 'joan stern', 'right')
joan "Hey now, he's had a hard time."

swap_sprites('joan', 'bob frowning', 'right')
bob "Well, let's get started."
where swap_sprites will do the actual show/hide/dissolve, and I can give it any two sprites to swap and any screen position they should appear in so it's reusable. Maybe a Python function isn't the way to do that or it'll looks slightly different, but there has to be a way to introduce some reusability since the same things are happening over and over.

philat
Eileen-Class Veteran
Posts: 1912
Joined: Wed Dec 04, 2013 12:33 pm
Contact:

Re: Need function/transformation to fade between two sprites

#4 Post by philat »

Well, the point is that with side images you can write

joan smiling "Hi!"
bob angry "You're late"

And it will show the images automatically... But hey, if you don't want to bother, you don't want to bother. *shrug*

In any case, you can easily define your own function to do what you want, you just need to use the python equivalents of statements. http://www.renpy.org/doc/html/statement ... ing-images

Code: Select all

init python:
    def swapsprites(old, new, position):
        renpy.hide(old)
        renpy.show(new, at_list=[position])
        renpy.with_statement(Dissolve(0.3))

image white = Solid("FFF", xysize=(50,50))
image red = Solid("F00", xysize=(50,50))

label start:

    show white at truecenter

    "blah"
    $ swapsprites("white", "red", truecenter)

    "blah"

    $ swapsprites("red", "white", right)

    "blah"

generalzoi
Newbie
Posts: 5
Joined: Tue Jun 09, 2015 10:31 pm
Contact:

Re: Need function/transformation to fade between two sprites

#5 Post by generalzoi »

It's not that I don't want to bother. I just find the Ren'py documentation confusing because there always seems to be some details I'm missing. For example, the page you linked only says that Ren'py "has support for automatically selecting and displaying a side image as part of the dialogue" and nothing about automatically hiding images for other characters, so I wasn't sure how it would be useful for this situation. Like, I know that if I do

Code: Select all

joan happy "Hey."
joan frowning "Are you okay?"
it will automatically swap out joan's sprites. But if I have bob on screen, and want to hide him when I show joan, just writing "joan happy" won't do that, correct? I tested something like that out, and if I recall correctly all it did was make joan's sprite show up on top of bob's. I had to explicitly hide bob to make him go away. But then, I wasn't using side images, just regular images.

Your example function looks very helpful, and I'll definitely play around with it when I get home. But if I am leading myself in a more difficult direction than I need to, then please let me know. I want to try and understand how Ren'py works and not force myself to stick to pure Python functions just because that's what I'm familiar with.

Kinsman
Regular
Posts: 130
Joined: Sun Jul 26, 2009 7:07 pm
Location: Fredericton, NB, Canada
Contact:

Re: Need function/transformation to fade between two sprites

#6 Post by Kinsman »

The key behind side images is that they use image tagging. In Ren'Py, you can give a tag to an image, and any image you give with the same tag replaces the old image.

The 'as' clause in the show statement is useful for retagging an image:

Code: Select all

show bill at left as leftchar
show dave as leftchar with Dissolve(0.3)
# Dave will replace Bill, since they share tags.
The side images system in Ren'Py is a pre-written feature that takes advantage of the engine's image tagging. But you can use image tagging by itself, in a simpler way.

You could use the above script as an example, but it's still a little tedious to write the transition each time. I know that PyTom recently added 'tag_layer' and 'tag_transform' to the configuration variables, letting you define automatic layers and/or transforms for certain image tags; maybe 'tag_transition' would be a good addition in the future.

Another, more advanced thing you can do is use 'config.show', and create a Python function that can intercept and/or filter the show statement. Here, how about something like this:

Code: Select all

init python:
    def filter_show(name,at_list,layer,what,zorder,tag,behind,atl):
        if left in at_list:
            tag = "leftchar"
        if right in at_list:
            tag = "rightchar"
        renpy.show(name,at_list,layer,what,zorder,tag,behind,atl)
        if (tag == "leftchar" or tag == "rightchar"):
            renpy.with_statement(dissolve)
        
    config.show = filter_show

Code: Select all

# Anything 'at left' or 'at right' will replace the previous image there, and do a transition
show bill at left
bill "Hello."
show dave at right
dave "Hello, Bill. Oh, I see you brought Sarah."
show sarah at left
sarah "Hi, Dave!"

EDIT: There are some limitations to what I wrote - any image put on the left or right will be named 'leftchar' or 'rightchar', so if you wanted to use say attributes in your dialogue, it wouldn't work.
Here's an alternate method:

Code: Select all

init python:
    
    recent_left = ("no image")
    recent_right = ("no image")
    
    def filter_show(name,at_list,layer,what,zorder,tag,behind,atl):
        global recent_left,recent_right
        if left in at_list:
            renpy.hide(recent_left)
            recent_left = name
        if right in at_list:
            renpy.hide(recent_right)
            recent_right = name
        renpy.show(name,at_list,layer,what,zorder,tag,behind,atl)
        if left in at_list or right in at_list:
            renpy.with_statement(dissolve)
        
    config.show = filter_show

    # Set a transition for changes made in dialogue
    config.say_attribute_transition = dissolve

Code: Select all

show bill at left
bill "Hello everyone."
bill happy "It is good to see you all."
show dave at right
dave "Welcome, Bill. Oh, hello Sarah."
show sarah at left
sarah "Hello!"
Last edited by Kinsman on Tue Jan 12, 2016 1:19 pm, edited 1 time in total.
Flash To Ren'Py Exporter
See the Cookbook thread

User avatar
Winterslice
Veteran
Posts: 230
Joined: Mon Sep 28, 2015 3:51 am
Completed: The Next World, Golem Creation Kit
Organization: Illuminated Games
Contact:

Re: Need function/transformation to fade between two sprites

#7 Post by Winterslice »

generalzoi wrote:I'm trying to learn my way around Ren'py. For some reason, although I'm proficient in Python, I find it a difficult language to use. I'm working on a VN game, and the plan is for character sprites to dissolve in and out as the speaker changes. So I figured the easiest thing to do would be to write a function where I could give it the two sprites I want to swap and the screen position they should appear in, and have that do the fading. But I can't figure out how to do actual Ren'py image manipulation in a Python function.

Or am I approaching it wrong? Should I be using a transformation? I see that I can give a transformation parameters, but I don't know how to them apply that transformation to an image. For example, how do I write a fade in transformation that will take as a parameter the position on screen where the sprite should be when it appears, and apply that to arbitrary images?
You can pass variable arguments to a transform by, for example, doing the following:

Code: Select all

transform example(argument1, argument2):
     xalign argument1
     yalign argument2
These will be automatically applied to whatever displayable you're using the at statement on. Like so:

Code: Select all

label start:
     show A at example(0.5, 1.0)
If you want to add fadein/out properties, you can add more args to the transform:

Code: Select all

transform example(argument1, argument2, time, opacity):
     xalign argument1
     yalign argument2
     linear time alpha opacity

label start:
     show A at example(0.5, 1.0, 0.8, 0.0)
     show B at example(0.5, 1.0, 0.8, 1.0)
In this case, A will become totally transparent (but not hidden) in 0.8 seconds while B will become completely opaque.

User avatar
Winterslice
Veteran
Posts: 230
Joined: Mon Sep 28, 2015 3:51 am
Completed: The Next World, Golem Creation Kit
Organization: Illuminated Games
Contact:

Re: Need function/transformation to fade between two sprites

#8 Post by Winterslice »

Ah, I forgot one thing in that last bit of code. You'd probably want to specify the beginning opacity level as well as the target opacity level. So, with one more arg:

Code: Select all

transform example(argument1, argument2, time, startopacity, endopacity):
     xalign argument1
     yalign argument2
     alpha startopacity
     linear time alpha endopacity

label start:
     show A at example(0.5, 1.0, 0.8, 1.0, 0.0)
     show B at example(0.5, 1.0, 0.8, 0.0, 1.0)

generalzoi
Newbie
Posts: 5
Joined: Tue Jun 09, 2015 10:31 pm
Contact:

Re: Need function/transformation to fade between two sprites

#9 Post by generalzoi »

Kinsman wrote:The key behind side images is that they use image tagging. In Ren'Py, you can give a tag to an image, and any image you give with the same tag replaces the old image.

The 'as' clause in the show statement is useful for retagging an image:
...
Another, more advanced thing you can do is use 'config.show', and create a Python function that can intercept and/or filter the show statement. Here, how about something like this:
I didn't know you could retag an image, which is good information to have. Using 'config.show' also looks very powerful and useful. Thanks for the examples!
Winterslice wrote:You can pass variable arguments to a transform by, for example, doing the following:

Code: Select all

transform example(argument1, argument2):
     xalign argument1
     yalign argument2
These will be automatically applied to whatever displayable you're using the at statement on. Like so:

Code: Select all

label start:
     show A at example(0.5, 1.0)
See, that looks like what I was originally trying for. Looking at your code, I see I somehow missed the 'at' keyword when I was trying to apply the transform. D'oh! Not sure how I managed that.

So it looks like there are a couple of ways to handle it. Thanks for the help!

Post Reply

Who is online

Users browsing this forum: No registered users