Advanced Movement
The second way that textures can be animated is by redefining the textureCoords or data points. These methods are very similar to basic plot animation, where points are recalculated and updated.
Example 1
In this example, a rocket texture is shifted in the X and Y directions using sliders. The data points are cleared, recalculated, and updated each time a slider is moved.
<xyPlot name="plot"> <style> <aspectRatio>1</aspectRatio> </style> <axis dim="x" auto="growOnly" min="0" max="1" /> <axis dim="y" auto="growOnly" min="0" max="1" /> <texture name="rocketTexture"> <image src="resources/rocket.png" /> </texture> <series name="rocket" draw="radialFill" style="trueColor" manual="true"> <textureCoords ref="rocketTexture">0 0; 0 1; 1 1; 1 0</textureCoords> <data>0.3 0.6; 0.3 0.4; 0.7 0.4; 0.7 0.6</data> </series> </xyPlot> <p>X</p> <slider name="xSlider" min="-0.5" max="0.5"> <onValueChanged> xVal = value yVal = ySlider.Value -- Add each new data point separately plot.rocket:Clear(); plot.rocket:Add(0.3 + xVal, 0.6 + yVal); plot.rocket:Add(0.3 + xVal, 0.4 + yVal); plot.rocket:Add(0.7 + xVal, 0.4 + yVal); plot.rocket:Add(0.7 + xVal, 0.6 + yVal); plot.rocket:Update() </onValueChanged> </slider> <p>Y</p> <slider name="ySlider" min="-0.5" max="0.5"> <onValueChanged> xVal = xSlider.Value yVal = value -- Add each new data point to a matrix, add at once local shift = matrixf({ {0.3 + xVal, 0.6 + yVal}, {0.3 + xVal, 0.4 + yVal}, {0.7 + xVal, 0.4 + yVal}, {0.7 + xVal, 0.6 + yVal} }); plot.rocket:Clear(); plot.rocket:Add(shift); plot.rocket:Update() </onValueChanged> </slider>
Example 2
This example updates the textureCoords of an image to simulate movement. Given an image of a character in multiple stages of walking, it is possible to shift between each frame of the image quickly to give the appearance of walking.
<xyPlot name="plot"> <style> <aspectRatio>1</aspectRatio> </style> <axis dim="x" auto="fixed" min="0" max="1" /> <axis dim="y" auto="fixed" min="0" max="1" /> <texture name="walkingTexture"> <image src="resources/Dog_Walk.png" /> </texture> <series name="dog" draw="triangles" style="trueColor" manual="true"> <!-- Texture coordinates only capture first 1/10 of the image (one frame of the dog) --> <textureCoords ref="walkingTexture">0 0; 0.1 0; 0.1 1; 0 0; 0 1; 0.1 1</textureCoords> <data>0.25 0.5; 0.5 0.5; 0.5 0.25; 0.25 0.5; 0.25 0.25; 0.5 0.25</data> </series> </xyPlot> <simulation name="sim"> <onActivePageChanged> if active then sim:Start(); else sim:Stop(); end </onActivePageChanged> <onUpdate> -- Cycle through all 10 images every 0.75 seconds, then return to the beginning (the % operator ensures that after 10 frames, we return to frame 1) local xd = (1/10) * math.floor((10/0.75) * (time % 0.75)) local walkingCoords = matrixf({ {xd, 0}, {xd + (1/10), 0}, {xd + (1/10), 1}, {xd, 0}, {xd, 1}, {xd + (1/10), 1} }); plot.dog.TextureCoordinates.Points:Clear(); plot.dog.TextureCoordinates.Points:Add(walkingCoords); plot.dog:Update(); </onUpdate> </simulation>
Example 3
In this example, the textureCoords of a background image are updated in small increments to create a continuous background. Given an image of a repeating texture, the coordinates can be continuously shifted to simulate the appearance of movement.
<drawing name="plot"> <style> <aspectRatio>1</aspectRatio> </style> <axis dim="x" auto="fixed" min="0" max="1" /> <axis dim="y" auto="fixed" min="0" max="1" /> <texture name="walkingTexture"> <image src="resources/Dog_Walk.png" /> </texture> <texture name="backgroundTexture"> <image src="resources/trees.png" /> </texture> <!-- Sky color --> <series name="sky" draw="radialFill"> <style> <foreground color="lightCyan" /> </style> <data>0 0; 1 0; 1 1; 0 1</data> </series> <series name="trees" draw="triangles" style="trueColor" manual="true"> <textureCoords ref="backgroundTexture">0 0; 1 0; 1 1; 0 0; 0 1; 1 1</textureCoords> <data>0 0; 1 0; 1 0.6; 0 0; 0 0.6; 1 0.6</data> </series> <series name="dog" draw="triangles" style="trueColor" manual="true"> <textureCoords ref="walkingTexture">0 0; 0.1 0; 0.1 1; 0 0; 0 1; 0.1 1</textureCoords> <data>0.25 0.27; 0.5 0.27; 0.5 0.02; 0.25 0.27; 0.25 0.02; 0.5 0.02</data> </series> </drawing> <simulation name="sim"> <onActivePageChanged> if active then sim:Start(); else sim:Stop(); end </onActivePageChanged> <onUpdate> -- Dog movement local xd = (1/10) * math.floor((10/0.75) * (time % 0.75)) local walkingCoords = matrixf({ {xd, 0}, {xd + (1/10), 0}, {xd + (1/10), 1}, {xd, 0}, {xd, 1}, {xd + (1/10), 1} }); plot.dog.TextureCoordinates.Points:Clear(); plot.dog.TextureCoordinates.Points:Add(walkingCoords); -- Since background is repeated 3 times, shift the coordinates until the image is 2/3 of the way through, which occurs every 20 seconds local xb = (time % 20) / 30 local shiftBG = (1/3) local backgroundCoords = matrixf({ {xb, 1}, {xb + shiftBG, 1}, {xb + shiftBG, 0}, {xb, 1}, {xb, 0}, {xb + shiftBG, 0} }); plot.trees.TextureCoordinates.Points:Clear(); plot.trees.TextureCoordinates.Points:Add(backgroundCoords); plot.dog:Update(); plot.trees:Update(); </onUpdate> </simulation>