DynamicDisplayable Character change emotion

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
Andy_kl
Newbie
Posts: 18
Joined: Sun Apr 09, 2017 12:00 pm
Contact:

DynamicDisplayable Character change emotion

#1 Post by Andy_kl »

Good day, Everyone. So, I was working on some code that is responsible for appearance of the characters, and I ran into a problem where I am unable to add a transition during the change in emotions.

The function used to calculate the size of the future image (P.S. PyTom, could it be replaced with  renpy.image_size, it is much faster?):

Code: Select all

Def get_size(displayable):
    return (int(renpy.render(renpy.easy.displayable(displayable), 0, 0, 0, 0).get_size()[0]),
       int(renpy.render(renpy.easy.displayable(displayable), 0, 0, 0, 0).get_size()[1]))
Function used to assemble the final image from the layers.

Code: Select all

def PersonDynamic(st, at, data, *args):
       images = []
       data = data.mItems.values()
       data.sort( key = lambda item: item.zorder )
       for element in data:
               if element.mIsVisible == True:
                   images.append(element.position)
                   images.append(element.image) #the image of the layer
       image = im.Composite(get_size(data[0].image),*images)
       return image, 0
Part of the code used to initialise the character:

Code: Select all

class Person(store.object, ADVCharacter):
       def __init__(self, name, caption, charData = None, defVals = None, constVals = None, viewVals = None):
           self.name = name
           self.caption = caption
           self.charData = charData
           self.stats = {}
           self.image = DynamicDisplayable(PersonDynamic, data = self.charData)
           renpy.start_predict(self.image)
           self.char = Character(caption, color="cdaa85", window_right_padding = 440, window_left_padding = 440, screen = "person_say")
    …
Code used to display the character

Code: Select all

def Visibility(self, talkingView="", isTalking=True, transition=None):
           self._talkingView = talkingView
           if (isTalking and ('head' in self._talkingView)) or ('head+' in self._talkingView):
               renpy.show(self.name+"_image_head", what = At(self.image, Transform(pos = self.posH, anchor = (0.0, 0.0))), zorder=8)
Function responsible for changing character’s emotions:

Code: Select all

def Face(self, s):
           self.__temp=s.split(" ")
           for i in range(4):
               self.data.setStyleKey( ['brows', 'eyes', 'blush', 'mouth'][i], ['brows', 'eyes', 'blush', 'mouth'][i]+"_"+self.__temp[i] )# setStyreKey changes the current image of the layer/layers
           return
Example:

Code: Select all

label start:
    "..."
    $markus.Visibility('body')
    $markus.Face("b04g e03 c00 m03")
    with Dissolve(0.3, alpha = True)# Image displays properly with the transition, works fine so far
    markus "First show"
    $markus.Face("b00g e07 c00 m01")# Here is where the transition suppose to happen, but the following string should also start at the same moment.
    markus "Emotion 1"
    $markus.Face("b00g e22 c00 m02")
    markus "Emotion 2"
    $markus.Visibility()
    with Dissolve(0.3, alpha = True)# Image disappears with the transition, this part also works.
    markus "i m hide"
So what I am trying to achieve - the change of emotions should happen with the transition set by me (meaning it will always be through Dissolve, but with different timing), and the transition shoudl not take time, but rather be part of a background (so that the dialogue window didn’t close during the transition).

I expect it to be quite a difficult thing to achieve (maybe even impossible in RenPy).

Things that were tried, but not sure whether it is the right way to do it.
Use DynamicImage(element.image), instead of im.Composite use LiveComposite.

Also tried to get the old image and change it through the At with trasnforamtion.

Code: Select all

transform same_transform(old, new):
    parallel:
           old
           alpha 1.0
           linear 0.3 alpha 0.0
    parallel:
           new
           alpha 0.0
           linear 0.3 alpha 1.0
And many other things (resulting in 6 hours of “empty” work).
So to sum it all up:
There should be one — and preferably only one — obvious way to do it.
I would prefer to do it properly, but sadly, for the moment, I lack the skills needed. So here my summons PyTom and other RenPy gurus and even pythons, at this point any help is welcomed…

P.S. If any person can explain to me, in Russian, how interaction and renpy.restrart_interaction work, I would be very greatfull, I think that the solution can be achieved through these functions, the real question is when to use them.

User avatar
Divona
Miko-Class Veteran
Posts: 678
Joined: Sun Jun 05, 2016 8:29 pm
Completed: The Falconers: Moonlight
Organization: Bionic Penguin
itch: bionicpenguin
Contact:

Re: DynamicDisplayable Character change emotion

#2 Post by Divona »

Wouldn't use just LiveComposite and variables be easier?
viewtopic.php?f=8&t=41806

Code: Select all

define markus = Character("Markus")

default markus_body = "body01"
default markus_face = ("b04g", "e03", "c00", "m03")

