-
Notifications
You must be signed in to change notification settings - Fork 0
RelativePositioning
===Relative Positioning:===
All objects in frogatto have a position value which is the "absolute position" in terms of level coordinates. A common desire is to make one object (say, a separate turret object mounted on a tank) follow another object. Traditionally, the only means we had to do this was to use an on_process="set(x, creator.x)", and have a reference to another object we wanted to follow; on each frame, the 'child' would manually set its absolute postion to match the object that created it. This is messy, but it's also a performance hit, because it involves interpreting a formula, per each object, every cycle. If many objects have children, this rapidly adds up.
We've made a new system to specifically support this, which has better performance, and is cleaner.
To make an object automatically follow another, you set the object to have that other as its parent - this will not be set automatically when a different object "spawns" another, it has to be done explicitly. Once you do this, it will automatically stay that relative distance away from the parent without any further intervention. A common idiom is to, in the spawn command, add: spawn('object_name', x, y, facing, set(parent, me)) Once this is done, you can set/query the values "relative_x" and "relative_y", which otherwise work exactly like the regular x,y values.
For certain usages, you need the ability to modify what point the child object is positioned relative to. For a simple example in game, if frogatto were given a "hat" as a child object, it would look very odd if the hat did not bob along with him in his standing position. Both different animations, and even individual frames within animations, would need custom offsets. To do this, you specify what is called a "pivot point". Pivot points each have a different name, which allows multiple pivot points to be created and tracked. For example, if one were creating a large creature out of multiple objects, you might have one pivot point for an arm, and a separate pivot point for the head.
First, inside the child object, you need to declare the name of the parent's pivot point to follow: [set(parent, level.player), set(pivot, 'foo')]
Second, inside the parent's animation tags, you need to declare the position of this pivot point: pivot_foo=x,y
To make it change per frame, you can provide a list of values, and it will smoothly interpolate between them:
pivot_foo=x1,y1,x2,y2...xn,yn
===Examples and design notes:===
-
You control where such a child object is initially placed the regular way, in the spawn command. It's initial position won't necessarily correspond to relative_x,relative_y = 0,0.
-
relative_x and relative_y, by default, are measured relative to the parent's midpoint. If it's solid, 'midpoint' means center of its solidity.
-
If you set a child object to an absolute position whilst it has a parent, the distance this is from the parent will become a new relative positioning. For example, if the parent's midpoint is at 500,500, and I set the child to an absolute position of 500,700, it's new relative_x,relative_y will be 0,200.
-
Relative positioning does respect facing - if an object reverses its facing, the relatively-positioned child will have it's position flipped across the parent's midpoint. The child will also reverse its facing, which makes sense for common usages like placing a hat on a character.
-
The reason we have x/y as well as relative_x/relative_y is because other objects might want to check the position of an object, say for proximity checking.
-
If you set velocity_x, or velocity_y, an object's velocity will be relative to the parent, which is useful for children coming off quickly-moving objects.