Zoom

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.
Message
Author
User avatar
PyTom
Ren'Py Creator
Posts: 15893
Joined: Mon Feb 02, 2004 10:58 am
Completed: Moonlight Walks
Projects: Ren'Py
IRC Nick: renpytom
Github: renpytom
itch: renpytom
Location: Kings Park, NY
Contact:

Zoom

#1 Post by PyTom » Wed Jan 25, 2006 12:13 pm

Here's some code that adds zooming support to the demo game. Just add this to your script (or to zoom.rpy), and you'll get zooming support.

Please note that this will duplicate code found in 5.3.4, so this should go away when 5.3.4 comes out.

The zoom is unfiltered, so you can expect some aliasing, especially when zooming in. But filtering would kill performance, so unfiltered it is.

I'm now getting 50-70 fps on this, depending on what my computer is doing in the background.

I have included the ability to switch over to another image when the zoom is done, which may help as people won't be staring at the artifacts for very long.

I've attached a screenshot so people can see

The code is:

Code: Select all

init -100:
  python:
      
    import pygame
      
    class _Zoom(renpy.display.core.Displayable):
        """
        This displayable causes a zoom to take place, using image
        scaling. The render of this displayable is always of the supplied
        size. The child displayable is rendered, and a rectangle is
        cropped out of it. This rectangle is interpolated between the
        start and end rectangles. The rectangle is then scaled to the
        supplied size. The zoom will take time seconds, after which it
        will show the end rectangle, unless an after_child is
        given.

        The algorithm used for scaling does not perform any
        interpolation or other smoothing.
        """
        


        def __init__(self, size, start, end, time, child,
                     after_child=None, **properties):
            """
            @param size: The size that the rectangle is scaled to, a
            (width, height) tuple.

            @param start: The start rectangle, an (xoffset, yoffset,
            width, height) tuple.

            @param end: The end rectangle, an (xoffset, yoffset,
            width, height) tuple.

            @param time: The amount of time it will take to
            interpolate from the start to the end rectange.

            @param child: The child displayable.

            @param after_child: If present, a second child
            widget. This displayable will be rendered after the zoom
            completes. Use this to snap to a sharp displayable after
            the zoom is done.
            """
            
            super(_Zoom, self).__init__(**properties)

            self.size = size
            self.start = start
            self.end = end
            self.time = time
            self.child = child            

            self.after_child = after_child

        def predict(self, callback):
            self.child.predict(callback)

            if self.after_child:
                self.after_child.predict(callback)
        
        def render(self, width, height, st):

            if self.time:
                done = min(st / self.time, 1.0)
            else:
                done = 1.0

            if self.after_child and done == 1.0:
                return renpy.display.render.render(self.after_child, width, height, st)


            rend = renpy.display.render.render(self.child, width, height, st)
            surf = rend.pygame_surface()
            
            rect = tuple([ (1.0 - done) * a + done * b for a, b in zip(self.start, self.end) ])
            subsurf = surf.subsurface(rect)

            scalesurf = pygame.transform.scale(subsurf, self.size)

            renpy.display.render.mutated_surface(scalesurf)

            rv = renpy.display.render.Render(self.size[0], self.size[1])
            rv.blit(scalesurf, (0, 0))
            rv.depends_on(rend)

            if done < 1.0:
                renpy.display.render.redraw(self, 0)

            return rv

        def event(self, ev, x, y):
            return None

    Zoom = renpy.curry(_Zoom)

    
label splashscreen:

    scene bg whitehouse
            
    "Before the zoom."

    $ start_frames = config.frames

    # This must be a scene or a hide/show pair. Just doing show bg
    # whitehouse at ... would not work, at least in 5.3.3, due to some
    # timebase issues.
    scene bg whitehouse at Zoom((800, 600), (0, 0, 800, 600), (225, 150, 400, 300), 2.0)

    $ renpy.pause(2.0)

    $ fps = (config.frames - start_frames) / 2.0

    "The zoom occured at %(fps).1f fps."

    return
Attachments
screenshot0003.png
screenshot0003.png (194.57 KiB) Viewed 1538 times
Supporting creators since 2004
(When was the last time you backed up your game?)
"Do good work." - Virgil Ivan "Gus" Grissom
"Silly and fun things are important." - Elon Musk
Software > Drama • https://www.patreon.com/renpytom