image markus = LiveComposite(
    (420, 720),
    (0, 0), "[markus_body].png",
    (0, 0), "[markus_face[0]].png",
    (0, 0), "[markus_face[1]].png",
    (0, 0), "[markus_face[2]].png",
    (0, 0), "[markus_face[3]].png"
)

label start:
    "..."

    $markus_face = ("b04g", "e03", "c00", "m03")
    show markus with Dissolve(0.3)

    markus "First Show"

    $markus_face = ("b00g", "e07", "c00", "m01")
    show markus with Dissolve(0.3)

    markus "Emotion 1"

    $markus_face = ("b00g", "e22", "c00", "m02")
    show markus with Dissolve(0.3)

    markus "Emotion 2"

    hide markus with Dissolve(0.3)

    markus "I'm hide."

    return
For ATL transform that can help dissolve sprites without the pause:

Code: Select all

transform LiveDissolve(new_sprite, duration=0.3):
    DynamicImage(new_sprite) with Dissolve(duration, alpha=True)

label start:
    show markus with Dissolve(0.3)
    
    "I'm Markus."

    show markus at LiveDissolve("eileen")

    "I'm Eileen!"

    return
To prevent dialogue window to close during transition, see "config.window" in "options.rpy":

Code: Select all

## Window management ###########################################################
##
## This controls when the dialogue window is displayed. If "show", it is always
## displayed. If "hide", it is only displayed when dialogue is present. If
## "auto", the window is hidden before scene statements and shown again once
## dialogue is displayed.
##
## After the game has started, this can be changed with the "window show",
## "window hide", and "window auto" statements.

define config.window = "show"
Completed:
Image

Andy_kl
Newbie
Posts: 18
Joined: Sun Apr 09, 2017 12:00 pm
Contact:

Re: DynamicDisplayable Character change emotion

#3 Post by Andy_kl »

I used this before ...
But now I have 14 characters each with 40 emotions, ~ 500 pictures, which can also go with different shift. And more clothes ...
I made a XML-linker that returns a list of pictures, shift, zOrder and a bunch of what else. I'm not doing the creation of characters, and I needed an instrument that can be used by a non-programmer. Here I need a general solution.

I think most likely the problem is that I do not understand how interation works, because In those places where the character appears different transformations are applied.

User avatar
Divona
Miko-Class Veteran
Posts: 678
Joined: Sun Jun 05, 2016 8:29 pm
Completed: The Falconers: Moonlight
Organization: Bionic Penguin
itch: bionicpenguin
Contact:

Re: DynamicDisplayable Character change emotion

#4 Post by Divona »

In your code, with "markus.Face", if it does change the sprite facial expression (brows, eyes, mouth, etc), I don't see that the sprite has been called again for a transition when variables changed. If it still working like text interpolating in LiveComposite, then it means the sprite facial expression would change instantly instead of with transition.

Here you wanting the expression changes with a transition at the same time with the next line of dialogue, if I understand correctly. That's mean you will need to show that character sprite again.

Perhaps something like this:

Code: Select all

def Face(self, s):
    self.__temp=s.split(" ")

    for i in range(4):
        self.data.setStyleKey( ['brows', 'eyes', 'blush', 'mouth'][i], ['brows', 'eyes', 'blush', 'mouth'][i]+"_"+self.__temp[i] )# setStyreKey changes the current image of the layer/layers
    
    ## Show character sprite with dissolve transition.
    renpy.show(self.name+"_image_head", what = At(self.image, Transform(pos = self.posH, anchor = (0.0, 0.0))), zorder=8)
    renpy.with_statement(Dissolve(0.3))

    return
However, this will give the game a 0.3 seconds pause while dissolve transition doing it thing. I'm really stumped with ATL transform when the same sprite is showing. Ren'Py just refused to redraw the sprite. It does work when it's a new sprite being call alongside the transform, though.
Completed:
Image

Andy_kl
Newbie
Posts: 18
Joined: Sun Apr 09, 2017 12:00 pm
Contact:

Re: DynamicDisplayable Character change emotion

#5 Post by Andy_kl »

Yes, I need the transform to run with every change of emotions at once.
As far as I understand, the right decision will be to transfer transform to layer, but I do not understand how to do it.
From what I found in the documentation for the description is suitable AlphaBlend.

Or write udd, but here I need to understand from scratch.

Ideally, I need a function that collects one image from all layers. But Fixed and Flatten create a different type of displayable.

Andy_kl
Newbie
Posts: 18
Joined: Sun Apr 09, 2017 12:00 pm
Contact:

Re: DynamicDisplayable Character change emotion

#6 Post by Andy_kl »

A good example from which I can develop further will be:
Five pictures, and a function that will change this picture (with dissolve) without interrupting the dialog.

example

Code: Select all

label start:
    $pic_show()
    "say"
    $change_pic(1)
    "1 change"
    $change_pic(3)
    "2 change"
    $change_pic(5)
    "3 change"
    $pic_hide()
    "end"
    return

Post Reply

Who is online

Users browsing this forum: Google [Bot], Lucyper, Majestic-12 [Bot]