Warning

This wiki is very out of date, and only exists for historical reasons. For more modern information, see the new documentation and cookbook forum.

renpy/doc/cookbook/Shake effect

From Ren'Py Visual Novel Engine

Jump to: navigation, search

Shake Effect

You can already use the default vpunch and hpunch transitions to shake the screen. But what about a shake that goes in every directions randomly, Phoenix Wright style?

init:

    python:
    
        import math

        class Shaker(object):
        
            anchors = {
                'top' : 0.0,
                'center' : 0.5,
                'bottom' : 1.0,
                'left' : 0.0,
                'right' : 1.0,
                }
        
            def __init__(self, start, child, dist):
                if start is None:
                    start = child.get_placement()
                #
                self.start = [ self.anchors.get(i, i) for i in start ]  # central position
                self.dist = dist    # maximum distance, in pixels, from the starting point
                self.child = child
                
            def __call__(self, t, sizes):
                # Float to integer... turns floating point numbers to
                # integers.                
                def fti(x, r):
                    if x is None:
                        x = 0
                    if isinstance(x, float):
                        return int(x * r)
                    else:
                        return x

                xpos, ypos, xanchor, yanchor = [ fti(a, b) for a, b in zip(self.start, sizes) ]

                xpos = xpos - xanchor
                ypos = ypos - yanchor
                
                nx = xpos + (1.0-t) * self.dist * (renpy.random.random()*2-1)
                ny = ypos + (1.0-t) * self.dist * (renpy.random.random()*2-1)

                return (int(nx), int(ny), 0, 0)
        
        def _Shake(start, time, child=None, dist=100.0, **properties):

            move = Shaker(start, child, dist=dist)
        
            return renpy.display.layout.Motion(move,
                          time,
                          child,
                          add_sizes=True,
                          **properties)

        Shake = renpy.curry(_Shake)
    #

#

You can now use it inline or create a few transitions :

init:
    $ sshake = Shake((0, 0, 0, 0), 1.0, dist=15)

Syntax : Shake(position, duration, maximum distance) with 'position' being a tuple of 4 values : x-position, y-position, xanchor, yanchor.

Examples

show phoenix think with dissolve
ph "I think this game lacks a little something... Right! Some..."
ph "Objection!" with sshake    # shaking the whole screen with the previously defined 'sshake'
ph "Eheh... Uh? What the?! It's reverberating!"
show phoenix at Shake((0.5, 1.0, 0.5, 1.0), 1.0, dist=5)    
with None
# shaking the sprite by placing it at the center (where it already was)
ph "Ng!..."
show phoenix at center, Shake(None, 1.0, dist=5)
with None
# exactly the same thing but it shows how you can first give a predefined position and, 
# giving None as a position for Shake, let it take 'center' as the shaking position.
ph "AAgh! Stop it already!"
ph "...... Is it over?"
with Shake((0, 0, 0, 0), 3.0, dist=30)
# some serious shaking of the screen for 3 seconds
# try not to abuse high values of 'dist' since it can make things hard on the eyes
Personal tools