# TweenGMS Starter Guide v0.9.6

0. What is Tweening

1. Basic Setup

2. Property Setters

3. Creating and Playing Tweens

4. Fire Tweens

5. Tween Delays

6. Tween Events

7. Extended Property Setters

`8. Troubleshooting`

0. What is Tweening?

Tweening is the interpolation of two values determined by a specified algorithm over a set duration of time. It lets you set a start and destination value which will automatically be eased between. Using different easing algorithms produces different behaviours for how the points between the start and destination values are filled in.

For example, we can tween an object's x position from 0 to 320 over 3 seconds.

    TweenFire(id, x__, true, EaseInOutQuad, 0, 320, 3.0);

Using the EaseInOutQuad algorithm, the object will smoothly accelerate from its starting position (0) and automatically move to it's destination point (320) where it will smoothly slow down before finishing. There are various easing algorithms you can choose from to help achieve the look you want.

You can find more information regarding the standard easing algorithms at easings.net.

Additionally, a good video to watch regarding tweening is Juice It or Lose It (YouTube) by Martin Jonasson and Petri Purho.

Support for Bezier and Catmull-Rom Spline easing is planned for future updates.

1. Basic Setup

Import all resources associated with the TweenGMS extension into your project.

Do not manually instantiate or destroy obj_SharedTweener. An instance of the object will, automatically, be created and destroyed, as needed, by the system. Try not to deactivate obj_SharedTweener with instance deactivation functions. If you do, call SharedTweenerActivate() to activate it again.

It is suggested to create custom property setters and ease algorithms independently of [Default_Property_Setters], [Default_Property_Setters_Ext] and [Default_Ease_Algorithms]. This will prevent future updates from accidentally deleting any custom scripts you choose to add.

When updating TweenGMS, delete all outdated files and import the new ones to replace them.

Also, make sure to check out the included example projects which are located in the TweenGMS extension folder. These .gmz files must be imported through GameMaker's launch menu screen.

* Demo_Project.gmz (Tweening examples)

* AlienOdds_Game_Project.gmz (Finished game project)

2. Property Setters

In order for TweenGMS to access and ease instance variables, property setter scripts must be created for each property. Some property setter scripts are included with TweenGMS for many of the default object properties (x, y, speed, image_index, etc). To create your own property setter scripts, you must create a new script and have the variable assigned to equal argument0. It is suggested to name property setter scripts with a post-fixed double underscore “__” to prevent potential variable naming conflicts.

    /// my_variable__(newValue)
    myVariable = argument0;

The property can then be used with one of the various tweening scripts:

    tween = TweenCreate(id, myVariable__, true, EaseLinear, 0, 100, 1.0);
    TweenPlayOnce(tween);

However, there are a couple of alternatives to using property setter scripts. One alternative is to create single-index arrays and pass them as the tween property. The tweened value can then be accessed from the array's [0] index value.

    // Create single-index array and assign it a value
    myVariable[0] = 0;
    // Pass array (name only) as property for new tween
    tween = TweenCreate(id, myVariable, true, EaseLinear, 0, 100, 1.0);
    // Play newly created tween
    TweenPlayOnce(tween);
    // Show value by accessing my_variable[0]
    show_message(myVariable[0]);

Another alternative is to supply a property as an empty string “” which will tell the system to not ease any specific value. The value will only be calculated and returned, when needed, using TweenCalc().

    tween = TweenCreate(id, “”, true, EaseLinear, 0, 100, 1.0);
    TweenPlayOnce(tween);
    show_message(TweenCalc(tween));

    There are two additional versions of TweenCalc(), TweenCalcAmount() and TweenCalcTime().

3. Creating and Playing Tweens

Using TweenCreate(), a created tween will exist in memory until its target instance is destroyed or it is manually destroyed with TweenDestroy(). When creating tweens this way, you can partially or fully define them.

    // Create partially defined tween
    tween_partial = TweenCreate(id, x__, true);

    // Create fully defined tween
    tween_full = TweenCreate(id, x__, true, EaseInQuad, 0, 100, 2.0);

Partially defined tweens must supply the remaining parameters when they are played. However, a fully defined tween can simply supply it's id handle and be played according to its previously set values.

    // Play partially defined tween
    TweenPlayOnce(tween_partial, EaseLinear, 16, 32, 1.0);

    // Play fully defined tween
    TweenPlayOnce(tween_full);

However, a fully defined tween can, optionally, have its previously set values overridden when played.

    // Override fully defined tween
    TweenPlayOnce(tween_full, EaseOutSine, 64, 128, 5.0);

IMPORTANT: Tween's will NOT be updated if their target instance is deactivated. They will continue once their target instance becomes active again.

4. Fire Tweens

TweenFire*() scripts are an alternative to using TweenCreate()/TweenPlay*(). They allow you to create and play a tween from a single script call which returns a unique tween id. Tweens created in this way differ from tweens created with TweenCreate() in that they are destroyed and become invalid as soon as they are finished or stopped. Like TweenCreate(), however, they will also become invalid if the target instance is destroyed or if TweenDestroy() is manually called.

    // Fire tween
    tween = TweenFire(id, x__, true, EaseLinear, 0, 100, 1.0);

    // Stop tween – will be immediately destroyed and removed from system
    TweenStop(tween);

IMPORTANT: Tween's will NOT be updated if their target instance is deactivated. They will continue once their target instance becomes active again.

5. Tween Delays

