Path motion

A place for Ren'Py tutorials and reusable Ren'Py code.
Forum rules
Do not post questions here!

This forum is for example code you want to show other people. Ren'Py questions should be asked in the Ren'Py Questions and Announcements forum.
Message
Author
delta
Epitome of Generic
Posts: 525
Joined: Sat Dec 22, 2007 12:59 pm
Projects: yes
Contact:

Re: Path motion

#31 Post by delta »

They work with move, and I couldn't get it to change with dummy code.
The rest is left as an exercise for the reader.

Aenakume
Regular
Posts: 182
Joined: Mon Aug 11, 2008 4:38 am
Projects: Arts... i hate arts -_-
Contact:

Re: Path motion

#32 Post by Aenakume »

delta wrote:They work with move, and I couldn't get it to change with dummy code.
Fixed. ^_^;

It works with every sized image i tried, from 10x10 up to 1024x768. i tried both eileen_happy.png and logo.png from the demo, and had them both looping around the screen.
“You can lead a fool to wisdom, but you cannot make him think.”

delta
Epitome of Generic
Posts: 525
Joined: Sat Dec 22, 2007 12:59 pm
Projects: yes
Contact:

Re: Path motion

#33 Post by delta »

Now it seems to work, thank you. I may end up using this heavily.
The rest is left as an exercise for the reader.

User avatar
PyTom
Ren'Py Creator
Posts: 16088
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:

Re: Path motion

#34 Post by PyTom »

Two questions:

1) Can I get confirmation that this is release under the Ren'Py license?
2) Is the code at the top of this the latest code?

Thanks for getting back to me soon, I'd like to release this with the next Ren'Py, this weekend.
Supporting creators since 2004
(When was the last time you backed up your game?)
"Do good work." - Virgil Ivan "Gus" Grissom
Software > Drama • https://www.patreon.com/renpytom

Aenakume
Regular
Posts: 182
Joined: Mon Aug 11, 2008 4:38 am
Projects: Arts... i hate arts -_-
Contact:

Re: Path motion

#35 Post by Aenakume »

PyTom wrote:1) Can I get confirmation that this is release under the Ren'Py license?
i think so? ^_^; i'm not sure what the Ren'Py licence is - but i'm not going to reserve any rights or anything. i have no problem with you releasing it under whatever licence terms Ren'Py itself is under.
PyTom wrote:2) Is the code at the top of this the latest code?
Yes.
“You can lead a fool to wisdom, but you cannot make him think.”

User avatar
PyTom
Ren'Py Creator
Posts: 16088
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:

Re: Path motion

#36 Post by PyTom »

A quick screenshot of the spline editor I'm putting together to go with Aenakume's spline code. Basically, the dots are equally spaced in time, and the gray square represents the screen. So this path would have an object starting at the bottom of the screen, rising up, and then dropping back down again.

The spline editor will be write-only, as it will be incapable of reading in splines once written out.
screenshot0038.png
screenshot0038.png (5.3 KiB) Viewed 4409 times
Supporting creators since 2004
(When was the last time you backed up your game?)
"Do good work." - Virgil Ivan "Gus" Grissom
Software > Drama • https://www.patreon.com/renpytom

Aenakume
Regular
Posts: 182
Joined: Mon Aug 11, 2008 4:38 am
Projects: Arts... i hate arts -_-
Contact:

Re: Path motion

#37 Post by Aenakume »

Oh, that's very sexy. i was just going to take the cheap way out and make a script that parsed SVG paths created in vector graphics editors. ^_^;
“You can lead a fool to wisdom, but you cannot make him think.”

Jo'ogn
Veteran
Posts: 398
Joined: Sat Jul 12, 2008 1:31 pm
Projects: Kassiopeia [iVN]
Location: Deutschland
Contact:

Re: Path motion

#38 Post by Jo'ogn »

I just started to play around with the Zoom and Pan functions. To make the motion look more camera-like: accelaration/deceleration (maybe even a tad of shake), is it possible to apply such pathes to Zoom and Pan?
Audio Plays: [original] The White Feathers Directive - [Star Wars] Through Flame and Shadow
Ren'Py: Kassiopeia [very interactive VN] work in progress - looking for proof reader english

TheSHAD0W
Newbie
Posts: 9
Joined: Wed Jun 18, 2014 8:03 am
Contact:

Re: Path motion

