The "scaleX" and "scaleY" properties decide how much distortion will occur. What you're probably after is an animation of the complete circle texture - it should start small directly above the center of the explosion and then become bigger over time.
And here's a problem: while you can currently change the position of the map texture over your filtered object (via "mapX" and "mapY"), you can't change its scale.
Well, you couldn't, until right now. I just added two new experimental properties to the DisplacementMapFilter, called "mapScaleX" and "mapScaleY". They allow you to scale the map texture at runtime. "git pull" the latest Starling version, and you'll have those properties available.
That's all you need!
So, I'll talk you through it. What you're after is the following: take the shockwave map texture and animate it over the center of the explosion. Like this:
You do this by animating "mapX/Y" and "mapScaleX/Y". Here's a small trick that will make this easier: open up "DisplacementFilter.as" and find the method "createProgram" (it's around line 266).
/* Replace the final line of the "fragmentShader" String: */
tex("oc", "ft3", 0, texture)
/* With this: */
tex("ft4", "ft3", 0, texture),
"mov oc, ft0"
With this small hack, the filter will actually show you the displacement map instead of actually displacing something. That makes it easier to check if your coordinates are correct.
That animation from above was created like this. Here's how it looks after reverting the shader code:
Pretty neat, right? π
Here's the complete code, to use as a starting point.
[Embed(source = "../../assets/textures/shockwave.png")]
private static const TextureShockwave:Class;
[Embed(source = "../../assets/textures/summoners-fate.png")]
private static const TextureSummonersFate:Class;
public function FilterExperiments()
{
addEventListener(Event.ADDED_TO_STAGE, shockwaveExperiment);
}
private function shockwaveExperiment():void
{
var filter:DisplacementMapFilter;
var map:Texture = Texture.fromEmbeddedAsset(TextureShockwave, false, false, 2);
var bg:Image = new Image(Texture.fromEmbeddedAsset(TextureSummonersFate));
addChild(bg);
bg.addEventListener(TouchEvent.TOUCH, function(e:TouchEvent):void
{
if (bg.filter) return;
var touch:Touch = e.getTouch(bg, TouchPhase.ENDED);
if (touch)
{
var touchPos:Point = touch.getLocation(bg);
var filter:DisplacementMapFilter = new DisplacementMapFilter(map,
BitmapDataChannel.RED, BitmapDataChannel.GREEN, 32, 32);
bg.filter = filter;
var wave:Object = { x: touchPos.x, y: touchPos.y, radius: 2, distortion: 32 };
Starling.juggler.tween(wave, 1, {
radius: bg.width, distortion: 0,
transition: Transitions.EASE_IN,
onUpdate: function():void
{
filter.mapX = wave.x - wave.radius;
filter.mapY = wave.y - wave.radius;
filter.mapScaleX = wave.radius / (map.width / 2);
filter.mapScaleY = filter.mapScaleX;
filter.scaleX = filter.scaleY = wave.distortion
},
onComplete: function():void
{
filter.dispose();
bg.filter = null;
}
});
}
});
}
Note how I'm using a simple temporary object ("wave"), simply to have something simple to animate (the tween class needs an object to work on, after all). The "onUpdate" callback of the tween then does the actual work.
I took the freedom of using a screenshot of Summoner's Fate from Ross Przybylski to highlight the effect. π
Cheers!