It is possible to delay the start of a tween by calling TweenPlay___Delay() or TweenFire___Delay(). These scripts will return a unique delay id which can be used to cancel, pause, or resume specific delays. The delay timer will use the timing type (delta/step) as indicated by the tween. It is important to note that TweenFire___Delay() scripts return an array which holds the tween id in index[0] and the delay id in index[1].

    // Create a fully defined tween and delay playing for 10 seconds
    tween_x = TweenCreate(id, x__, true, EaseLinear, 0, 100, 2.0);
    delay_x = TweenPlayOnceDelay(tween, 10);

    // Fire a delayed tween, returning unique tween/delay ids
    ids = TweenFireDelay(id, y__, true, EaseLinear, 0, 100, 2.0);
    tween_y = ids[0];
    delay_y = ids[1];

IMPORTANT: Delays will NOT be updated if their target instance is deactivated. They will continue once their target instance becomes active again.

`6. Tween Events`

Tweens can have script callbacks attached to various events (play,finish,stop,pause,resume,reverse). You can add multiple callbacks to these events by using TweenOn____Add() scripts, where “____” is the indicated event type. A unique callback id is returned from the script call. Up to 13 arguments can be passed to event callback scripts.

    tween = TweenCreate(id, x__, true);
    cbDispNumb = TweenOnFinishAdd(tween, id, ShowNumber, 42);
    cbDispText = TweenOnFinishAdd(tween, id, ShowString, “Don't panic!”);

If needed, specific tween events can be suppressed by using the TweenOn____Enable() scripts.

Tween delays also have their own events (finish, cancel, pause, resume). You can add callbacks to delay events by using the TweenDelayOn__Add() scripts with a specified delay id handle.

IMPORTANT: Like tweens, callbacks are associated with a designated target instance which uses its environment to execute the script. Any callback associated with a deactivated target instance will not be executed. Those associated with destroyed target instances will be automatically removed and cleared from memory the next time the event is invoked.

`7. Extended Property Setters`

It is advised to add custom extended property setters outside of Default_Property_Setters_Ext. It is also advised to use the "ext_property__" convention when naming custom extended property setters. There is no need to destroy extended property setters.

With extended property setters you are able to access custom data which you choose to pass to it. Before an extended property setter script can be used, you must call:

    TPSetExt(ext_property__, arg0, arg1, ...)

This script defines the values you want to pass to the specified extended property setter. A new handle is returned which can be used as a property setter for future tween calls.

    /// [Mouse Up Event]

    // Create extended property setter
    property_xy = TPSetExt(ext_xy__, x, mouse_x, y, mouse_y);

    // Use extended property setter with new tween
    TweenFire(id, property_xy, true, EaseInOutQuad, 0, 1, 5.0);

Note that when using extended property setters, it is often useful to create tweens with a start value of 0 and destination value of 1. The value between 0 and 1 can then be accessed from the extended property setter as a relative amount reflecting the tween's ease algorithm over time. This value can be used with GameMaker's lerp() function to calculate the custom data supplied to the extended property setter.

e.g.

    /// ext_xy__(amount,data[x1|x2|y1|y2])

    // Get amount reflecting ease algorithm over time
    var _amount = argument0;

    // Get custom data
    var _data = argument1;
    var _x1 = _data[0];
    var _x2 = _data[1];
    var _y1 = _data[2];
    var _y2 = _data[3];

    // Update x/y position by using lerp() with custom data and amount
    x = lerp(_x1, _x2, _amount);
    y = lerp(_y1, _y2, _amount);

As shown in the example above, the eased amount is passed to the extended property setter as argument0. We can use this value as an amount for the lerp function and fill in the custom start/destination values as needed. Any custom values passed to the property setter is accessible via argument1 which holds an array of data in the order you supplied it when creating the extended property setter with TPSetExt().

You can also have extended properties use different tweening algorithms for each eased variable. You can achieve this by using a linear tween with a start value of 0 and a destination value of 1. You can then use the Ease() function in the extended property setter with the linear value reflecting the total time elapsed. The modified version of the above example could look like this:

    /// ext_xy__(amount,data[x1|x2|y1|y2])

    // Get amount representing time elapsed (0.0 – 1.0)
    var _amount = argument0;

    // Get custom data
    var _data = argument1;
    var _x1 = _data[0];
    var _x2 = _data[1];
    var _y1 = _data[2];
    var _y2 = _data[3];

    // Update x/y position by using Ease() with custom data and amount
    x = Ease(_x1, _x2, _amount, EaseInOutQuad);
    y = Ease(_y1, _y2, _amount, EaseInOutElastic);

PLEASE NOTE: When using tween delays and extended properties, there are times when you don't want a delayed tween's property type to be changed until the tween starts playing. This is an issue which can occur when using the TweenPlay****Delay scripts and shouldn't be a problem when using TweenFire****Delay or TweenSimple****Delay scripts. To help remedy this, the following script has been supplied:

/// TweenDelayPropertySetter(delay,property)

Example:

    // Create two different extended property setters
    pExt1 = TPSetExt(ext_xy__, 0, 100, 0, 100);
    pExt2 = TPSetExt(ext_xy__, 100, 0, 100, 0);

    // Create and play a tween using the first property setter
    tween = TweenCreate(id, pExt1, true);
    TweenPlayOnce(id, EaseInQuad, 0, 1, 3.0);

    // Delay the tween and tell it to activate the second property when the tween starts playing
    var _delay = TweenPlayOnceDelay(tween, 3.0, EaseOutQuad, 0, 1, 3.0);
    TweenDelayPropertySetter(_delay, pExt2);

The script tells the specified delay to activate the intended property setter only when the delay finishes.

`8. Troubleshooting`

A) When using native YYC targets, clear the compiler cache (broom button at top) if strange errors occur.

B) If nothing seems to be working, check that “Copies To:” is selected for your target platform. This can be done by going to [Extensions] -> [TweenGMS] -> and clicking on [TweenGMS_Extension_Setup.gml]. Make sure all target platforms are checked!!