Trying to make bouncing text work

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
User avatar
XT9K
Newbie
Posts: 14
Joined: Sun Nov 01, 2020 10:50 pm
Contact:

Trying to make bouncing text work

#1 Post by XT9K »

I've been trying to implement a system for making text effects in the say screen similar to Paper Mario. Like some words having letters that bob up and down or shake around to show fright. I've got something that will allow for alpha and zoom to change on the text. But anything positional seems to be restricted.

Here's what I have so far.

Code: Select all

init python:

    import math
    #Custom Displayable class to handle the text being manipulated. Effectively just a wrapper for text.
    class BounceText(renpy.Displayable):
        def __init__(self, child, id, bounce_height=10, **kwargs):

            # Pass additional properties on to the renpy.Displayable
            # constructor.
            super(BounceText, self).__init__(**kwargs)

            # The child.
            self.child = renpy.displayable(child)

            self.bounce_height = bounce_height
            self.id = id #Should probably rename to word_offset or something.

        def render(self, width, height, st, at):
            curr_height = math.sin(st+float(self.id))+1 #* float(self.bounce_height) #Adjust this function to get different results.

            # Create a transform
            t = Transform(child=self.child,  zoom = curr_height) ####  Altering this changes the effect. ####
            #### Replace zoom with yoffset or alpha to try different results  ####

            # Create a render from the child.
            child_render = renpy.render(t, width, height, st, at)

            # Get the size of the child.
            self.width, self.height = child_render.get_size()

            # Create the render we will return.
            render = renpy.Render(self.width, self.height)

            # Blit (draw) the child's render to our render.
            render.blit(child_render, (0, 0))
            renpy.redraw(self, 0)
            # Return the render.
            return render

        def visit(self):
            return [ self.child ]
    #Custom Text Tag that swaps the text for the BounceText class.
    #TODO: Make it more compatible with other text tags. 
    def bounce_tag(tag, argument, contents):
        new_list = [ ]
        for kind,text in contents:
            if kind == renpy.TEXT_TEXT:
                disp_id = 0 # Used more to give the characters some offsets in the sine function. 
                    ###The commented lines below were an attempt to wrap the BounceText displayables in another container. 
                    ###Did not work as I'd hoped but play around with it if you'd like.
                #text_list = []
                for char in text:
                    char_text = Text(char)
                    char_disp = BounceText(char_text, disp_id, argument)
                    #text_list.append((50*disp_id,50)) #TODO: 50 is placeholder. Should be more programatic
                    #text_list.append(char_text)
                    new_list.append((renpy.TEXT_DISPLAYABLE, char_disp))
                    disp_id = disp_id + 1
                #new_composite = Composite((50*(disp_id+1),100), *text_list)
                #new_list.append((renpy.TEXT_DISPLAYABLE, new_composite))
                disp_id = 0
            else:
                new_list.append((kind,text))

        return new_list

    config.custom_text_tags["bt"] = bounce_tag #Adds the text tag.
#end python
define e = Character("Eileen")
label start:
    scene bg room
    e "I want to test text"
    e "Here is some {bt=10}wavy{/bt} text"
    e "how did it go?"
Currently zoom and alpha are the main ones that seem to work. But would really like if positional or rotational transforms were possible too. My assumption is that the Text displayable is overriding any positional rendering. I know you can tell the say screen to do

Code: Select all

text what id "what" at text_bounce
But that moves the whole line. Using a Composite does space out the characters more, but still restricts movement, likely due to them being a Fixed. And you could just animate some characters and play them as a movie file or something. But would rather use Renpy's built-in Transforms so it's more dynamic. If you have any ideas on a workaround please let me know. I'm trying to peek at the code for the Text displayable to see what causes the restrictions, but might be faster to just ask.

Poked around the cookbook and didn't find anything similar but let me know if someone else has solved this problem before. Again, I'd like it to be more of a per text character effect rather than per word or whole lines. It feels so close to working but something holding it back.

Known (additional) problems: This pretty much causes all the characters within the text tag to display at once regardless of text speed
Probably won't work with other text tag styling very well
Effect is not reproduced on the History screen.

User avatar
Imperf3kt
Lemma-Class Veteran
Posts: 3794
Joined: Mon Dec 14, 2015 5:05 am
itch: Imperf3kt
Location: Your monitor
Contact:

Re: Trying to make bouncing text work

#2 Post by Imperf3kt »

The way renpy renders the text will limit you. If I recall, the text is turned into a single image before being added to the say screen. Pytom goes into greater detail somewhere, I'll see if I can dig it up.


You could always turn each letter into a displayable and place them in an image in the order you need, that way you can animate them using ATL as you like, but you'd have to hide the text window and manually add every single letter to each screen and it'd just be a complicated mess.
Warning: May contain trace amounts of gratuitous plot.
pro·gram·mer (noun) An organism capable of converting caffeine into code.

Current project: GGD Mentor

Twitter

User avatar
Alex
Lemma-Class Veteran
Posts: 3094
Joined: Fri Dec 11, 2009 5:25 pm
Contact:

Re: Trying to make bouncing text work

#3 Post by Alex »

Check the code samples here - viewtopic.php?f=51&t=59587

User avatar
XT9K
Newbie
Posts: 14
Joined: Sun Nov 01, 2020 10:50 pm
Contact:

Re: Trying to make bouncing text work

#4 Post by XT9K »

Thank you for that link to the FancyText thing. I managed to start figuring out what was causing it to override my transforms. But fix I found is to just have the positional arguments applied to the blit. So instead of

Code: Select all

render.blit(child_render, (0, 0))
replace it with something like

Code: Select all

render.subpixel_blit(child_render, (0, curr_height))
My current render function for this is

Code: Select all

def render(self, width, height, st, at):
            curr_height = math.sin(2*(st+float(self.id))) * float(self.bounce_height)  #Uped the frequency a bit here to make it a bit smoother.

            # Create a transform
            #t = Transform(child=self.child,  zoom = curr_height) ####  Add back in if you'd like zoom or alpha effects ####

            # Create a render from the child.
            child_render = renpy.render(self.child, width, height, st, at) #Replace self.child with t here for the above transform to apply

            # Get the size of the child.
            self.width, self.height = child_render.get_size()

            # Create the render we will return.
            render = renpy.Render(self.width, self.height)

            # Blit (draw) the child's render to our render.
            render.subpixel_blit(child_render, (0, curr_height)) 
            renpy.redraw(self, 0)
            # Return the render.
            return render
m1lZbDUXOF.gif
m1lZbDUXOF.gif (104.57 KiB) Viewed 802 times
I'll probably continue experimenting with this for bugs and make a new thread if I feel happy with it. Otherwise, ppl are free to use this as they want. Still not sure how to add in rotations with this, but you can use the FancyText viewtopic.php?f=51&t=59587 . But I'm pretty happy with just some shaking and sliding.

User avatar
XT9K
Newbie
Posts: 14
Joined: Sun Nov 01, 2020 10:50 pm
Contact:

Re: Trying to make bouncing text work

#5 Post by XT9K »

For anyone who sees this and wonders where that went I posted my results here viewtopic.php?f=51&t=60527

Post Reply

Who is online

Users browsing this forum: Google [Bot]