So i have a need to make transforms that have an numerous changes of direction. I need to be able to create transforms to show movement paths, but since the route taken is not decided until the start point and end point of any given path is determined it is impossible to define a transform in an init block that is enough to cover all eventualities. The path's length can vary and can twist and turn as needed to bypass obstacles. I'm using a method of multiple small pre defined transforms to move along these paths, but it is jerky and inefficient.
I've had a stab at Aenakume's Bezier Motion Code, but it's not really usable in my situation. I was wondering if there was a way to define transforms on the fly in the same way you can define global variables mid code, or perhaps a way of structuring a transform to accept more variables. The main issue i'm hitting is that for loops are not supported in transforms, but there might be a workaround i'm not aware of (I hope).
If anyone has a good knowledge of transforms and might be able to help i'd really appreciate it.
Possible to create transforms mid code?
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.
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.
- Evildumdum
- Regular
- Posts: 191
- Joined: Sun Jan 18, 2015 8:49 am
- Projects: ApoclypseZ
- Contact:
Possible to create transforms mid code?
"If at first you don't succeed, try hitting it with a shoe."
Re: Possible to create transforms mid code?
Code: Select all
transform my_atl_instructions(*args, **kwargs):
# ...
- Remix
- Eileen-Class Veteran
- Posts: 1628
- Joined: Tue May 30, 2017 6:10 am
- Completed: None... yet (as I'm still looking for an artist)
- Projects: An un-named anime based trainer game
- Contact:
Re: Possible to create transforms mid code?
Bezier is not 'easily' useful for paths that generally want to actually go through each point, you'd need to calculate the Bezier control points and then calculate a path based upon those... messy and umm still Bezier.
A much nicer option, in my opinion, is Cat-mull Rom pathing though that uses matrix multiplication and most Python examples import numpy which is a C based math library and hence would not sit well as a Ren'py import... I think it could still be done with simpler math though and might still be worth looking at.
You could smooth your 'turn' points by writing your own algorithm that uses a set radius circle to arc at each point then calculates an arc from each logical intersection to the centre of each path segment... easiest math, fastest compute, maybe most work though
Knots in Ren'py... if you can understand what each co-ordinate relates to in the movement... might also be an option
As xela says, you are likely looking at passing parameters into a set ATL transform (which will get messy as atl definitions do not play well with more than just simple coding logic. The alternative is function...
Pseudo code
As you can see, the transform functions cannot be passed extra information, so cannot themselves calculate the path unless all the outside data is globalized. The path points calculation would in most cases be best done outside the atl function and called for.
On an aside: You should note, Bezier, Cat-mull Rom and probably Knot based paths are all non equidistant points algorithms which basically means if you are moving along them with a linear time step you will be seen to be moving at a non linear speed.
I am in the midst of finishing an events controller at the moment. Perhaps afterwards I might revisit the Cat-mull Rom stuff and get a few sprites walking around
A much nicer option, in my opinion, is Cat-mull Rom pathing though that uses matrix multiplication and most Python examples import numpy which is a C based math library and hence would not sit well as a Ren'py import... I think it could still be done with simpler math though and might still be worth looking at.
You could smooth your 'turn' points by writing your own algorithm that uses a set radius circle to arc at each point then calculates an arc from each logical intersection to the centre of each path segment... easiest math, fastest compute, maybe most work though
Knots in Ren'py... if you can understand what each co-ordinate relates to in the movement... might also be an option
As xela says, you are likely looking at passing parameters into a set ATL transform (which will get messy as atl definitions do not play well with more than just simple coding logic. The alternative is function...
Pseudo code
Code: Select all
init python:
# basic move in a circle sort of thing...
# no actual path logic
def move_ellipse(trans, st, at):
rad = st / 10 * math.pi * 2
trans.xalign = float(math.sin(rad)) / 4 + 0.5
trans.yalign = float(math.cos(rad)) / 4 + 0.5
return 0.02 # 50fps
# presuming we had a function elsewhere that returned
# a (x, y) co-ordinate tuple based upon time we could
# use something like this
def move_along_precalculated_path(trans, st, at):
trans.xalign, trans.yalign = get_coords_for_time( st )
return 0.02 # 50fps
label start:
# $ girl = AnimatedSprite("girl", girl_sprites.get_sprite_map(), image="girl_tag" )
show expression (girl) as tara:
function move_ellipse
On an aside: You should note, Bezier, Cat-mull Rom and probably Knot based paths are all non equidistant points algorithms which basically means if you are moving along them with a linear time step you will be seen to be moving at a non linear speed.
I am in the midst of finishing an events controller at the moment. Perhaps afterwards I might revisit the Cat-mull Rom stuff and get a few sprites walking around
Frameworks & Scriptlets:
- Speech Bubble dialogue system
- Multiple Notify with ATL and history
- (WIP) Radial Masking - needs updating to use Shader
- 7.4 - Smooth Tinting using ATL and matrixcolor
- Several other repositories there too
- Evildumdum
- Regular
- Posts: 191
- Joined: Sun Jan 18, 2015 8:49 am
- Projects: ApoclypseZ
- Contact:
Re: Possible to create transforms mid code?
Both brilliant pieces of advice. That function looks worth digging into in earnest. In terms of the way i structure the movement, its based on a grid and the path is a list of grid co-ordinates.
"If at first you don't succeed, try hitting it with a shoe."
- Remix
- Eileen-Class Veteran
- Posts: 1628
- Joined: Tue May 30, 2017 6:10 am
- Completed: None... yet (as I'm still looking for an artist)
- Projects: An un-named anime based trainer game
- Contact:
Re: Possible to create transforms mid code?
To help you along:
Any ATL function is always passed 3 parameters;
trans -> the transform object - you can directly alter positions (trans.xpos, ypos, align etc) of that or even delve down to the child displayable
st -> the important one - this is the time in seconds since the function was first called - it drops back to 0.0 if called fresh again
at -> rarely worth using - the seconds since the displayable first appeared
The function can return;
A float -> seconds until next repeat is called -> such as 0.04 (25 fps) or 0.0 (as soon as possible/next screen draw call)
None -> function has finished, no more repeat, pass control back to calling line
If/when I do get back to the Cat-mull stuff I would personally implement a class or function that built a list of x,y (or even x,y,z) co-ordinates that were equidistant apart along the calculated path (or segments there-of). Within that an iterator or method would be called with a time (0.0 to 0.1) that could be pre-warped if desired and return a tuple representing the x,y(,z) relating to that time. This should allow a semblance of linear path speed to be seen on the screen, would allow warpers to work correctly where desired (either as full path or just segment) and allow segments to define their own friction/speed. . . . Once I finish this Event system that is...
Any ATL function is always passed 3 parameters;
trans -> the transform object - you can directly alter positions (trans.xpos, ypos, align etc) of that or even delve down to the child displayable
st -> the important one - this is the time in seconds since the function was first called - it drops back to 0.0 if called fresh again
at -> rarely worth using - the seconds since the displayable first appeared
The function can return;
A float -> seconds until next repeat is called -> such as 0.04 (25 fps) or 0.0 (as soon as possible/next screen draw call)
None -> function has finished, no more repeat, pass control back to calling line
If/when I do get back to the Cat-mull stuff I would personally implement a class or function that built a list of x,y (or even x,y,z) co-ordinates that were equidistant apart along the calculated path (or segments there-of). Within that an iterator or method would be called with a time (0.0 to 0.1) that could be pre-warped if desired and return a tuple representing the x,y(,z) relating to that time. This should allow a semblance of linear path speed to be seen on the screen, would allow warpers to work correctly where desired (either as full path or just segment) and allow segments to define their own friction/speed. . . . Once I finish this Event system that is...
Frameworks & Scriptlets:
- Speech Bubble dialogue system
- Multiple Notify with ATL and history
- (WIP) Radial Masking - needs updating to use Shader
- 7.4 - Smooth Tinting using ATL and matrixcolor
- Several other repositories there too
Who is online
Users browsing this forum: Semrush [Bot]