Mutable Sprites
#
IntroMutable Sprites are an alternative API for Sprites and Textures which drastically reduce the amount of Garbage Collection (GC) required by the JavaScript engine. This can result in big performance improvements, especially in dropped frames due to regular GC. To do this they rely on mutating state and props instead of always returning new objects.
A Custom Sprite may contain a Mutable Sprite, but not vice versa. The Top-Level Game Sprite also cannot be Mutable.
You can create a Mutable Sprite with the makeMutableSprite
function, which is similar to a Sprite but with a few differences:
- JavaScript
- TypeScript
The loop
method of the Level
Mutable Sprite no longer needs to return a new state, instead you can mutate the state
object directly.
The render
function is returning a circle
Mutable Texture and a single Player
Mutable Sprite. Use t2
instead of t
for Mutable Textures. Instead of taking a single props argument, the 1st argument is the initial props, and the 2nd argument is an update callback which is run every frame. thisProps
can be mutated to update the props being passed to circle
or Player
.
Important
The render
function is only called once after init
. All updates are applied through update callbacks like the 2nd argument of Player.Single
.
To call a Mutable Sprite from a Custom Sprite, make sure an id
prop is passed in (they're not required within Mutable Sprites):
- JavaScript
- TypeScript
The 2nd argument of Item.Single
(the update callback) won't be used since render
will run every frame in the Player
Custom Sprite. To reduce GC it's best to avoid this as much as possible by nesting multiple Mutable Sprites within one Mutable Sprite.
#
API#
MySprite.Single(props, update)Render a single Mutable Sprite.
#
Argumentsprops
: The initial props for the Sprite.update(thisProps)
: (Optional) Callback to mutate the Sprite's props.
#
MySprite.Array({ props, array, key, update, updateAll, filter })Render an array of Mutable Sprites.
#
ArgumentsAn object with the following properties:
props(itemState, index)
: A function returning Sprite's props. This is called for each new element in the array with the element's valueitemState
and its position in the arrayindex
.array()
: A function returning the array data to render.key(itemState, index)
: (Optional) A function returning a unique (within the array) idstring
ornumber
. You can just returnindex
to avoid creating strings every frame if you don't need to preserve state.update(thisProps, itemState, index)
: (Optional) Callback to mutate the Sprite's props.updateAll(thisProps)
: (Optional) Callback to mutate props for all Sprites in the array. This can avoid repeated calculations for every Sprite.filter(itemState, index)
: (Optional) A function returning whether to render an element (true
) or not (false
).
#
t2.text(props, update)#
Argumentsprops
: Partial of text Texture props.update(thisProps)
: (Optional) Callback to mutate the texture's props.
#
t2.textArray({ props, array, update, mask, testId })#
ArgumentsAn object with the following properties:
props(itemState, index)
: A function returning partial of text Texture props. This is called for each new element in the array with the element's valueitemState
and its position in the arrayindex
.array()
: A function returning the array data to render.update(thisProps, itemState, index)
: (Optional) Callback to mutate the texture's props.mask
: (Optional) A Mask for all elements.testId(itemState, index)
: (Optional) A function returning a unique test id string, used by Replay Test.
#
t2.circle(props, update)#
Argumentsprops
: Partial of circle Texture props.update(thisProps)
: (Optional) Callback to mutate the texture's props.
#
t2.circleArray({ props, array, update, mask, testId })#
ArgumentsAn object with the following properties:
props(itemState, index)
: A function returning partial of circle Texture props. This is called for each new element in the array with the element's valueitemState
and its position in the arrayindex
.array()
: A function returning the array data to render.update(thisProps, itemState, index)
: (Optional) Callback to mutate the texture's props.mask
: (Optional) A Mask for all elements.testId(itemState, index)
: (Optional) A function returning a unique test id string, used by Replay Test.
#
t2.rectangle(props, update)#
Argumentsprops
: Partial of rectangle Texture props.update(thisProps)
: (Optional) Callback to mutate the texture's props.
#
t2.rectangleArray({ props, array, update, mask, testId })#
ArgumentsAn object with the following properties:
props(itemState, index)
: A function returning partial of rectangle array Texture props. This is called for each new element in the array with the element's valueitemState
and its position in the arrayindex
.array()
: A function returning the array data to render.update(thisProps, itemState, index)
: (Optional) Callback to mutate the texture's props.mask
: (Optional) A Mask for all elements.testId(itemState, index)
: (Optional) A function returning a unique test id string, used by Replay Test.
#
t2.line(props, update)#
Argumentsprops
: Partial of line Texture props.update(thisProps)
: (Optional) Callback to mutate the texture's props.
#
t2.lineArray({ props, array, update, mask, testId })#
ArgumentsAn object with the following properties:
props(itemState, index)
: A function returning partial of line Texture props. This is called for each new element in the array with the element's valueitemState
and its position in the arrayindex
.array()
: A function returning the array data to render.update(thisProps, itemState, index)
: (Optional) Callback to mutate the texture's props.mask
: (Optional) A Mask for all elements.testId(itemState, index)
: (Optional) A function returning a unique test id string, used by Replay Test.
#
t2.image(props, update)#
Argumentsprops
: Partial of image Texture props.update(thisProps)
: (Optional) Callback to mutate the texture's props.
#
t2.imageArray({ props, array, update, mask, testId })#
ArgumentsAn object with the following properties:
props(itemState, index)
: A function returning partial of image array Texture props. This is called for each new element in the array with the element's valueitemState
and its position in the arrayindex
.array()
: A function returning the array data to render.update(thisProps, itemState, index)
: (Optional) Callback to mutate the texture's props.mask
: (Optional) A Mask for all elements.testId(itemState, index)
: (Optional) A function returning a unique test id string, used by Replay Test.
#
t2.spriteSheet(props, update)#
Argumentsprops
: Partial of sprite sheet Texture props.update(thisProps)
: (Optional) Callback to mutate the texture's props.
#
r.if(condition, sprites)#
Argumentscondition()
: A function that returns aboolean
.sprites()
: A function returning an array of Mutable Sprites to render only if the 1st argument returnstrue
.
#
r.ifElse(condition, trueSprites, falseSprites)#
Argumentscondition()
: A function that returns aboolean
.trueSprites()
: A function returning an array of Mutable Sprites to render only if the 1st argument returnstrue
.falseSprites()
: A function returning an array of Mutable Sprites to render only if the 1st argument returnsfalse
.
#
r.onChange(value, sprites)#
Argumentsvalue()
: A function that returns a value to watch.sprites()
: A function returning an array of Mutable Sprites. This will re-render whenever thevalue
returned changes (prev !== new
). (This will cause Sprites to unmount and remount, which will reset their state.)
#
r.run(fn)#
Argumentsfn()
: A function that runs every frame.
#
Example- JavaScript
- TypeScript
#
ContextA Mutable Sprite cannot use a Context from a non-Mutable Sprite. Create a Context in the normal way but use context.Single
. The context
prop is a function which is updated every frame to avoid stale values.
- JavaScript
- TypeScript
Be aware that values returned with getContext
may not update unless they're mutated, so it can be worth calling getContext
in your update callbacks rather than in the body of render
.
#
Native SpritesNative Sprites also have an optional 2nd argument, which is used when nested in Mutable Sprites to update their props:
- JavaScript
- TypeScript