User avatar
monele
Lemma-Class Veteran
Posts: 4101
Joined: Sat Oct 08, 2005 7:57 am
Location: France
Contact:

#2 Post by monele » Wed Jan 25, 2006 3:47 pm

Runs at 30fps on my low-end machine. Not too bad considering it refreshes the whole screen :)

User avatar
PyTom
Ren'Py Creator
Posts: 15893
Joined: Mon Feb 02, 2004 10:58 am
Completed: Moonlight Walks
Projects: Ren'Py
IRC Nick: renpytom
Github: renpytom
itch: renpytom
Location: Kings Park, NY
Contact:

#3 Post by PyTom » Wed Jan 25, 2006 4:54 pm

If you could run the speed-test (press shift-S during the demo), and compare the results of that, I'd appreciate it.
Supporting creators since 2004
(When was the last time you backed up your game?)
"Do good work." - Virgil Ivan "Gus" Grissom
"Silly and fun things are important." - Elon Musk
Software > Drama • https://www.patreon.com/renpytom

User avatar
monele
Lemma-Class Veteran
Posts: 4101
Joined: Sat Oct 08, 2005 7:57 am
Location: France
Contact:

#4 Post by monele » Thu Jan 26, 2006 12:11 pm

61.4 fps :)

User avatar
Dre
Regular
Posts: 118
Joined: Tue Jan 25, 2005 8:55 pm
Location: Allugic.com
Contact:

#5 Post by Dre » Thu Jan 26, 2006 9:10 pm