#39 Post by TheSHAD0W »

So, Uncle Mugen mentioned this in channel and sent me a copy; it didn't work right for current Ren'py and lacked the ability to work on different resolutions, so I updated it. Here ya go.
Attachments
spline_editor_2.zip
Spline Editor v2
(10.41 KiB) Downloaded 247 times

User avatar
xela
Lemma-Class Veteran
Posts: 2481
Joined: Sun Sep 18, 2011 10:13 am
Contact:

Re: Path motion

#40 Post by xela »

In what world is this not in the cookbook... this is very, very useful. My gratitude to everyone involved.
Like what we're doing? Support us at:
Image

User avatar
SypherZent
Veteran
Posts: 362
Joined: Fri Sep 02, 2016 3:14 am
Completed: Multiverse Heroes, Space Hamster in Turmoil
Location: Puerto Rico
Contact:

Re: Path motion

#41 Post by SypherZent »

Thank you so much for sharing this!
Creator of Multiverse Heroes & Space Hamster in Turmoil

Want me to code your game?
Check my services thread!

User avatar
Milkymalk
Miko-Class Veteran
Posts: 753
Joined: Wed Nov 23, 2011 5:30 pm
Completed: Don't Look (AGS game)
Projects: KANPEKI! ★Perfect Play★
Organization: Crappy White Wings
Location: Germany
Contact:

Re: Path motion

#42 Post by Milkymalk »

Aenakume wrote:This is a motion function to move stuff around - similar to Move - that allows you to specify paths by key-frame points. Between your key-frame points, you can specify motion that is linear, quadratic or cubic.

Here's an example that uses quadratic interpolation.
Image

Code: Select all

points = (
  ((100, 300),),
  ((400, 300), (550, 450)),
  ((700, 300), (250, 150))
)

show box at PathMotion(points, 1.0)
I feel stupid for asking this, but can you "explain to me like I'm 5" what (550, 450) and (250, 150) means? I only figured out that they are the coordinates of the "stretching points", but with the coords mixed up between them (their real coordinates would be (550, 150) and (250, 450)).
Crappy White Wings (currently quite inactive)
Working on: KANPEKI!
(On Hold: New Eden, Imperial Sea, Pure Light)

User avatar
_ticlock_
Miko-Class Veteran
Posts: 910
Joined: Mon Oct 26, 2020 5:41 pm
Contact:

Re: Path motion

#43 Post by _ticlock_ »

Aenakume wrote: Wed Aug 27, 2008 3:11 am
I am not sure what happened to the original post Aenakume, but it is not showing the code correctly. For consistency and for other people to use code without figuring out the correct indentations and other possible problems, here is Aenakume code (I used other post to restore the code.)

Code: Select all

