Calling filterFrames.applyToSprite multiple times on the same sprite makes the offset of that sprite to grow each time
- Haxe version: 4.3.1
- Flixel version: 5.3.1
- OpenFL version: 9.2.2
- Lime version: 8.0.2
- Affected targets: Tested html, but probably any
Code snippet reproducing the issue:
package;
import flixel.FlxG;
import flixel.FlxSprite;
import flixel.FlxState;
import flixel.graphics.frames.FlxFilterFrames;
import flixel.tweens.FlxTween;
import flixel.util.FlxColor;
import openfl.filters.GlowFilter;
class PlayState extends FlxState
{
static inline var SIZE_INCREASE:Int = 5;
var spr:FlxSprite;
var filterFrames:FlxFilterFrames;
var running:Bool = false;
var tween:FlxTween;
override public function create():Void
{
FlxG.camera.bgColor = 0xFF01355F;
var glowFilter = new GlowFilter(0xFF0000, 1, 50, 50, 1.5, 1);
spr = new FlxSprite(200, 200);
spr.makeGraphic(10, 10, FlxColor.BROWN);
add(spr);
filterFrames = FlxFilterFrames.fromFrames(spr.frames, SIZE_INCREASE, SIZE_INCREASE, [glowFilter]);
// The tween isn't necessary for the bug, but without it, reapplying the
// filter frames doesn't really make sense...
tween = FlxTween.tween(glowFilter, {blurX: 4, blurY: 4}, 1, {type: PINGPONG});
tween.active = true;
}
override public function update(elapsed:Float):Void
{
// The whole running thing isn't necessary for the bug
// I added it because it makes the bug easier to see
if (FlxG.mouse.justPressed)
{
running = true;
}
super.update(elapsed);
if (running)
{
filterFrames.applyToSprite(spr, false, true);
}
}
}
(Note: this is just https://haxeflixel.com/demos/FlxSpriteFilters/ cut down to a minimal sample for this bug)
Observed behavior:
After you click, the screen, the sprite flies off the screen.
Expected behavior:
After you click the screen, the sprite stays where it is supposed to, and an animated blur filter starts being applied to it.
Cause of problem:
This bug was introduced with this change: https://github.com/HaxeFlixel/flixel/pull/2176
Before that change, you could call FlxFilterFrames.applyToSprite() repeatedly on the same sprite, but calling it on a sprite that had a non-zero offset would lead to wrong result. After the change, non-zero offsets would work as expected, but calling it repeatedly no longer did.
I don't see a simple solution that keeps the behavior as expected in both situations. The best I can come up with is keeping a list of sprites that the frames have been applied to, but that doesn't eliminate the bug but just pushes it to a more complicated spot (namely, if you call it again after changing the graphics, but do have an offset). Perhaps the way to go is to create two methods - or an extra argument - and leave discerning the two situations to the user. But that's a more architectural choice.