I got 18.5 fps running the zoom. :(

edit: On a good note, the zoom looks great!
Last edited by Dre on Thu Jan 26, 2006 9:14 pm, edited 1 time in total.

User avatar
PyTom
Ren'Py Creator
Posts: 15893
Joined: Mon Feb 02, 2004 10:58 am
Completed: Moonlight Walks
Projects: Ren'Py
IRC Nick: renpytom
Github: renpytom
itch: renpytom
Location: Kings Park, NY
Contact:

#6 Post by PyTom » Thu Jan 26, 2006 9:12 pm

I'm not sure what to tell you... zooming is expensive work.

On the plus side, movies are only 24fps, and I think I've seen anime with as little as 10fps. So 18.5 fps is actually not too bad. (It's not great, but I don't know what to do except, perhaps, to wait for cairo to come into its own.)
Supporting creators since 2004
(When was the last time you backed up your game?)
"Do good work." - Virgil Ivan "Gus" Grissom
"Silly and fun things are important." - Elon Musk
Software > Drama • https://www.patreon.com/renpytom

User avatar
Dre
Regular
Posts: 118
Joined: Tue Jan 25, 2005 8:55 pm
Location: Allugic.com
Contact:

#7 Post by Dre » Thu Jan 26, 2006 9:33 pm

Well, as long as the zoom works. The results may vary but it isn't like it will be used obsessively.

Quick question, is running several effects (move, pan, screen fading, music...) ok? Will it still run smooth enough to function right? Is this even possibly? Reason me asking is because I have a title screen in mind.

User avatar
PyTom
Ren'Py Creator
Posts: 15893
Joined: Mon Feb 02, 2004 10:58 am
Completed: Moonlight Walks
Projects: Ren'Py
IRC Nick: renpytom
Github: renpytom
itch: renpytom
Location: Kings Park, NY
Contact:

#8 Post by PyTom » Thu Jan 26, 2006 9:50 pm

Yes, it is possible. For example, Moonlight Walks uses a pan and dissolve at the same time as part of the splashscreen. If it runs well enough is a matter of taste... I find that framerate changes are quite noticable during fast motion, but less noticable for slower motions, so you need to watch for that (or use config.framerate as a limiter).

It also helps if you kill of programs in the background. Bittorrent clients are notorious for bursty cpu usage, which is noticable as framerate changes.

But there shouldn't be a fundamental problem with multiple moves and pans on the screen at once... Ren'Py is designed to handle that.

The one thing is that I wouldn't zoom a moving image. That will half the speed of the zoom, which isn't good. (One can easily move a zoomed image, however.)
Supporting creators since 2004
(When was the last time you backed up your game?)
"Do good work." - Virgil Ivan "Gus" Grissom
"Silly and fun things are important." - Elon Musk
Software > Drama • https://www.patreon.com/renpytom

User avatar
Dre
Regular
Posts: 118
Joined: Tue Jan 25, 2005 8:55 pm
Location: Allugic.com
Contact:

#9 Post by Dre » Thu Jan 26, 2006 10:12 pm

That's good to know. :D (Thinks of the possibilities) So much possibility, so little time.

User avatar
monele
Lemma-Class Veteran
Posts: 4101
Joined: Sat Oct 08, 2005 7:57 am
Location: France
Contact:

#10 Post by monele » Fri Jan 27, 2006 4:20 am

Moonlight Walks uses a pan and dissolve at the same time
I'm interested since I'd like to have a character dissolve in as it moves. How would we do this? ô_o

User avatar
PyTom
Ren'Py Creator
Posts: 15893
Joined: Mon Feb 02, 2004 10:58 am
Completed: Moonlight Walks
Projects: Ren'Py
IRC Nick: renpytom
Github: renpytom
itch: renpytom
Location: Kings Park, NY
Contact:

#11 Post by PyTom » Fri Jan 27, 2006 8:38 am

The usual way. Just show the character at a move, and then follow that command with a "with dissolve".

with None
show foo bar at Move(...)
with dissolve
Supporting creators since 2004
(When was the last time you backed up your game?)
"Do good work." - Virgil Ivan "Gus" Grissom
"Silly and fun things are important." - Elon Musk
Software > Drama • https://www.patreon.com/renpytom

User avatar
monele
Lemma-Class Veteran
Posts: 4101
Joined: Sat Oct 08, 2005 7:57 am
Location: France
Contact:

#12 Post by monele » Fri Jan 27, 2006 4:58 pm

I squealed with joy at first but then I realized this doesn't seem to work with "hide", hence you can't make a character dissolve out instead of dissolve in :|. Should I use some other trick instead ?

User avatar
PyTom
Ren'Py Creator
Posts: 15893
Joined: Mon Feb 02, 2004 10:58 am
Completed: Moonlight Walks
Projects: Ren'Py
IRC Nick: renpytom
Github: renpytom
itch: renpytom
Location: Kings Park, NY
Contact:

#13 Post by PyTom » Fri Jan 27, 2006 5:26 pm

What are you trying to do? Do you want to dissolve away a moving character? If so, you want to start the move before the with None, then go and hide them and do the dissolve away.

Code: Select all

show foo bar at Move(...)
with None
hide foo
with dissolve
Supporting creators since 2004
(When was the last time you backed up your game?)
"Do good work." - Virgil Ivan "Gus" Grissom
"Silly and fun things are important." - Elon Musk
Software > Drama • https://www.patreon.com/renpytom

User avatar
monele
Lemma-Class Veteran
Posts: 4101
Joined: Sat Oct 08, 2005 7:57 am
Location: France
Contact:

#14 Post by monele » Sat Jan 28, 2006 5:56 am

And needing "hide foo" if it was shown previously, ok. Now it works, thanks ^^.
Question though : how come we have to hide the character before a Move command ? I noticed the animation seems to be started at the previous command if the character is already visible...

User avatar
PyTom
Ren'Py Creator
Posts: 15893
Joined: Mon Feb 02, 2004 10:58 am
Completed: Moonlight Walks
Projects: Ren'Py
IRC Nick: renpytom
Github: renpytom
itch: renpytom
Location: Kings Park, NY
Contact:

#15 Post by PyTom » Sat Jan 28, 2006 9:31 am

Well, the original idea was that the time-base would continue from where the character was last shown. This is useful for smooth animation, but kinda a misfeature for zoom, move, and friends.

The next release of Ren'Py (5.4.0, probably), will introduce a second timebase, and allow one to select which timebase to use.
Supporting creators since 2004
(When was the last time you backed up your game?)
"Do good work." - Virgil Ivan "Gus" Grissom
"Silly and fun things are important." - Elon Musk
Software > Drama • https://www.patreon.com/renpytom

Post Reply

Who is online

Users browsing this forum: _ticlock_