init python:
    class PathInterpolator(object):

        anchors = {
            'top'    : 0.0,
            'center' : 0.5,
            'bottom' : 1.0,
            'left'   : 0.0,
            'right'  : 1.0,
        }

        # Default anchors (from Position)
        default_anchors = (0.5, 1.0)

        def __init__(self, points):

            assert len(points) >= 2, "Need at least a start and end point."

            def setup_coordinate_(c):
                if len(c) == 2:
                    c += self.default_anchors
                return [ self.anchors.get(i, i) for i in c ]

            self.points = []

            for p in points:
                length = len(p)

                if isinstance(p[-1], float):
                    length = len(p) - 1
                    point = [ p[-1] ]
                else:
                    length = len(p)
                    point = [ -1 ]

                self.points.append(point + [ setup_coordinate_(p[i]) for i in range(length) ])

            # Make sure start and end times are set, if not already set
            if self.points[0][0] == -1:
                self.points[0][0] = 0.0
            if self.points[-1][0] == -1:
                self.points[-1][0] = 1.0

            # Now we gotta calculate the step times that need calculating
            for start in range(1, len(self.points) - 1):
                if self.points[start][0] != -1:
                    continue

                end = start + 1

                while end < (len(self.points) - 1) and self.points[end][0] == -1:
                    end += 1

                step = (self.points[end][0] - self.points[start - 1][0]) / float(end - start + 1)

                for i in range(start, end):
                    self.points[i][0] = self.points[i - 1][0] + step

            # And finally, sort the list of points by increasing time
            self.points.sort(lambda a, b: cmp(a[0], b[0]))

            self.initialized = False

        def init_values_(self, sizes):
            def to_abs_(value, size):
                if isinstance(value, float):
                    return value * size
                else:
                    return value

            def coord_(c):
                return [ to_abs_(c[0], sizes[0]) + to_abs_(c[2], sizes[2]),
                       to_abs_(c[1], sizes[1]) + to_abs_(c[3], sizes[3]) ]

            for p in self.points:
                for i in range(1, len(p)):
                    p[i] = coord_(p[i])

            self.initialized = True

        def __call__(self, t, sizes):
            # Initialize if necessary
            if not self.initialized:
                self.init_values_(sizes)

            # Now we must determine which segment we are in
            for segment in range(len(self.points)):
                if self.points[segment][0] > t:
                    break

            # If this is the zeroth segment, just start at the start point
            if segment == 0:
                result = self.points[0][1]
            # If this is past the last segment, just leave it at the end point
            elif segment == len(self.points) - 1 and t > self.points[-1][0]:
                result = self.points[-1][1]
            else:
                # Scale t
                t = (t - self.points[segment - 1][0]) / (self.points[segment][0] - self.points[segment - 1][0])

                # Get start and end points
                start = self.points[segment - 1][1]
                end   = self.points[segment][1]

              # Now what kind of interpolation is it?
                if len(self.points[segment]) == 2:   # Straight line
                    t_p = 1.0 - t

                    result = [ t_p * start[i] + t * end[i] for i in 0,1 ]
                elif len(self.points[segment]) == 3: # Quadratic Bézier
                    t_pp = (1.0 - t)**2
                    t_p = 2 * t * (1.0 - t)
                    t2 = t**2

                    result = [ t_pp * start[i] + t_p * self.points[segment][2][i] + t2 * end[i] for i in 0,1 ]
                elif len(self.points[segment]) == 4: # Cubic Bézier
                    t_ppp = (1.0 - t)**3
                    t_pp = 3 * t * (1.0 - t)**2
                    t_p = 3 * t**2 * (1.0 - t)
                    t3 = t**3

                    result = [ t_ppp * start[i] + t_pp * self.points[segment][2][i] + t_p * self.points[segment][3][i] + t3 * end[i] for i in 0,1 ]

            return ( int(result[0]), int(result[1]), 0, 0 )

    def PathMotion(points, time, child=None, repeat=False, bounce=False, anim_timebase=False, style='default', time_warp=None, **properties):
      return Motion(PathInterpolator(points), time, child, repeat=repeat, bounce=bounce, anim_timebase=anim_timebase, style=style, time_warp=time_warp, add_sizes=True, **properties)

User avatar
bonnie_641
Regular
Posts: 133
Joined: Sat Jan 13, 2018 10:57 pm
Projects: Código C.O.C.I.N.A.
Deviantart: rubymoonlily
Contact:

Re: Path motion

#44 Post by bonnie_641 »

TheSHAD0W wrote: Thu Apr 16, 2015 9:11 am So, Uncle Mugen mentioned this in channel and sent me a copy; it didn't work right for current Ren'py and lacked the ability to work on different resolutions, so I updated it. Here ya go.
download/file.php?id=33566
In Ren`Py version 7.3.5 it works perfectly.
The only thing you have to do to save the path you create, modify the following:

- In the 'game' folder of Spline editor, create a file called 'splinedata.rpy'.
- Edit the file 'spline_editor.rpy' in the 'label write' section.

Code: Select all

label write:

    hide screen background
    scene black

    if not se.spline_points:
        "A spline must have at least two points in it."
        jump edit

    python:
        with open( os.path.join( renpy.config.gamedir, "splinedata.rpy" ), 'w' ) as f:
            f.write("init python:\n")
            f.write("    spline = SplineMotion([\n")
            for t in se.relative_spline():
                f.write("        %s,\n" % format(t))
            f.write("        ], %.1f, anchors=(0.5, 0.5), repeat=False)\n" % se.delay)
            f.close()

    "Information about this spline was written to splinedata.rpy.\nClick to continue."

    jump edit
- When you start the program, draw as usual, press 'w' when you are done and open the file 'splinedata.rpy'... there is the code written there for you to paste into your project.
I speak and write in Spanish. I use an English-Spanish translator to express myself in this forum. If I make any mistakes, please forgive me.
I try my best to give an answer according to your question. :wink:

Post Reply

Who is online

Users browsing this forum: No registered users